Skip to content

Latest commit

 

History

History
80 lines (59 loc) · 2.38 KB

File metadata and controls

80 lines (59 loc) · 2.38 KB

Z009: Unbounded Proof-Verification Loops

Severity

HIGH - Causes resource exhaustion and contract DoS

Description

Detects loops that verify a caller-controlled, unbounded number of proofs in a single transaction. Proof verification is expensive; unbounded batches can exceed Soroban's CPU instruction budget, making the contract unusable.

Vulnerable Pattern

// ❌ BAD: Unbounded batch verification
pub fn batch_claim(env: Env, proofs: Vec<Proof>, inputs: Vec<Vec<u64>>) {
    // No length check - caller can send 1000 proofs!
    for (i, proof) in proofs.iter().enumerate() {
        verify_zk_proof(&env, &proof, &inputs[i]);
        process_claim(&env, &inputs[i]);
    }
    // Exceeds CPU budget, reverts, wastes gas
}

Impact: Even legitimate users cannot use the function if batch size isn't capped.

Secure Pattern

// ✅ GOOD: Bounded with maximum batch size
const MAX_BATCH_SIZE: usize = 10;

pub fn batch_claim(env: Env, proofs: Vec<Proof>, inputs: Vec<Vec<u64>>) {
    if proofs.len() > MAX_BATCH_SIZE {
        panic!("Batch size exceeds maximum of {}", MAX_BATCH_SIZE);
    }
    
    for (i, proof) in proofs.iter().enumerate() {
        verify_zk_proof(&env, &proof, &inputs[i]);
        process_claim(&env, &inputs[i]);
    }
}

Why This Matters

  • Availability: Contract becomes unusable if every call exhausts resources
  • Cost: Users waste fees on reverting transactions
  • DoS: Attacker can intentionally trigger resource exhaustion
  • Degraded UX: Legitimate batch operations fail unpredictably

Detection Method

  1. Find loops over collections (for, while, .iter())
  2. Check if loop body calls proof-verification functions
  3. Analyze collection source:
    • From function parameter → potentially unbounded
    • Fixed-size array → bounded
    • With .take(N) → bounded
  4. Check for explicit length validation
  5. Flag unbounded verification loops

Recommended Limits

Based on Soroban resource budgets:

  • Conservative: 5-10 proofs per transaction
  • Moderate: 10-20 proofs (measure actual CPU usage)
  • Document: Clearly state max batch size in comments

Related Rules

  • S021: Unbounded loops (general pattern)
  • G004: Resource consumption checks

Dependencies

  • #1192, #1194: ZK infrastructure
  • #1223: Test fixture

Examples

See contracts/fixtures/finding-codes/z009_unbounded_verify_loop.rs