Cross-Program State
Detects state inconsistencies and race conditions across CPI boundaries.
Cross-Program State
Overview
The cross-program state detector identifies state inconsistencies across CPI boundaries including race conditions in cross-program interactions, missing atomic operation guarantees, and state validation issues after CPI returns.
For remediation guidance, see Cross-Program State Remediation.
Why This Is an Issue
When a program reads account state, makes a CPI call, and then uses the previously-read state, the CPI call may have modified that state. This creates a Time-of-Check-Time-of-Use race condition where the program operates on stale data, leading to incorrect calculations, authorization bypasses, or fund theft.
How to Resolve
Before (Vulnerable)
let balance = ctx.accounts.vault.amount; // Read before CPI
invoke(&external_ix, accounts)?; // May modify vault
// balance is now stale
if balance >= threshold { process_withdrawal()?; }
After (Fixed)
invoke(&external_ix, accounts)?;
ctx.accounts.vault.reload()?; // Refresh after CPI
let balance = ctx.accounts.vault.amount; // Fresh read
if balance >= threshold { process_withdrawal()?; }
Example JSON Finding
{
"detector": "cross-program-state",
"severity": "high",
"confidence": 0.7,
"message": "Account state read before CPI used after CPI without reload",
"location": { "function": "process", "block": 3, "statement": 1 }
}
Detection Methodology
- State read/write tracking: Records account data reads and writes with block positions.
- CPI detection: Identifies all CPI calls including expression-based forms.
- Post-CPI stale usage: Flags variables read before CPI that are used after CPI without reload.
- Per-CPI state invalidation: Tracks which accounts each CPI could modify.
Limitations
False positives: CPI calls to programs that provably do not modify the read accounts. False negatives: State invalidation through indirect account relationships.
Related Detectors
- Cross-Program Reinit — reinitialization after CPI
- Anchor Constraint TOCTOU — constraint TOCTOU
- Readonly CPI Write Bypass — write lock bypass