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

Commit b39efe8

Browse files
zrthxnjoncinque
andauthored
token-cli: Fix unexpected behavior when closing a wrapped SOL account with another wrapped SOL account as recipient (#3278)
* Check if recipient is a wrapped account * Make clippy and fmt happy * Avoided mutable, more functional clarity * Add test for closing wrapped sol account * wrap the default account Co-authored-by: Jon Cinque <[email protected]> * Fix formatting and failing tests Co-authored-by: Jon Cinque <[email protected]>
1 parent 937b64d commit b39efe8

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

token/cli/src/main.rs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,9 @@ fn command_close(
13511351
recipient: Pubkey,
13521352
bulk_signers: BulkSigners,
13531353
) -> CommandResult {
1354-
if !config.sign_only {
1354+
let is_recipient_wrapped = if config.sign_only {
1355+
false
1356+
} else {
13551357
let source_account = config
13561358
.rpc_client
13571359
.get_token_account(&account)?
@@ -1375,15 +1377,24 @@ fn command_close(
13751377
)
13761378
.into());
13771379
}
1378-
}
13791380

1380-
let instructions = vec![close_account(
1381+
let recipient_account = config.rpc_client.get_token_account(&recipient)?;
1382+
1383+
recipient_account.map(|x| x.is_native).unwrap_or(false)
1384+
};
1385+
1386+
let mut instructions = vec![close_account(
13811387
&config.program_id,
13821388
&account,
13831389
&recipient,
13841390
&close_authority,
13851391
&config.multisigner_pubkeys,
13861392
)?];
1393+
1394+
if is_recipient_wrapped {
1395+
instructions.push(sync_native(&config.program_id, &recipient)?);
1396+
}
1397+
13871398
let tx_return = handle_tx(
13881399
&CliSignerInfo {
13891400
signers: bulk_signers,
@@ -3635,6 +3646,43 @@ mod tests {
36353646
assert_eq!(ui_account.token_amount.amount, "90");
36363647
}
36373648

3649+
#[test]
3650+
fn close_wrapped_sol_account() {
3651+
let (test_validator, payer) = validator_for_test();
3652+
let config = test_config(&test_validator, &payer, &spl_token::id());
3653+
let bulk_signers: Vec<Box<dyn Signer>> = vec![Box::new(clone_keypair(&payer))];
3654+
3655+
let token = create_token(&config, &payer);
3656+
let source = create_associated_account(&config, &payer, token);
3657+
let ui_amount = 10.0;
3658+
command_wrap(&config, ui_amount, payer.pubkey(), None, bulk_signers).unwrap();
3659+
3660+
let recipient = get_associated_token_address_with_program_id(
3661+
&payer.pubkey(),
3662+
&native_mint::id(),
3663+
&config.program_id,
3664+
);
3665+
let _result = process_test_command(
3666+
&config,
3667+
&payer,
3668+
&[
3669+
"spl-token",
3670+
CommandName::Close.into(),
3671+
"--address",
3672+
&source.to_string(),
3673+
"--recipient",
3674+
&recipient.to_string(),
3675+
],
3676+
);
3677+
3678+
let ui_account = config
3679+
.rpc_client
3680+
.get_token_account(&recipient)
3681+
.unwrap()
3682+
.unwrap();
3683+
assert_eq!(ui_account.token_amount.amount, "10000000000");
3684+
}
3685+
36383686
#[test]
36393687
fn disable_mint_authority() {
36403688
let (test_validator, payer) = validator_for_test();

0 commit comments

Comments
 (0)