SPL Token Account Close Remediation
How to fix unsafe account close operations in Solana programs.
SPL Token Account Close Remediation
Overview
Related Detector: SPL Token Account Close
Unsafe account closes can lose tokens, drain rent to attackers, or disrupt protocol operations. The fix requires verifying zero balance, validating authority, and checking the rent destination.
Recommended Fix
Before (Vulnerable)
// No balance check, no destination validation
spl_token::instruction::close_account(
&spl_token::id(), token_account.key, destination.key, authority.key, &[],
)?;
After (Fixed)
// Verify zero balance
let data = Account::unpack(&token_account.data.borrow())?;
require!(data.amount == 0, NonZeroBalance);
// Validate authority
require!(authority.is_signer, MissingSignature);
// Validate destination
require!(destination.key == &expected_dest, InvalidDestination);
spl_token::instruction::close_account(
&spl_token::id(), token_account.key, destination.key, authority.key, &[],
)?;
Alternative Mitigations
1. Anchor close constraint
#[account(
mut,
close = destination,
constraint = token_account.amount == 0 @ ErrorCode::NonZeroBalance
)]
pub token_account: Account<'info, TokenAccount>,
2. Burn before close
If the account has tokens, burn them first, then close:
token::burn(ctx.accounts.burn_ctx(), remaining_amount)?;
token::close_account(ctx.accounts.close_ctx())?;
Common Mistakes
Mistake 1: Closing non-empty accounts
// WRONG: tokens are lost when account is closed with balance > 0
Mistake 2: Not validating rent destination
// WRONG: attacker can redirect rent SOL to their address