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.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.