From 45cebaf75447b405b036f15c7746499f88a89219 Mon Sep 17 00:00:00 2001 From: Jack May Date: Mon, 21 Sep 2020 12:48:58 -0700 Subject: [PATCH] backport #435 to v2 --- token/program/src/processor.rs | 121 ++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 8 deletions(-) diff --git a/token/program/src/processor.rs b/token/program/src/processor.rs index 466b6447..5ef4395a 100644 --- a/token/program/src/processor.rs +++ b/token/program/src/processor.rs @@ -327,8 +327,8 @@ impl Processor { let authority_info = next_account_info(account_info_iter)?; if account_info.data_len() == Account::get_packed_len() { - let mut account_data = account_info.data.borrow_mut(); - Account::unpack_mut(&mut account_data, &mut |account: &mut Account| { + let mut account = Account::unpack(&account_info.data.borrow())?; + if account.is_frozen() { return Err(TokenError::AccountFrozen.into()); } @@ -362,11 +362,9 @@ impl Processor { return Err(TokenError::AuthorityTypeNotSupported.into()); } } - Ok(()) - })?; + Account::pack(account, &mut account_info.data.borrow_mut())?; } else if account_info.data_len() == Mint::get_packed_len() { - let mut mint_data = account_info.data.borrow_mut(); - Mint::unpack_mut(&mut mint_data, &mut |mint: &mut Mint| { + let mut mint = Mint::unpack(&account_info.data.borrow())?; match authority_type { AuthorityType::MintTokens => { // Once a mint's supply is fixed, it cannot be undone by setting a new @@ -400,8 +398,7 @@ impl Processor { return Err(TokenError::AuthorityTypeNotSupported.into()); } } - Ok(()) - })?; + Mint::pack(mint, &mut account_info.data.borrow_mut())?; } else { return Err(ProgramError::InvalidArgument); } @@ -2184,6 +2181,114 @@ mod tests { .unwrap(); } + #[test] + fn test_set_authority_dups() { + let program_id = pubkey_rand(); + let account1_key = pubkey_rand(); + let mut account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into(); + let owner_key = pubkey_rand(); + let mint_key = pubkey_rand(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into(); + let rent_key = rent::id(); + let mut rent_sysvar = rent_sysvar(); + let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + // create mint + do_process_instruction_dups( + initialize_mint(&program_id, &mint_key, &mint_key, Some(&mint_key), 2).unwrap(), + vec![mint_info.clone(), rent_info.clone()], + ) + .unwrap(); + + // create account + do_process_instruction_dups( + initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + rent_info.clone(), + ], + ) + .unwrap(); + + // set mint_authority when currently self + do_process_instruction_dups( + set_authority( + &program_id, + &mint_key, + Some(&owner_key), + AuthorityType::MintTokens, + &mint_key, + &[], + ) + .unwrap(), + vec![mint_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // set freeze_authority when currently self + do_process_instruction_dups( + set_authority( + &program_id, + &mint_key, + Some(&owner_key), + AuthorityType::FreezeAccount, + &mint_key, + &[], + ) + .unwrap(), + vec![mint_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // set account owner when currently self + do_process_instruction_dups( + set_authority( + &program_id, + &account1_key, + Some(&owner_key), + AuthorityType::AccountOwner, + &account1_key, + &[], + ) + .unwrap(), + vec![account1_info.clone(), account1_info.clone()], + ) + .unwrap(); + + // set close_authority when currently self + Account::unpack_unchecked_mut( + &mut account1_info.data.borrow_mut(), + &mut |account: &mut Account| { + account.close_authority = COption::Some(account1_key); + Ok(()) + }, + ) + .unwrap(); + + do_process_instruction_dups( + set_authority( + &program_id, + &account1_key, + Some(&owner_key), + AuthorityType::CloseAccount, + &account1_key, + &[], + ) + .unwrap(), + vec![account1_info.clone(), account1_info.clone()], + ) + .unwrap(); + } + #[test] fn test_set_authority() { let program_id = pubkey_rand();