Skip to main content
Sigvex

SPL Token Delegation Overflow

Detects integer overflow vulnerabilities in token delegation amount calculations.

SPL Token Delegation Overflow

Overview

Remediation Guide: How to Fix SPL Token Delegation Overflow

The delegation overflow detector identifies integer overflow vulnerabilities in token delegation amount calculations. When programs compute delegation amounts using unchecked arithmetic (addition, multiplication, or bit shifts), overflow can wrap the value, resulting in delegates receiving more or fewer tokens than intended. This can lead to complete account drainage.

Why This Is an Issue

Token amounts in Solana are u64 values. Unchecked arithmetic on these values can overflow:

  • Unchecked addition: base_amount + additional can wrap around u64::MAX, resulting in a small value that bypasses balance checks
  • Unchecked multiplication: price * quantity can overflow, producing an incorrect approval amount
  • Bit shifts: Left shifts can silently discard high bits, producing unexpected values
  • Missing balance validation: Approving amounts that exceed the actual account balance

An overflow in delegation amount calculation could allow an attacker to manipulate the approved amount, potentially draining the entire token account.

CWE mapping: CWE-190 (Integer Overflow), CWE-682 (Incorrect Calculation).

How to Resolve

pub fn calculate_and_approve(accounts: &[AccountInfo], base: u64, additional: u64) -> ProgramResult {
    // Use checked arithmetic
    let amount = base
        .checked_add(additional)
        .ok_or(ProgramError::ArithmeticOverflow)?;

    // Validate against balance
    let token_data = Account::unpack(&accounts[0].data.borrow())?;
    if amount > token_data.amount {
        return Err(ProgramError::InsufficientFunds);
    }

    let ix = spl_token::instruction::approve(
        &spl_token::id(), accounts[0].key, accounts[1].key,
        accounts[2].key, &[], amount,
    )?;
    invoke(&ix, accounts)?;
    Ok(())
}

Examples

Vulnerable Code

pub fn approve_calculated(accounts: &[AccountInfo], base: u64, multiplier: u64) -> ProgramResult {
    // VULNERABLE: unchecked multiplication can overflow
    let amount = base * multiplier;

    // VULNERABLE: no balance validation
    let ix = spl_token::instruction::approve(
        &spl_token::id(), accounts[0].key, accounts[1].key,
        accounts[2].key, &[], amount,
    )?;
    invoke(&ix, accounts)?;
    Ok(())
}

Fixed Code

pub fn approve_calculated(accounts: &[AccountInfo], base: u64, multiplier: u64) -> ProgramResult {
    let amount = base
        .checked_mul(multiplier)
        .ok_or(ProgramError::ArithmeticOverflow)?;

    let token_data = Account::unpack(&accounts[0].data.borrow())?;
    require!(amount <= token_data.amount, InsufficientBalance);

    let ix = spl_token::instruction::approve(
        &spl_token::id(), accounts[0].key, accounts[1].key,
        accounts[2].key, &[], amount,
    )?;
    invoke(&ix, accounts)?;
    Ok(())
}

Sample Sigvex Output

{
  "detector_id": "spl-token-delegation-overflow",
  "severity": "critical",
  "confidence": 0.80,
  "description": "Token delegation uses amount computed using unchecked addition. Integer overflow could result in approving an incorrect amount.",
  "location": { "function": "approve_calculated", "offset": 1 }
}

Detection Methodology

  1. Arithmetic classification: Identifies unchecked addition, multiplication, and bit shift operations in assignment statements.
  2. Amount tracking: Tracks variables derived from arithmetic operations that are subsequently used in Approve/ApproveChecked CPI calls.
  3. Balance validation: Checks for comparison operations (<=, <) that indicate balance validation before delegation.
  4. Combined analysis: Reports critical findings when unchecked arithmetic results flow directly into delegation operations.

Limitations

  • The detector uses heuristic-based classification of arithmetic operations; checked_add/checked_mul calls may not be distinguishable from unchecked variants in decompiled bytecode.
  • Balance validation via helper functions may not be detected.
  • Arithmetic in called functions (not inlined) is not tracked.

References