The claimExpired function unconditionally sets claimsStarted = true during pool resolution, even when the caller has zero stake and no value is transferred. This permanently closes the moderator’s re‑flag window with a zero‑value transaction, locking in an incorrect outcome if the moderator later needs to correct it.
The moderator can re‑flag the pool outcome until the first claim occurs (claimsStarted = false). This allows the moderator to correct a mistaken outcome.
A caller with zero stake can invoke claimExpired, which resolves the pool and sets claimsStarted = true even though no value is transferred. This permanently closes the re‑flag window.
Likelihood:
Any external account can call claimExpired after expiry, including those with zero stake.
The attack requires no special conditions; simply being past expiry.
Impact:
The moderator’s re‑flag window is permanently closed, potentially locking an incorrect outcome.
Stakers may suffer indirect loss if the true outcome should have been different (e.g., good‑faith CORRUPTED bounty).
Explanation:
A pool is created and a staker deposits 100 tokens. After expiry, a zero‑stake account calls claimExpired. The function resolves the pool to SURVIVED (because the registry state is PRODUCTION) and sets claimsStarted = true. The zero‑staker has no stake, so the function returns early without any transfer.
Then, the legitimate outcome moderator attempts to re‑flag the outcome to good‑faith CORRUPTED (simulating a later discovery of a breach), but the call reverts with OutcomeAlreadySet because claimsStarted is already true. This shows that the moderator’s re‑flag window was closed by a zero‑value transaction.
Mitigation explanation:
The fix moves the claimsStarted = true assignment from the resolution block into the actual claim branch that executes only when the caller has a non‑zero stake and a valid claim. The resolution of the pool (setting outcome) is kept separate from the finality latch.
A zero‑stake caller can still trigger the pool’s resolution (useful for mechanically advancing a stuck pool), but it does not close the moderator’s re‑flag window. The re‑flag window now ends only when a genuine claimant receives tokens, matching the design intent of “finality is value‑movement.”
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.