52186 sc low incorrect reward calculation for slashed validators due to single segment time handling
Submitted on Aug 8th 2025 at 15:20:58 UTC by @DSbeX for Attackathon | Plume Network
Report ID: #52186
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/lib/PlumeRewardLogic.sol
Impacts:
Theft of unclaimed yield
Description
Brief/Intro
The calculateRewardsWithCheckpoints function contains a vulnerability in its slashed validator reward calculation logic. By using a single time segment with a static reward rate between the last update and slash time, it ignores intermediate reward rate changes. This results in reward miscalculations that would cause financial losses to users (through underpayment) or protocol drains (through overpayment) if exploited in production.
Vulnerability Details
The vulnerability is in the slashed validator handling within calculateRewardsWithCheckpoints. When a validator is slashed, rewards should be calculated up to the slash timestamp, accounting for all reward rate changes during this period. However, the current implementation uses a single continuous segment with a static rate:
} else {
// Slashed validator case
uint256 currentCumulativeRewardPerToken = ...;
uint256 effectiveEndTime = validator.slashedAtTimestamp;
if (effectiveEndTime > validatorLastUpdateTime) {
uint256 timeSinceLastUpdate = effectiveEndTime - validatorLastUpdateTime;
uint256 effectiveRewardRate =
getEffectiveRewardRateAt($, token, validatorId, validatorLastUpdateTime).rate;
//Vulnerable single-segment calculation
uint256 rewardPerTokenIncrease = timeSinceLastUpdate * effectiveRewardRate;
currentCumulativeRewardPerToken += rewardPerTokenIncrease;
}
return _calculateRewardsCore(...);
}Uses one continuous time segment from
validatorLastUpdateTimetoeffectiveEndTimeStatic rate application: Applies the initial reward rate at
validatorLastUpdateTimefor the entire durationCheckpoint ignorance: Fails to account for intermediate reward rate changes captured in
validatorRewardRateCheckpoints
Impact Details
Reward-rate changes during unprocessed periods can cause large underpayments to users or overpayments by the protocol. Because slashed-validator calculations are final, those errors are permanent and compound as delayed slashes or repeated rate changes amplify the discrepancy. Miscalculated base rewards also corrupt validator commission accounting, creating a stealth drain that looks like minor rounding but adds up.
References
Proof of Concept
Incorrect reward distribution
User receives rewards for T0-T2 period calculated entirely at R1
Correct calculation should be:
T0-T1 segment: (T1 - T0) × R1
T1-T2 segment: (T2 - T1) × R2
Impact:
Protocol underpaying user by (T2-T1) × (R2 - R1) tokens
Validator commission also miscalculated based on wrong base rewards
Was this helpful?