When the moderator re-flags a good-faith CORRUPTED outcome to correct a mistakenly-named attacker more than 180 days after the pool's first good-faith CORRUPTED flag, the corruptedClaimDeadline is recomputed from the original _firstGoodFaithCorruptedAt timestamp (which is never reset). The deadline is already expired, so the newly-named correct whitehat cannot claim the bounty. The full pool is swept to the sponsor's recoveryAddress — a permanent, irreversible loss of the entire bounty for the intended beneficiary.
Normal behavior: flagOutcome(CORRUPTED, true, attacker) names a whitehat attacker and starts a 180-day claim window via corruptedClaimDeadline. DESIGN.md §4 documents that re-flagging is explicitly supported to "fix a typo'd outcome/attacker before any participant locks in the wrong distribution." Re-flagging is gated only by claimsStarted == false.
The issue: _firstGoodFaithCorruptedAt is set exactly once — on the first-ever good-faith CORRUPTED flag — and is never reset for the lifetime of the pool (lines 363-372). On re-flag, corruptedClaimDeadline is always derived from this original anchor:
If >180 days have elapsed since the first flag, the re-computed deadline is in the past. The state machine allows the transition (claimsStarted is still false), the attacker field updates, OutcomeFlagged emits — but the liveness property is broken: the newly-named attacker cannot claim (ClaimWindowExpired), and anyone can sweep the pool to recoveryAddress via sweepUnclaimedCorrupted().
The gap: DESIGN.md §4 says re-flagging exists to "fix a typo'd attacker" (unqualified promise). The implementation silently fails at this purpose after 180 days. The code comment at L368-369 acknowledges the mechanism but DESIGN.md — the authoritative reference per the contest brief — does not document this limitation as a known issue or accepted tradeoff.
Likelihood: Low
Moderator must initially name the wrong attacker address (typo, identity dispute, unresponsive whitehat)
180 days must elapse before the correction is made
The correction window is generous, but real-world Safe Harbor agreements involve legal coordination, identity verification, and DAO governance delays that can extend beyond 180 days
No attacker action required; purely a function of moderator operational timeline
Impact: High
Complete, permanent, irreversible loss of the correctly-named whitehat's entire bounty entitlement (up to 100% of snapshotTotalStaked + snapshotTotalBonus)
Full pool diverted to the sponsor's recoveryAddress — a windfall to the sponsor at the whitehat's expense
The failure is silent: the re-flag transaction succeeds, emits OutcomeFlagged, and updates the attacker field, giving no on-chain signal that the correction is useless
Permissionless: once the re-flag lands with an expired deadline, any third party can immediately trigger sweepUnclaimedCorrupted() — no window for intervention
Run: forge test --match-contract PoC_CorruptedBountyDeadlineExpired -vvv
Result: [PASS] test_poc_corruptedClaimDeadline_expiredOnReflag() (gas: 619243)
Option 1 (preferred): Reset _firstGoodFaithCorruptedAt when the attacker address changes on re-flag, giving a fresh 180-day window to a newly-named identity while preserving the non-extendable deadline for same-attacker re-confirmations:
Option 2 (simpler, fail-loud): Revert the re-flag if the recomputed corruptedClaimDeadline would already be expired, forcing the moderator to use an alternate resolution path rather than silently committing a dead state:
Both options preserve the invariant that the deadline must never be extendable for the same attacker while ensuring the documented "fix a typo'd attacker" workflow actually works.
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.