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

Commit 339100e

Browse files
Disable CloseAccount for non-native token accounts (#127)
1 parent 6fd5917 commit 339100e

File tree

2 files changed

+16
-58
lines changed

2 files changed

+16
-58
lines changed

token/src/error.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
use num_derive::FromPrimitive;
44
use num_traits::FromPrimitive;
55
use solana_sdk::{
6+
decode_error::DecodeError,
67
info,
78
program_error::{PrintProgramError, ProgramError},
8-
decode_error::DecodeError,
99
};
1010
use thiserror::Error;
1111

@@ -42,12 +42,12 @@ pub enum TokenError {
4242
/// Instruction does not support native tokens
4343
#[error("Instruction does not support native tokens")]
4444
NativeNotSupported,
45+
/// Instruction does not support non-native tokens
46+
#[error("Instruction does not support non-native tokens")]
47+
NonNativeNotSupported,
4548
/// Invalid instruction
4649
#[error("Invalid instruction")]
4750
InvalidInstruction,
48-
/// Non-native account can only be closed if its balance is zero
49-
#[error("Non-native account can only be closed if its balance is zero")]
50-
NonNativeHasBalance,
5151
}
5252
impl From<TokenError> for ProgramError {
5353
fn from(e: TokenError) -> Self {
@@ -83,10 +83,10 @@ impl PrintProgramError for TokenError {
8383
TokenError::NativeNotSupported => {
8484
info!("Error: Instruction does not support native tokens")
8585
}
86-
TokenError::InvalidInstruction => info!("Error: Invalid instruction"),
87-
TokenError::NonNativeHasBalance => {
88-
info!("Non-native account can only be closed if its balance is zero")
86+
TokenError::NonNativeNotSupported => {
87+
info!("Error: Instruction does not support non-native tokens")
8988
}
89+
TokenError::InvalidInstruction => info!("Error: Invalid instruction"),
9090
}
9191
}
9292
}

token/src/state.rs

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use crate::{
66
option::COption,
77
};
88
use solana_sdk::{
9-
account_info::AccountInfo, entrypoint::ProgramResult, info, program_error::ProgramError,
10-
account_info::next_account_info, pubkey::Pubkey,
9+
account_info::next_account_info, account_info::AccountInfo, entrypoint::ProgramResult, info,
10+
program_error::ProgramError, pubkey::Pubkey,
1111
};
1212
use std::mem::size_of;
1313

@@ -425,8 +425,8 @@ impl State {
425425
let mut source_data = source_account_info.data.borrow_mut();
426426
let source_account: &mut Account = Self::unpack(&mut source_data)?;
427427

428-
if !source_account.is_native && source_account.amount != 0 {
429-
return Err(TokenError::NonNativeHasBalance.into());
428+
if !source_account.is_native {
429+
return Err(TokenError::NonNativeNotSupported.into());
430430
}
431431

432432
Self::validate_owner(
@@ -2053,19 +2053,12 @@ mod tests {
20532053
)
20542054
);
20552055

2056-
// initialize and mint to account
2056+
// initialize non-native account
20572057
do_process_instruction(
20582058
initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
20592059
vec![&mut account_account, &mut mint_account, &mut owner_account],
20602060
)
20612061
.unwrap();
2062-
do_process_instruction(
2063-
initialize_mint(&program_id, &mint_key, Some(&account_key), None, 42, 2).unwrap(),
2064-
vec![&mut mint_account, &mut account_account, &mut owner_account],
2065-
)
2066-
.unwrap();
2067-
let account: &mut Account = State::unpack(&mut account_account.data).unwrap();
2068-
assert_eq!(account.amount, 42);
20692062

20702063
// initialize native account
20712064
do_process_instruction(
@@ -2083,9 +2076,9 @@ mod tests {
20832076
assert!(account.is_native);
20842077
assert_eq!(account.amount, 2);
20852078

2086-
// close account with balance
2079+
// close non-native account
20872080
assert_eq!(
2088-
Err(TokenError::NonNativeHasBalance.into()),
2081+
Err(TokenError::NonNativeNotSupported.into()),
20892082
do_process_instruction(
20902083
close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
20912084
vec![
@@ -2095,41 +2088,7 @@ mod tests {
20952088
],
20962089
)
20972090
);
2098-
2099-
// empty account
2100-
do_process_instruction(
2101-
burn(&program_id, &account_key, &owner_key, &[], 42).unwrap(),
2102-
vec![&mut account_account, &mut owner_account],
2103-
)
2104-
.unwrap();
2105-
2106-
// wrong owner
2107-
assert_eq!(
2108-
Err(TokenError::OwnerMismatch.into()),
2109-
do_process_instruction(
2110-
close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
2111-
vec![
2112-
&mut account_account,
2113-
&mut account3_account,
2114-
&mut owner2_account,
2115-
],
2116-
)
2117-
);
2118-
2119-
// close account
2120-
do_process_instruction(
2121-
close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
2122-
vec![
2123-
&mut account_account,
2124-
&mut account3_account,
2125-
&mut owner_account,
2126-
],
2127-
)
2128-
.unwrap();
2129-
let account: &mut Account = State::unpack_unchecked(&mut account_account.data).unwrap();
2130-
assert_eq!(account_account.lamports, 0);
2131-
assert_eq!(account.amount, 0);
2132-
assert_eq!(account3_account.lamports, 44);
2091+
assert_eq!(account_account.lamports, 42);
21332092

21342093
// close native account
21352094
do_process_instruction(
@@ -2143,9 +2102,8 @@ mod tests {
21432102
.unwrap();
21442103
let account: &mut Account = State::unpack_unchecked(&mut account2_account.data).unwrap();
21452104
assert!(account.is_native);
2146-
assert_eq!(account_account.lamports, 0);
21472105
assert_eq!(account.amount, 0);
2148-
assert_eq!(account3_account.lamports, 46);
2106+
assert_eq!(account3_account.lamports, 4);
21492107
}
21502108

21512109
#[test]

0 commit comments

Comments
 (0)