ConfidencePool accepts stake amounts that can make the expanded k=2 accounting overflow at claim time. One oversized stake can permanently block all SURVIVED and EXPIRED claims for the pool because every claimant uses the same overflowing global denominator.
The bonus formula is mathematically based on amount * (T - entry)^2, but _bonusShare() evaluates the expanded form over absolute Unix timestamps:
stake() only proves that each accepted deposit's stored amount * entry * entry contribution fits. It does not prove that a later T * T * stake + entry * entry * stake addition will fit. For entries close to T, both individual terms can fit while their sum overflows.
This is reachable with a standard ERC20 that has a large unit supply. It does not require a malicious token callback or non-standard transfer behavior.
A staker with a sufficiently large balance of an allowlisted token can grief the pool by making successful-outcome claims revert for every participant. Honest stakers cannot recover principal or bonus through claimSurvived() or claimExpired() because the global score calculation includes the oversized stake and is executed for every claimant.
Place this file at test/unit/ConfidencePoolOversizedStakePoC.t.sol and run:
Both claims revert on the vulnerable implementation. Alice's normal-sized claim fails because _bonusShare() computes the global denominator from snapshotTotalStaked and snapshotSumStakeTimeSq, which include Bob's oversized stake.
Avoid expanding the score over absolute Unix timestamps. Store and compute the k=2 sums using bounded deltas from riskWindowStart, so intermediate values scale with the pool's risk-window duration rather than with block.timestamp.
Alternatively, enforce a maximum per-stake or total-eligible-stake bound that proves every _bonusShare() intermediate fits for the largest possible T.
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.