The moderator may correct a posted outcome (fix a wrong outcome or attacker) right up until the first claim trips the one-way claimsStarted finality latch — DESIGN §4 states the re-flag window "closes on the first claim (by design)." Every value-moving claim/sweep path sets claimsStarted on execution (claimSurvived, claimCorrupted, claimAttackerBounty, sweepUnclaimedCorrupted, claimExpired), so once value moves, the outcome is frozen. Separately, when a pool resolves SURVIVED with riskWindowStart == 0 (no on-chain-observed risk window), _bonusShare pays zero to every staker, so the whole bonus pot is legitimately swept to recoveryAddress (DESIGN §5).
sweepUnclaimedBonus() is the one value-moving path that deliberately does not set claimsStarted, and its reservation gates the accounted bonus solely on riskWindowStart != 0. So when riskWindowStart == 0, the entire accounted snapshotTotalBonus is treated as unreserved and can be transferred out without tripping the finality latch. Because recoveryAddress is owner-settable at any time (setRecoveryAddress, onlyOwner), the sponsor can point it at itself and, the moment the moderator posts SURVIVED, front-run the moderator's pending correction to good-faith CORRUPTED with a permissionless sweepUnclaimedBonus. The bonus lands at the sponsor's address, claimsStarted stays false (so the correction still "succeeds"), and the corrected bountyEntitlement is recomputed from the now-drained pot — leaving the named whitehat entitled to principal only. DESIGN §4's guarantee is violated: value left the pool before any "claim," yet the correction window it was supposed to protect is hollow.
Occurs whenever a genuinely in-scope breach is settled on a pool whose active-risk window was never observed on-chain (riskWindowStart == 0) — the default for any low-activity pool, since the window is sealed only if some interaction happens to coincide with the active-risk dwell.
Occurs on the exact SURVIVED→good-faith-CORRUPTED correction that DESIGN §4's re-flag window is built for (the moderator's off-chain in/out-of-scope judgement being revised), so it fires during a supported, anticipated operation rather than an unusual error.
The sponsor is economically motivated (the swept bonus lands at its own recoveryAddress) and can reliably win the race — sweepUnclaimedBonus is permissionless and the correction is a public mempool transaction it front-runs.
The named good-faith attacker (whitehat) permanently loses the entire bonus portion of the bounty; the bonus pot is designed to be substantial (it exists to attract stakers), so the loss can be large.
The value is misappropriated between parties — from the whitehat the corrected outcome owes it to, to the sponsor — and is irreversible (it has physically left the pool to a sponsor-controlled address).
A protocol-documented safety mechanism (the moderator's pre-claim outcome correction) is silently defeated by a permissionless action, violating the DESIGN §4 guarantee that correction is possible until the first claim.
Add to a test inheriting the project's BaseConfidencePoolTest and run with forge test. Both pass green.
Do not set claimsStarted inside the sweep — that would let a 1-wei donation trip the finality latch and block the moderator's re-flag window (the reason the latch is intentionally omitted here). Instead, reserve the accounted bonus whenever the correction window is still open (!claimsStarted), so only genuine donations/dust remain sweepable before finality:
Once a legitimate claim sets claimsStarted, the outcome is final and the DESIGN §5 riskWindowStart == 0 behavior resumes (the unowed bonus becomes sweepable to recoveryAddress). This closes the front-running window without reintroducing the dust-griefing concern.
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.