52588 sc high retroactive reward accrual for newly added tokens when validator was inactive
Previous52890 sc low no recipient yield distribution locks yield tokens on arctoken efftotal 0 Next52988 sc medium deposit function dos
Was this helpful?
Was this helpful?
function addRewardToken(
address token,
uint256 initialRate,
uint256 maxRate
) external onlyRole(PlumeRoles.REWARD_MANAGER_ROLE) {
PlumeStakingStorage.Layout storage $ = PlumeStakingStorage.layout();
if (token == address(0)) {
revert ZeroAddress("token");
}
if ($.isRewardToken[token]) {
revert TokenAlreadyExists();
}
if (initialRate > maxRate) {
revert RewardRateExceedsMax();
}
// Prevent re-adding a token in the same block it was removed to avoid checkpoint overwrites.
if ($.tokenRemovalTimestamps[token] == block.timestamp) {
revert CannotReAddTokenInSameBlock(token);
}
// Add to historical record if it's the first time seeing this token.
if (!$.isHistoricalRewardToken[token]) {
$.isHistoricalRewardToken[token] = true;
$.historicalRewardTokens.push(token);
}
uint256 additionTimestamp = block.timestamp;
// Clear any previous removal timestamp to allow re-adding
$.tokenRemovalTimestamps[token] = 0;
$.rewardTokens.push(token);
$.isRewardToken[token] = true;
$.maxRewardRates[token] = maxRate;
$.rewardRates[token] = initialRate; // Set initial global rate
$.tokenAdditionTimestamps[token] = additionTimestamp;
// Create a historical record that the rate starts at initialRate for all validators
uint16[] memory validatorIds = $.validatorIds;
@> for (uint256 i = 0; i < validatorIds.length; i++) {
@> uint16 validatorId = validatorIds[i];
@> PlumeRewardLogic.createRewardRateCheckpoint(
@> $,
@> token,
@> validatorId,
@> initialRate
@> );
@> }
emit RewardTokenAdded(token);
if (maxRate > 0) {
emit MaxRewardRateUpdated(token, maxRate);
}
}