52996 sc high users can claim rewards for newly added reward tokens even when the validator they staked for was inactive during some time interval
Submitted on Aug 14th 2025 at 15:41:04 UTC by @swarun for Attackathon | Plume Network
Report ID: #52996
Report Type: Smart Contract
Report severity: High
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/ValidatorFacet.sol
Impacts: Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief / Intro
Suppose a validator was inactive for some time interval and during that time interval a new token got added. Users shouldn't receive rewards when the validator is inactive, but they will receive rewards when a new reward token was added during the inactive interval. This causes users to receive rewards for time intervals where there was no accumulation of rewards, which should not happen.
Vulnerability Details
When a new reward token is added while a validator is inactive, the logic creates reward checkpoints for all validators (including the inactive one) at the addition time. Later, when the validator is reactivated, a new checkpoint is created again at the activation time. Because the reward calculation logic splits time into segments based on checkpoints, this can result in a segment that covers the inactive interval with a non-zero effective reward rate (from the token addition checkpoint), producing rewards to stakers even though the validator was inactive during that time.
Impact Details
Users receive more rewards than they are eligible for.
References
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/plume/src/facets/ValidatorFacet.sol#L252
Proof of Concept
Validator reactivated and another checkpoint created
At t = 2 days the admin reactivates the validator. The active transition creates another checkpoint for all reward tokens at t = 2 days and resets timestamp caps:
Now the newly added token has two checkpoints for this validator: one at t = 1 day (added) and one at t = 2 days (reactivation).
Reward accumulation logic and how it miscomputes for the inactive interval
Important notes:
While the validator was inactive, the system prevents updating $.validatorRewardPerTokenCumulative[validatorId][token] due to timestamp caps (no reward accumulation while inactive).
Later, after reactivation and time passing, the cumulative RPT is updated, and a user triggers a claim.
Claim flow (relevant parts):
Main reward processing:
updateRewardsForValidatorAndToken ultimately calls core calculation logic which splits the period since the user's last update into segments based on distinct checkpoint timestamps (rate or commission changes).
How the segments cause incorrect rewards
The core loop computing rewards iterates segments between distinct timestamps (checkpoints). Simplified snippet:
In the scenario: distinctTimestamps includes t = 1 day (token addition) and t = 2 days (validator reactivated).
For the segment [1 day, 2 day], getEffectiveRewardRateAt at segmentStartTime (1 day) returns a non-zero rate (token was added).
segmentDuration = 1 day, userStakedAmount > 0, so gross reward is calculated and added to the user's rewards even though the validator was inactive during that segment.
This yields extraneous rewards for the inactive interval.
Was this helpful?