On the CORRUPTED-path, resolution finality is tied to claimsStarted: flagOutcome may be re-flagged to correct a mistaken outcome, but only until the first value-moving claim latches claimsStarted. The design's stated invariant (docs/DESIGN.md §4) is "Once value has left the contract, a corrective re-flag cannot be honored without breaking balance accounting."
sweepUnclaimedBonus deliberately never sets claimsStarted (to stop a 1-wei donation from slamming the re-flag window shut), yet in the riskWindowStart == 0 / totalEligibleStake == 0 branch it removes the entire real bonus from the pool and zeroes totalBonus. Because the outcome stays re-flaggable, a moderator correction from SURVIVED to good-faith CORRUPTED re-snapshots snapshotTotalBonus from an already-emptied pot, so the named whitehat is paid principal only while the bonus sits at recoveryAddress.
Severity: Medium - Medium Impact x Medium Likelihood.
Likelihood: Medium - requires specific but achievable conditions, none privileged on the exploiting side.
Occurs when the registry reaches terminal CORRUPTED without any pool interaction ever observing an active-risk state, so riskWindowStart stays 0 (the documented "no observed risk" path, achievable whenever no one stakes/withdraws/pokes during the active-risk interval)
Occurs when the moderator uses the documented pre-claim re-flag window to correct a SURVIVED flag to good-faith CORRUPTED (a supported, non-erroneous reassessment when an initially out-of-scope-looking breach is later judged in-scope), while the sponsor, the recoveryAddress beneficiary calls the permissionless sweepUnclaimedBonus in the interval before the correction lands.
Impact: Medium - indirect fund risk; a bounded amount is misrouted to a protocol-designated address rather than openly drained.
The named whitehat receives only the principal; the bonus they are entitled to under good-faith CORRUPTED (whole pool = principal + bonus) is permanently redirected to the sponsor-controlled recoveryAddress. Because a sponsor typically funds a large bonus to attract stakers, the misdirected amount can be a majority of the pool value.
The protocol's own coupling of value movement to finality §4 is broken: real bonus leaves the pool under a still-re-flaggable outcome
Latch finality precisely when real (non-donation) bonus leaves the pool, keeping the dust-donation exemption intact.
Impact – Medium Up to the entire bonus pool can be routed to the wrong party for good, with no on-chain way to unwind it, and in a stakerless pool the effect is total since bountyEntitlement computes to zero and claimAttackerBounty reverts outright. This impact is definitely not High: the pool stays solvent throughout with no principal ever at risk, and the money ends up at the sponsor's own recoveryAddress, which in most pools means a sponsor recovering a bonus they funded themselves. The whitehat's claim on that bonus also only exists because the moderator changed their mind after the fact. Likelihood – Low Four separate things have to coincide: nobody touches the pool for the whole active-risk window (or there are no stakers to begin with), the moderator flags SURVIVED and later reverses to CORRUPTED, that reversal is good-faith with a named attacker, and a sweep lands between the two flags. The first cuts against staker self-interest, since skipping the poke costs them their entire bonus share, and the second asks the moderator to overturn a scope judgement, which is a bigger deal than the typo fix DESIGN.md #4 offers the window for. The sweep itself I'd treat as near-certain once the rest holds, given it's permissionless and the sponsor has an obvious reason to make the call, but assembling the first three in one pool lifecycle is where this stays rare.
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.