Skip to main content
Sigvex

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.

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

References