Token Balance Invariant
Detects token operations that violate balance invariants such as mint without supply update or burn without supply decrease.
Token Balance Invariant
Overview
Remediation Guide: How to Fix Token Balance Invariant
The token balance invariant detector identifies token operations (mint, burn, transfer) that do not maintain proper accounting invariants. The fundamental invariant is that sum(all_account_balances) == total_supply. Violations lead to supply inflation/deflation, accounting discrepancies, fund loss, or protocol insolvency.
Why This Is an Issue
Token operations must maintain mathematical invariants:
- Mint:
total_supply' = total_supply + amountANDaccount_balance' = account_balance + amount - Burn:
total_supply' = total_supply - amountANDaccount_balance' = account_balance - amount - Transfer:
from_balance' = from_balance - amountANDto_balance' = to_balance + amount
When programs implement custom token logic (rather than using SPL Token CPI), violations can occur:
- Mint without supply update: Account balance increases but total supply stays the same, creating phantom tokens
- Burn without supply decrease: Tokens are removed from an account but supply count remains inflated
- Asymmetric transfer: Source decreases by a different amount than destination increases
CWE mapping: CWE-682 (Incorrect Calculation), CWE-754 (Improper Check for Unusual Conditions).
How to Resolve
pub fn mint_tokens(mint: &mut Mint, account: &mut Account, amount: u64) -> ProgramResult {
// Update BOTH account balance and total supply atomically
account.amount = account.amount
.checked_add(amount)
.ok_or(ProgramError::ArithmeticOverflow)?;
mint.supply = mint.supply
.checked_add(amount)
.ok_or(ProgramError::ArithmeticOverflow)?;
// Invariant: sum(balances) == supply
Ok(())
}
pub fn burn_tokens(mint: &mut Mint, account: &mut Account, amount: u64) -> ProgramResult {
account.amount = account.amount
.checked_sub(amount)
.ok_or(ProgramError::InsufficientFunds)?;
mint.supply = mint.supply
.checked_sub(amount)
.ok_or(ProgramError::ArithmeticOverflow)?;
Ok(())
}
Examples
Vulnerable Code
pub fn custom_mint(account: &mut Account, amount: u64) -> ProgramResult {
// VULNERABLE: updates balance but not total supply
account.amount = account.amount.checked_add(amount)?;
// Missing: mint.supply = mint.supply.checked_add(amount)?;
Ok(())
}
Fixed Code
pub fn custom_mint(mint: &mut Mint, account: &mut Account, amount: u64) -> ProgramResult {
account.amount = account.amount.checked_add(amount)?;
mint.supply = mint.supply.checked_add(amount)?; // Maintains invariant
Ok(())
}
Sample Sigvex Output
{
"detector_id": "token-balance-invariant",
"severity": "critical",
"confidence": 0.70,
"description": "Detected a token balance increase resembling a mint operation, but no corresponding total supply update was found. This violates the fundamental accounting invariant.",
"location": { "function": "custom_mint", "offset": 1 }
}
Detection Methodology
- Balance update tracking: Identifies assignment statements that use addition or subtraction operations, classifying them as potential balance or supply updates.
- Mint pattern detection: Heuristically identifies addition operations that resemble minting (balance increase without corresponding source decrease).
- Burn pattern detection: Identifies subtraction operations resembling burns (balance decrease without corresponding supply decrease).
- Transfer validation: For CPI-based transfers, checks for prior balance validation.
- Proximity analysis: Verifies that supply updates occur within reasonable proximity of balance updates.
Limitations
- Balance vs supply update classification is heuristic-based and conservative; many potential violations are not flagged to avoid false positives.
- Programs using SPL Token CPI for all operations are inherently safe (SPL Token maintains invariants) and should not trigger findings.
- Custom token implementations with non-standard data layouts may not be recognized.
- Cross-instruction invariant violations (where mint and supply update are in separate instructions) are not detected.
Related Detectors
- SPL Token Mint Authority — detects mint authority issues
- SPL Token Freeze Burn — detects burn operation issues
- Zero Amount Operation — detects zero-value operations