TempleGold

TempleDAO
Foundry
25,000 USDC
View results
Submission Details
Severity: medium
Invalid

`setRewardDistributionCoolDown()` doesn't distribute reward before setting rewardDistributionCoolDown

Summary

rewardDistributionCoolDown represents the cooldown time before the next distribution of rewards. There should be at least a rewardDistributionCoolDown time difference between two successive distributeRewards() calls. The admin can change rewardDistributionCoolDown but doesn't call distributeRewards() before changing it, which can lead to unintended waiting for the next distribution of rewards to stakers.

Vulnerability Details

function distributeRewards() updateReward(address(0), 0) external {
if (distributionStarter != address(0) && msg.sender != distributionStarter)
{ revert CommonEventsAndErrors.InvalidAccess(); }
if (totalSupply == 0) { revert NoStaker(); }
// Mint and distribute TGLD if no cooldown set
if (lastRewardNotificationTimestamp + rewardDistributionCoolDown > block.timestamp)
{ revert CannotDistribute(); }
_distributeGold();
uint256 rewardAmount = nextRewardAmount;
// revert if next reward is 0 or less than reward duration (final dust amounts)
if (rewardAmount < rewardDuration ) { revert CommonEventsAndErrors.ExpectedNonZero(); }
nextRewardAmount = 0;
_notifyReward(rewardAmount);
lastRewardNotificationTimestamp = uint32(block.timestamp);
}

distribution can only be completed if lastRewardNotificationTimestamp + rewardDistributionCoolDown <= block.timestamp

Assume the admin decides to update rewardDistributionCoolDown to a value greater than the existing rewardDistributionCoolDown.

function setRewardDistributionCoolDown(uint160 _cooldown) external override onlyElevatedAccess {
/// @dev zero cooldown is allowed
rewardDistributionCoolDown
rewardDistributionCoolDown = _cooldown;
emit RewardDistributionCoolDownSet(_cooldown);
}

The admin will call setRewardDistributionCoolDown() to update the cooldown time period.

If _cooldown > existing cooldown, distribution can be revert, and stakers will lose exposure to the reward tokens for _cooldown - rewardDistributionCoolDown time period.

Impact

Stakers will lose exposure to reward tokens during the newCooldown - oldCooldown period.

Tools Used

Manual

Recommendations

distributeRewards() should be called before updating rewardDistributionCoolDown if new coolDown > rewardDistributionCoolDown

An eg implementation

function setRewardDistributionCoolDown(
uint160 _cooldown
) external override onlyElevatedAccess {
/// @dev zero cooldown is allowed
if (
(totalSupply != 0) &&
(_cooldown > rewardDistributionCoolDown) &&
(lastRewardNotificationTimestamp + rewardDistributionCoolDown <=
block.timestamp)
) {
_distributeGold();
uint256 rewardAmount = nextRewardAmount;
if (rewardAmount >= rewardDuration) {
nextRewardAmount = 0;
_notifyReward(rewardAmount);
lastRewardNotificationTimestamp = uint32(block.timestamp);
}
}
rewardDistributionCoolDown = _cooldown;
emit RewardDistributionCoolDownSet(_cooldown);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.