Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 36ec1b2

Browse files
committed
backport #438 to v2
1 parent 449d74b commit 36ec1b2

File tree

1 file changed

+166
-6
lines changed

1 file changed

+166
-6
lines changed

token/program/src/processor.rs

Lines changed: 166 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,7 @@ impl Processor {
552552
let dest_account_info = next_account_info(account_info_iter)?;
553553
let authority_info = next_account_info(account_info_iter)?;
554554

555-
let mut source_data = source_account_info.data.borrow_mut();
556-
Account::unpack_mut(&mut source_data, &mut |source_account: &mut Account| {
555+
let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
557556
if !source_account.is_native() && source_account.amount != 0 {
558557
return Err(TokenError::NonNativeHasBalance.into());
559558
}
@@ -576,8 +575,9 @@ impl Processor {
576575
**source_account_info.lamports.borrow_mut() = 0;
577576
source_account.amount = 0;
578577

578+
Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
579+
579580
Ok(())
580-
})
581581
}
582582

583583
/// Processes a [FreezeAccount](enum.TokenInstruction.html) or a
@@ -592,8 +592,7 @@ impl Processor {
592592
let mint_info = next_account_info(account_info_iter)?;
593593
let authority_info = next_account_info(account_info_iter)?;
594594

595-
let mut source_data = source_account_info.data.borrow_mut();
596-
Account::unpack_mut(&mut source_data, &mut |source_account: &mut Account| {
595+
let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
597596
if source_account.is_native() {
598597
return Err(TokenError::NativeNotSupported.into());
599598
}
@@ -621,8 +620,9 @@ impl Processor {
621620
AccountState::Initialized
622621
};
623622

623+
Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
624+
624625
Ok(())
625-
})
626626
}
627627

628628
/// Processes an [Instruction](enum.Instruction.html).
@@ -3567,6 +3567,97 @@ mod tests {
35673567
signers[5].is_signer = true;
35683568
}
35693569

3570+
#[test]
3571+
fn test_close_account_dups() {
3572+
let program_id = pubkey_rand();
3573+
let account1_key = pubkey_rand();
3574+
let mut account1_account = SolanaAccount::new(
3575+
account_minimum_balance(),
3576+
Account::get_packed_len(),
3577+
&program_id,
3578+
);
3579+
let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
3580+
let account2_key = pubkey_rand();
3581+
let mut account2_account = SolanaAccount::new(
3582+
account_minimum_balance(),
3583+
Account::get_packed_len(),
3584+
&program_id,
3585+
);
3586+
let account2_info: AccountInfo = (&account2_key, true, &mut account2_account).into();
3587+
let owner_key = pubkey_rand();
3588+
let mint_key = pubkey_rand();
3589+
let mut mint_account =
3590+
SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3591+
let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
3592+
let rent_key = rent::id();
3593+
let mut rent_sysvar = rent_sysvar();
3594+
let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
3595+
3596+
// create mint
3597+
do_process_instruction_dups(
3598+
initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3599+
vec![mint_info.clone(), rent_info.clone()],
3600+
)
3601+
.unwrap();
3602+
3603+
// create account
3604+
do_process_instruction_dups(
3605+
initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
3606+
vec![
3607+
account1_info.clone(),
3608+
mint_info.clone(),
3609+
account1_info.clone(),
3610+
rent_info.clone(),
3611+
],
3612+
)
3613+
.unwrap();
3614+
3615+
// source-owner close
3616+
do_process_instruction_dups(
3617+
close_account(
3618+
&program_id,
3619+
&account1_key,
3620+
&account2_key,
3621+
&account1_key,
3622+
&[],
3623+
)
3624+
.unwrap(),
3625+
vec![
3626+
account1_info.clone(),
3627+
account2_info.clone(),
3628+
account1_info.clone(),
3629+
],
3630+
)
3631+
.unwrap();
3632+
3633+
// source-close-authority close
3634+
Account::unpack_unchecked_mut(
3635+
&mut account1_info.data.borrow_mut(),
3636+
&mut |account: &mut Account| {
3637+
account.close_authority = COption::Some(account1_key);
3638+
account.owner = owner_key;
3639+
Ok(())
3640+
},
3641+
)
3642+
.unwrap();
3643+
do_process_instruction_dups(
3644+
close_account(
3645+
&program_id,
3646+
&account1_key,
3647+
&account2_key,
3648+
&account1_key,
3649+
&[],
3650+
)
3651+
.unwrap(),
3652+
vec![
3653+
account1_info.clone(),
3654+
account2_info.clone(),
3655+
account1_info.clone(),
3656+
],
3657+
)
3658+
.unwrap();
3659+
}
3660+
35703661
#[test]
35713662
fn test_close_account() {
35723663
let program_id = pubkey_rand();
@@ -4390,6 +4481,75 @@ mod tests {
43904481
);
43914482
}
43924483

4484+
#[test]
4485+
fn test_freeze_thaw_dups() {
4486+
let program_id = pubkey_rand();
4487+
let account1_key = pubkey_rand();
4488+
let mut account1_account = SolanaAccount::new(
4489+
account_minimum_balance(),
4490+
Account::get_packed_len(),
4491+
&program_id,
4492+
);
4493+
let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
4494+
let owner_key = pubkey_rand();
4495+
let mint_key = pubkey_rand();
4496+
let mut mint_account =
4497+
SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4498+
let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
4499+
let rent_key = rent::id();
4500+
let mut rent_sysvar = rent_sysvar();
4501+
let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
4502+
4503+
// create mint
4504+
do_process_instruction_dups(
4505+
initialize_mint(&program_id, &mint_key, &owner_key, Some(&account1_key), 2).unwrap(),
4506+
vec![mint_info.clone(), rent_info.clone()],
4507+
)
4508+
.unwrap();
4509+
4510+
// create account
4511+
do_process_instruction_dups(
4512+
initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
4513+
vec![
4514+
account1_info.clone(),
4515+
mint_info.clone(),
4516+
account1_info.clone(),
4517+
rent_info.clone(),
4518+
],
4519+
)
4520+
.unwrap();
4521+
4522+
// freeze where mint freeze_authority is account
4523+
do_process_instruction_dups(
4524+
freeze_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
4525+
vec![
4526+
account1_info.clone(),
4527+
mint_info.clone(),
4528+
account1_info.clone(),
4529+
],
4530+
)
4531+
.unwrap();
4532+
4533+
// thaw where mint freeze_authority is account
4534+
Account::unpack_unchecked_mut(
4535+
&mut account1_info.data.borrow_mut(),
4536+
&mut |account: &mut Account| {
4537+
account.state = AccountState::Frozen;
4538+
Ok(())
4539+
},
4540+
)
4541+
.unwrap();
4542+
do_process_instruction_dups(
4543+
thaw_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
4544+
vec![
4545+
account1_info.clone(),
4546+
mint_info.clone(),
4547+
account1_info.clone(),
4548+
],
4549+
)
4550+
.unwrap();
4551+
}
4552+
43934553
#[test]
43944554
fn test_freeze_account() {
43954555
let program_id = pubkey_rand();

0 commit comments

Comments
 (0)