expiry instead of the corruption transition, letting a post-grace breach confiscate a pool that already survived its termSeverity: Medium
A pool that reaches expiry while the agreement remains UNDER_ATTACK or PROMOTION_REQUESTED has survived the insured term. The expected resolution is EXPIRED, returning principal and earned bonus.
claimExpired() reads the live registry state when settlement is triggered. Because the permissionless CORRUPTED grace period is anchored to expiry rather than the corruption transition, a breach appearing after expiry + MODERATOR_CORRUPTED_GRACE can be finalized immediately as bad-faith CORRUPTED.
Likelihood:
An approved attack remains UNDER_ATTACK beyond the pool deadline while no participant calls claimExpired(), leaving the pool unresolved.
The agreement becomes CORRUPTED only after the expiry-based grace period, allowing the first caller to bypass a fresh moderator-review window.
Impact:
The full pool balance, including principal and bonus, is transferred to recoveryAddress even though the insured term ended before corruption.
claimsStarted prevents the moderator from later choosing SURVIVED for an out-of-scope breach or naming a good-faith whitehat.
The test deposits 100 tokens of principal and 20 tokens of bonus, then opens the risk window by moving the agreement to UNDER_ATTACK. Time advances beyond both expiry and the expiry-based grace period while the pool remains unresolved.
Only afterward does the agreement become CORRUPTED. A permissionless caller resolves the pool as bad-faith CORRUPTED, and claimCorrupted() transfers all 120 tokens to recoveryAddress, leaving Alice with none of her principal.
Only a corruption that became terminal at or before expiry should confiscate the pool. A corruption first observed after the insured term should resolve EXPIRED.
Impact - High The mechanical branch always picks bad-faith, so the whole corpus lands at recoveryAddress and claimsStarted makes it permanent in the same call. Both alternatives it forecloses send the money elsewhere: DESIGN.md #8 lets the moderator flag SURVIVED for an out-of-scope breach, returning everything to stakers, and good-faith CORRUPTED reserves the pool for a named whitehat. Losing the classification decides who gets paid. Likelihood - Low The pool has to sit unresolved through the whole window past expiry, which is the hard part, since claimExpired stays permissionless throughout and would settle it as EXPIRED against the live active-risk state. Any staker with principal waiting has reason to make that call. Once corruption does land late, the moderator's first legal moment to classify and the fallback's first to finalize arrive together, so ordering alone decides it.
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.