52422 sc low using the current time in geteffectiverewardrateat will result in incorrect reward calculation for an entire duration of a time segment
Description
Brief/Intro
Vulnerability Details
uint256 totalStaked = $.validatorTotalStaked[validatorId];
uint256 oldLastUpdateTime = $.validatorLastUpdateTimes[validatorId][token];
if (block.timestamp > oldLastUpdateTime) {
if (totalStaked > 0) {
uint256 timeDelta = block.timestamp - oldLastUpdateTime;
// Get the reward rate effective for the segment ending at block.timestamp
PlumeStakingStorage.RateCheckpoint memory effectiveRewardRateChk =
getEffectiveRewardRateAt($, token, validatorId, block.timestamp);
uint256 effectiveRewardRate = effectiveRewardRateChk.rate;
if (effectiveRewardRate > 0) {
uint256 rewardPerTokenIncrease = timeDelta * effectiveRewardRate;
$.validatorRewardPerTokenCumulative[validatorId][token] += rewardPerTokenIncrease;
// Accrue commission for the validator for this segment
// The commission rate should be the one effective at the START of this segment (oldLastUpdateTime)
uint256 commissionRateForSegment = getEffectiveCommissionRateAt($, validatorId, oldLastUpdateTime);
uint256 grossRewardForValidatorThisSegment =
(totalStaked * rewardPerTokenIncrease) / PlumeStakingStorage.REWARD_PRECISION;
// Use regular division (floor) for validator's accrued commission
uint256 commissionDeltaForValidator = (
grossRewardForValidatorThisSegment * commissionRateForSegment
) / PlumeStakingStorage.REWARD_PRECISION;
if (commissionDeltaForValidator > 0) {
$.validatorAccruedCommission[validatorId][token] += commissionDeltaForValidator;
}
}
}
}
// Update last global update time for this validator/token AFTER all calculations for the segment
$.validatorLastUpdateTimes[validatorId][token] = block.timestamp;Impact Details
References
Proof of Concept
Previous52690 sc medium dos of smart contracts on bridging functionsNext50924 sc high validators are not able to claim their accrued commission when the reward token is removed
Was this helpful?