The protocol allows the moderator to correct typos or errors in flagOutcome by re-flagging before the first claim occurs. A good-faith CORRUPTED flag gives the named attacker a 180-day window (CORRUPTED_CLAIM_WINDOW) to claim their bounty before it becomes permissionlessly sweepable by the sponsor.
If the moderator flags CORRUPTED, then SURVIVED, and then corrects back to CORRUPTED naming a different attacker, the new attacker does not get a fresh 180-day window. The _firstGoodFaithCorruptedAt timestamp never resets, so the new attacker's claim window is silently truncated to whatever remains of the original 180 days.
Likelihood:
The moderator flags a good-faith CORRUPTED outcome, then temporarily re-flags to SURVIVED or another outcome due to new information or further investigation.
The moderator later discovers a different whitehat was the true cause and re-flags back to CORRUPTED with the new attacker late in the original 180-day window.
Impact:
The newly named attacker has their claim window severely truncated, potentially leaving them only days or hours to claim their rightfully earned bounty.
If the new attacker misses this unexpectedly short window, their entire bounty is lost and can be swept to the sponsor's recoveryAddress via sweepUnclaimedCorrupted.
The following sequence of events demonstrates how a valid sequence of moderator actions permanently anchors the claim deadline to the very first flag, unfairly penalizing a newly discovered attacker.
Because _firstGoodFaithCorruptedAt is only written when it equals 0, any subsequent re-flags back into the CORRUPTED state reuse the original timestamp, regardless of how much time has passed or if the recipient has changed.
To resolve this issue while maintaining the invariant that a single attacker cannot get their deadline extended, the contract should track the previous attacker. If the moderator re-flags and names a new attacker, the _firstGoodFaithCorruptedAt timestamp should be reset to block.timestamp to guarantee the new whitehat receives their full 180-day claim window.
The diff below implements this by temporarily storing the oldAttacker before the state update, and expanding the zero-check to also reset the timestamp if attacker_ != oldAttacker.
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.