Normal behavior: userSumStakeTime[u]/userSumStakeTimeSq[u] are meant to represent a staker's time-weighted contribution, floored at riskWindowStart once the risk window opens, this floor is what the k=2 bonus formula relies on to pay correctly.
The issue: the floor is only applied lazily, via _clampUserSums(u), which runs solely as a side effect of that specific user's own next stake/withdraw/claim call. Because both mappings are public, Solidity auto-generates external view getters for them, and those getters return the unclamped, stale, pre-window value for any staker who hasn't personally transacted since the window opened, even though their eventual payout (once they do claim) will correctly use the clamped value.
Likelihood:
This is the default state for any staker who deposited before the risk window opened and simply holds their position, the majority-case behavior for a staking pool, not a rare occurrence.
No action by any party is required to trigger the staleness, it exists automatically the moment riskWindowStart seals via anyone's unrelated transaction.
Impact:
Any off-chain system that reads these getters directly, a front-end estimating a user's expected bonus share, a subgraph, an integrating contract, computes an incorrect (understated, pre-clamp) figure for as long as the user remains inactive, with no on-chain signal that the value is stale.
Add this test to test/unit/ConfidencePool.k2Bonus.t.sol
Run forge test --mt testPublicGetterStaysStaleAfterWindowOpens
Either expose a view function that returns the clamped, current-truth value without requiring a state changing call, or clearly document that these mappings' raw getters are last interaction-relative and not live truth:
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.