The moderator's pre-claim outcome-correction window (flagOutcome is re-flaggable while !claimsStarted, per docs/DESIGN.md §4) can be permanently foreclosed by a permissionless front-run. claimCorrupted() is callable by anyone, has no time/grace gate on the moderator-flagged bad-faith path, immediately sweeps the entire pool balance to the sponsor-controlled recoveryAddress, and sets claimsStarted = true. So after an honest-but-mistaken moderator flags bad-faith CORRUPTED — the exact mistake §4's correction window exists to fix — any third party (in particular the sponsor, who receives the funds) can front-run the corrective re-flag with claimCorrupted, permanently locking in the wrong outcome and sending all staker principal + bonus to the sponsor.
flagOutcome allows correction until the first claim:
DESIGN §4 justifies closing this window "on the first claim" by asserting the claimant is "an interested stakeholder exercising a correct outcome, not usurping one." That reasoning holds for claimSurvived / claimExpired, where caller == beneficiary == staker (a staker only ever pulls their own rightful share). It does not hold for the bad-faith claimCorrupted path:
caller ≠ beneficiary: the funds go to recoveryAddress (sponsor, per §10), not to the caller — the caller is not "an interested stakeholder exercising a correct outcome."
the beneficiary profits from locking in the wrong outcome: bad-faith CORRUPTED routes the whole pool to the sponsor, versus SURVIVED (principal + bonus returned to stakers) or good-faith CORRUPTED (whole pool to the named whitehat). The sponsor is directly incentivized to foreclose a correction toward a staker-favorable outcome.
the moderator has no defense: the pool owner is the sponsor (the factory passes the agreement owner as owner_), and pause() is onlyOwner — so the only party who could pause to protect the correction window is the beneficiary of the theft. Unlike the auto-CORRUPTED path in claimExpired (which correctly sits behind a 180-day grace), the moderator-flagged bad-faith path has no delay at all.
The correction the design promises for a mistaken outcome therefore does not exist for the single highest-stakes outcome (a full-pool sweep). SURVIVED is a legal outcome on a CORRUPTED registry (an out-of-scope breach — see flagOutcome L338), so nothing but the front-run's claimsStarted blocks the correct resolution.
Total loss of stakers' principal + bonus, misdirected to the sponsor (recoveryAddress), whenever an honest moderator's initial bad-faith CORRUPTED flag was wrong (the breach was out-of-scope → SURVIVED, or a whitehat did it → good-faith CORRUPTED). The moderator's documented ability to correct the mistake is nullified by a permissionless, sponsor-benefiting front-run, and the moderator has no defensive tool.
Add as test/poc/ReflagForeclosure.t.sol and run forge test --match-contract ReflagForeclosurePoC -vvv. Both tests pass. Alice and Bob stake in-term, a real risk window is observed, and the registry reaches CORRUPTED — the state under which the moderator can flag bad-faith CORRUPTED.
Output:
Give the bad-faith claimCorrupted sweep the same finality protection the design promises elsewhere: gate it behind a short delay after the flag (or the same moderator grace used by the auto path), and/or restrict the moderator-flagged bad-faith sweep to the moderator/owner rather than any caller — so the §4 correction window genuinely exists for the full-pool-sweep outcome. (The claimExpired auto-CORRUPTED path is unaffected: it sets claimsStarted atomically at resolution and is scope-blind by accepted design.)
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
View preliminary resultsAppeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.