After a pool resolves as SURVIVED or EXPIRED, stakers are expected to claim their principal plus any k=2 time-weighted bonus through claimSurvived() or claimExpired().
The issue is that _bonusShare() computes the quadratic score using absolute Unix timestamps and multiplies T * T * stake before reaching Math.mulDiv. Since the contract does not enforce a maximum stake amount for allowlisted ERC20s, a sufficiently large valid stake can make the claim-time score overflow and revert with panic 0x11.
Likelihood:
This occurs when the factory allowlists a standard ERC20 whose base-unit supply and holder distribution can reach approximately type(uint256).max / (2 * block.timestamp * block.timestamp), around 1.89e58 base units at current timestamps.
This occurs after the risk window has started and the pool later resolves as SURVIVED or EXPIRED with a nonzero bonus, causing _bonusShare() to execute the overflowing k=2 path.
Impact:
Normal stakers cannot claim their principal or bonus because claimSurvived() and claimExpired() revert with arithmetic panic 0x11.
Once the registry has reached UNDER_ATTACK, withdrawals are disabled, so affected users have no alternate withdrawal path and their stake remains locked in the pool.
Run:
Both local and fork PoCs pass.
Compute the k=2 score using bounded time deltas relative to riskWindowStart, not absolute Unix timestamps.
Also add regression tests for large allowed stakes in both claimSurvived() and claimExpired().
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.