Skip to main content
Sigvex

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.

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.

References