Skip to main content
Sigvex

SPL Token Account Close

Detects unsafe account close operations including non-empty accounts and rent drain attacks.

SPL Token Account Close

Overview

Remediation Guide: How to Fix SPL Token Account Close

The account close security detector identifies programs that close token accounts without verifying the balance is zero, without validating the destination account for rent reclaim, or without checking close authority. These gaps enable token loss, rent drain attacks, and unauthorized account closures.

Why This Is an Issue

Closing a token account transfers its remaining SOL rent to a destination address. Without proper validation:

  • Token loss: Closing a non-empty account loses any remaining tokens forever
  • Rent drain: An attacker closes accounts and directs rent SOL to their own address
  • Unauthorized closure: Closing accounts without proper authority disrupts protocol operations
  • Destination manipulation: Sending rent to an unvalidated destination address

CWE mapping: CWE-863 (Incorrect Authorization), CWE-404 (Improper Resource Shutdown).

How to Resolve

pub fn close_token_account(accounts: &[AccountInfo]) -> ProgramResult {
    let token_account = &accounts[0];
    let destination = &accounts[1];
    let authority = &accounts[2];

    // Verify balance is zero
    let token_data = Account::unpack(&token_account.data.borrow())?;
    if token_data.amount > 0 {
        return Err(ProgramError::Custom(ErrorCode::NonZeroBalance as u32));
    }

    // Verify authority
    if !authority.is_signer { return Err(ProgramError::MissingRequiredSignature); }

    // Verify destination is expected
    if destination.key != &EXPECTED_DESTINATION {
        return Err(ProgramError::InvalidAccountData);
    }

    let ix = spl_token::instruction::close_account(
        &spl_token::id(), token_account.key, destination.key, authority.key, &[],
    )?;
    invoke(&ix, accounts)?;
    Ok(())
}

Examples

Sample Sigvex Output

{
  "detector_id": "spl-token-account-close",
  "severity": "high",
  "confidence": 0.80,
  "description": "Token account closed without verifying balance is zero and without validating destination for rent reclaim.",
  "location": { "function": "close_account", "offset": 1 }
}

Detection Methodology

  1. CloseAccount identification: Detects CloseAccount CPI operations (discriminator 9).
  2. Balance validation: Checks for balance comparison operations before the close.
  3. Authority validation: Verifies the authority account has been validated as a signer.
  4. Destination validation: Checks whether the destination account for rent reclaim is validated.

Limitations

  • The SPL Token program enforces that only accounts with zero token balance can be closed, but explicit checks provide better error messages.
  • Destination validation patterns vary and may not all be recognized.

References