Normal behavior. After the moderator flags an outcome, participants claim their entitlement. The resolution is meant to become final only once value has actually been distributed, so that already-paid amounts cannot be clawed back.
Issue. claimsStarted is a single, pool-wide flag. The first participant to claim sets it, and once set, the outcome can never be re-resolved for the entire pool. Because the flag is global rather than per-position, one self-interested staker can permanently lock a favorable-but-wrong outcome for everyone — including other stakers whose principal is still held by the contract, and the recoveryAddress that should have received it. The lock therefore freezes funds that have not moved, not just the claimant's own paid-out amount.
Likelihood:
An outcome is flagged SURVIVED while the true in-scope outcome is CORRUPTED (an in-scope breach that should slash stakers).
Any staker calls claimSurvived() immediately; it needs only a nonzero stake and is permissionless.
The claimant is economically motivated: claiming keeps principal (and bonus) that a CORRUPTED resolution would send to recoveryAddress.
Impact:
The pool outcome is permanently frozen as SURVIVED.
Every staker — including those who never claimed and whose principal is still in the contract at the moment of the lock — can then withdraw their stake, evading slashing.
The recoveryAddress receives nothing, although the entire pool should have been swept to it.
Two stakers deposit 100 each (200 in the pool). The agreement is CORRUPTED (in-scope breach → the whole pool should sweep to recoveryAddress). One staker claims first; that single claim locks the outcome pool-wide, and the second staker — whose 100 was still in the contract when the lock happened — walks out with it too.
Place in test/unit/ and run:
forge test --match-test test_oneClaimLocks -vv
Output:
Decouple finality from the first claim, so a single claimant can no longer lock the whole pool. Record the flag time and require a short finalization delay before any claim is allowed; during that delay the outcome can still be re-resolved, but no claim can pre-empt it.
Apply the same delay guard to every claim entrypoint that sets claimsStarted (claimCorrupted, claimAttackerBounty, sweepUnclaimedCorrupted, claimExpired).
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.