// @audit claimCorrupted is permissionless with no caller check; sweeps entire pool in same tx as bad-faith flag
// @audit Good-faith correction window is caller-gated (claimAttackerBounty: msg.sender == attacker)
// @audit Bad-faith has NO equivalent protection — any caller can foreclose the correction
DESIGN.md §4 guarantees the moderator can correct an outcome by re-flagging before the first claim. For a good-faith CORRUPTED flag this window is enforceable because claimAttackerBounty is gated to msg.sender == attacker. For a bad-faith CORRUPTED flag the window is not: claimCorrupted() (line 408) has no caller check.
The function is permissionless, sweeps the entire pool to recoveryAddress, and latches claimsStarted = true in the same call. The sponsor, who controls recoveryAddress (mutable anytime at line 611), executes the sweep in the same block a bad-faith flag lands, permanently foreclosing the moderator's correction. The whitehat, entitled to the entire pool under §12, receives nothing. This is realistic: an exploit initially flagged as blackhat is later confirmed as a whitehat disclosure — exactly the correction §4's re-flag window exists to protect.
The PoC below shows a zero-stake caller sweeping the pool via permissionless claimCorrupted() immediately after a bad-faith flag. The moderator's good-faith correction reverts, and the whitehat receives nothing — the full pool diverts to recoveryAddress.
claimCorrupted() is permissionless with no caller check. The sponsor controls recoveryAddress (mutable anytime at line 611) and is uniquely incentivized: the bad-faith sweep sends the entire pool there. The call is immediate and can execute same-block as the bad-faith flag — the moderator has zero window to correct.
100% of the pool diverted to sponsor-controlled recoveryAddress instead of the legitimate whitehat. Irreversible once claimsStarted is latched. Violates §12 and §10.
Restrict the first claimCorrupted() after a bad-faith flag to recoveryAddress or the moderator, symmetric to how claimAttackerBounty is caller-gated.
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.