# Proof-Slot Leak Halts Parallel Prover

ParallelProverService reserves a proof slot before make_proof succeeds; on error the slot leaks, eventually deadlocking the prover and halting rollup proofs.

- Payout: Contest reward
- Severity: medium
- Program: Citrea
- Credited: AlmanaxAI
- Disclosed: 2025-10-21
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_citrea_jul2025.pdf#3.2.10
- Library page: https://bugbountylibrary.com/r/cantina%3Acitrea_jul2025%3A3.2.10
- Tags: domain:web3 impact:dos kind:contest platform:cantina sev:medium tech:rust technique:source-review vuln:accounting-error vuln:dos

**Target:** ParallelProverService in crates/prover-services/src/parallel.rs
**Root cause:** reserve_proof_slot increments ongoing_proof_count before make_proof is called; the only decrement lives in the spawned task, so an early `?` return on make_proof error leaks the slot permanently.
**Steps:**
1. Call `start_proving` with a corrupt ELF (e.g. `vec![0u8;16]`) so `make_proof` returns Err.
2. Observe the `?` propagates before the tokio task is spawned, so `ongoing_proof_count` is never decremented and notifier never signalled.
3. Repeat until PARALLEL_PROOF_LIMIT (default 4-16) slots are leaked.
4. Next `start_proving` call blocks forever in `reserve_proof_slot`, hanging the prover.
**How found:** Code reading of parallel.rs: noticed reserve_proof_slot precedes make_proof while the decrement only exists inside the post-success spawned task, and git grep confirmed no other writer to ongoing_proof_count.
**Insight:** When auditing async slot/semaphore accounting, check that every acquire has a matching release on ALL exit paths including early `?` returns before the task is spawned; a counter incremented before a fallible call is a classic leak-to-deadlock.
