The contract allows stakers to call claimExpired() post-expiry to mechanically resolve the pool and claim their portion of the stakes and bonus pool.
When the first caller executes claimExpired() under the PRODUCTION registry state, the pool auto-resolves to SURVIVED. Once this outcome is set, any subsequent stakers calling claimExpired() will revert due to a check that only accepts UNRESOLVED or EXPIRED outcomes, forcing subsequent stakers to call claimSurvived() instead.
Likelihood:
A pool expires when the agreement is in the PRODUCTION state.
The first caller triggers mechanical resolution via claimExpired(), setting the outcome to SURVIVED.
Subsequent stakers or automated vaults attempt to claim using the claimExpired() entrypoint.
Impact:
Subsequent stakers' calls to claimExpired() revert.
Automated vaults or claiming scripts experience runtime transaction failures if they do not dynamically branch and call claimSurvived().
The test file LogicalFindingsValidation.t.sol contains the PoC.
The PoC sets up two stakers (alice and bob) and advances time to expiry with the registry in the PRODUCTION state. alice calls claimExpired() first, which auto-resolves the pool to SURVIVED. When bob then calls claimExpired(), the transaction reverts with InvalidOutcome because the outcome is now SURVIVED, not UNRESOLVED or EXPIRED. bob is forced to call claimSurvived() to retrieve their funds.
How to Run
Run the test from the workspace directory using the following Foundry command:
Output Result
Update claimExpired() to accept the SURVIVED outcome and route payouts to stakers accordingly, preventing post-resolution reverts.
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.