Skip to main content
Sigvex

Cross-Instruction State Desync Remediation

How to fix cross-instruction state desynchronization.

Cross-Instruction State Desync Remediation

Overview

Related Detector: Cross-Instruction State Desync

Cross-instruction state manipulation enables double-spending and corruption. The fix is to use nonces or version fields to detect stale state, and to perform prepare-and-execute atomically within a single instruction when possible.

// Use nonce-based state validation
require!(state.nonce == expected_nonce, StaleState);
process(state)?;
state.nonce += 1;  // Invalidate for replay

Alternative Mitigations

Single-Instruction Design

Combine prepare and execute into a single instruction to eliminate the desync window:

pub fn prepare_and_execute(ctx: Context<Combined>, params: Params) -> Result<()> {
    let amount = calculate(params)?;
    transfer(ctx.accounts, amount)?;
    Ok(())
}

Common Mistakes

Mistake: Not Clearing State After Use

// WRONG: state.prepared remains true, can be replayed
require!(state.prepared, NotPrepared);
transfer(ctx, state.amount)?;
// Missing: state.prepared = false;

Always clear or version-bump state after consumption.

References