Stack Depth Violation Remediation
How to fix CPI depth limit violations.
Stack Depth Violation Remediation
Overview
Related Detector: Stack Depth Violation
Solana enforces a maximum CPI depth of 4. The fix is to flatten CPI chains by restructuring program interactions so that the top-level instruction handler makes direct CPI calls rather than relying on intermediary programs to chain calls.
Recommended Fix
Before (Vulnerable)
// A -> B -> C -> D -> E (depth 5, FAILS)
pub fn complex_operation(ctx: Context<Op>) -> Result<()> {
invoke_program_b(ctx.accounts)?; // B calls C calls D calls E
Ok(())
}
After (Fixed)
// A -> B (depth 1), A -> C (depth 1), A -> D (depth 1)
pub fn complex_operation(ctx: Context<Op>) -> Result<()> {
invoke_program_b(ctx.accounts)?;
invoke_program_c(ctx.accounts)?;
invoke_program_d(ctx.accounts)?;
Ok(())
}
Alternative Mitigations
Multi-Instruction Transactions
Split deep chains into separate instructions within the same transaction:
const tx = new Transaction()
.add(instructionA)
.add(instructionB) // Each runs at depth 0
.add(instructionC);
Common Mistakes
Mistake: Not Accounting for Caller Depth
// WRONG: assumes this program is always called at depth 0
// If another program calls this via CPI, depth increases
pub fn handler(ctx: Context<Handler>) -> Result<()> {
cpi_call_1()?; // Depth depends on caller
cpi_call_2()?; // Each adds to the chain
Ok(())
}
Design programs to work within depth 2-3, leaving room for callers.