If a pool expires while the BattleChain registry is in UNDER_ATTACK before transitioning to CORRUPTED, calling claimExpired auto-resolves the pool to EXPIRED and sets claimsStarted = true. This permanently locks the outcome, blocking the moderator from flagging CORRUPTED when the registry transitions post-expiry. Stakers withdraw all funds, leaving zero recovery funds for the sponsor. This creates a race condition where attacker has call claimexpired before moderator can flag corrupted.
The claimExpired function is completely permissionless and can be invoked by any caller (including non-stakers, bots, or an attacker) once block.timestamp >= expiry.
If the registry is in UNDER_ATTACK at expiry, any caller can trigger the auto-resolution. This sets outcome = PoolStates.Outcome.EXPIRED and unconditionally latches claimsStarted = true (lines 566-575). Once set, any corrective flagOutcome call by the moderator reverts:
This allows an attacker or a bot to front-run the registry transition or moderator flag the block the pool expires, locking the outcome to EXPIRED and preventing recovery sweeps.
Severity: High / Critical
Likelihood: Medium-High (registry updates or moderator actions lag pool expiry).
Impact: Critical (complete diversion of recovery/bounty funds to stakers).
Important: Unlike the no-risk-window race (where bonus sweeps to recovery and principal can still be recovered via CORRUPTED flag), this variant permanently diverts ALL funds. Once stakers claim under EXPIRED lock, the pool balance is zero. The moderator cannot re-flag CORRUPTED (reverts OutcomeAlreadySet) and cannot recover any funds they have already been paid out to stakers.
Remove the unconditional claimsStarted = true assignment from the claimExpired auto-resolution block in src/ConfidencePool.sol. Let the outcome remain overrideable by the moderator until a staker actually claims their payout (which sets claimsStarted = true at line 600).
Run command:
Below is the unit test simulating this attack flow:
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.