When claimExpired() auto-resolves the pool to SURVIVED (because registry is PRODUCTION at expiry), the first caller claims normally. But every subsequent staker who calls claimExpired() gets InvalidOutcome and has to figure out they need claimSurvived() instead. This doesn't happen with the EXPIRED path — that one works for everyone.
Line 514 of ConfidencePool.sol:
After the first caller auto-resolves the pool and sets outcome = SURVIVED, this gate blocks all further claimExpired() calls because SURVIVED is not in the allowed set. There is no event, getter, or error message telling subsequent stakers which function to use instead. Compare with auto-EXPIRED where outcome = EXPIRED passes the gate, so everyone can keep calling claimExpired().
Likelihood: High — this happens every time a pool auto-resolves to SURVIVED via claimExpired and has more than one staker.
Impact: Low — no loss of funds. Stakers can always claim via claimSurvived(). The impact is UX confusion from an opaque revert.
Add SURVIVED to the allowed outcomes in claimExpired:
Or use a more descriptive custom error like UseClaimSurvived() when outcome == SURVIVED.
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.