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.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.