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.
View preliminary resultsAppeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.