When riskWindowStart == 0 (the pool's one-way risk latch was never triggered because nobody observed the registry in active-risk state), a staker can call claimExpired() to settle the pool as EXPIRED before the moderator flags CORRUPTED. This bypasses the intended CORRUPTED settlement path and returns principal to stakers instead of sweeping to the recovery address.
In ConfidencePool.sol:532-534, the automatic CORRUPTED resolution inside claimExpired() is gated on riskWindowStart != 0:
When riskWindowStart == 0, CORRUPTED state is skipped and the pool falls through to EXPIRED resolution. After claimExpired() sets claimsStarted = true, the moderator can no longer call flagOutcome(CORRUPTED) (line 327).
If the registry enters CORRUPTED state without anyone first observing the active-risk transition, a staker can:
Monitor the registry
Call claimExpired() immediately when the pool expires
Force EXPIRED resolution → withdraw principal
Moderator's subsequent flagOutcome(CORRUPTED) reverts
This is documented in DESIGN.md §5 as "accepted, not a bug" but represents a bypass of the intended CORRUPTED settlement mechanics.
Remove the riskWindowStart != 0 gate from claimExpired() auto-CORRUPTED:
ConfidencePool.sol:532-534 — CORRUPTED gate
ConfidencePool.sol:327 — claimsStarted lock
DESIGN.md §5 — documented race condition
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.