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 + additionalcan wrap aroundu64::MAX, resulting in a small value that bypasses balance checks - Unchecked multiplication:
price * quantitycan 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
- Arithmetic classification: Identifies unchecked addition, multiplication, and bit shift operations in assignment statements.
- Amount tracking: Tracks variables derived from arithmetic operations that are subsequently used in Approve/ApproveChecked CPI calls.
- Balance validation: Checks for comparison operations (
<=,<) that indicate balance validation before delegation. - 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_mulcalls 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.
Related Detectors
- SPL Token Delegation Security — detects unsafe delegation patterns
- Integer Overflow — detects general integer overflow vulnerabilities