TempleGold

TempleDAO
Foundry
25,000 USDC
View results
Submission Details
Severity: low
Valid

Malicious user can prevent `rewardData.perodfinish` from ending by calling `TempleGoldStaking::distributeRewards()` before the end of the reward duration when no starter is set.

Summary

Calling TempleGoldStaking::distributeRewards() upadates the rewwardData.periodFinish paramater which specificies when reward distribution is supposed to stop however when a starter is not set, a malicious user can call this function towards the end of a reward duration which will renew the rewardData.periodFinish paramater making the reward period go beyond the intended time.

Vulnarebility Details

In the TempleGoldStaking contract it is possible for rewardDistribution to be started by anyone when a starter is not set.

* @dev If starter is address zero, anyone can call `distributeRewards` to apply and
* distribute rewards for next reward duration

A malitious user a can recall this function towards the end of a reward duration which will renew the rewwardData.periodFinish when TempleGoldStaking::_notifyReward is called.

function _notifyReward(uint256 amount) private {
if (block.timestamp >= rewardData.periodFinish) {
rewardData.rewardRate = uint216(amount / rewardDuration);
// collect dust
nextRewardAmount = amount - (rewardData.rewardRate * rewardDuration);
} else {
uint256 remaining = uint256(rewardData.periodFinish) - block.timestamp;
uint256 leftover = remaining * rewardData.rewardRate;
rewardData.rewardRate = uint216((amount + leftover) / rewardDuration);
// collect dust
nextRewardAmount =
(amount + leftover) -
(rewardData.rewardRate * rewardDuration);
}
rewardData.lastUpdateTime = uint40(block.timestamp);
@@>> rewardData.periodFinish = uint40(block.timestamp + rewardDuration);
}

The rewardData.periodFinish paramater is renewed when the above function is called making the reward period go beyond the intended time.

POC

  • We have user A and B
    User A is the reward distribution starter but has not been set in the contract.

  • User A starts the Reward Distribution for a duration that has been set.

  • Towards the end of this reward distribution duration, User B maliciously calls TempleGoldStaking::distributeRewards() just to prevent the reward distribution from stopping.

  • This would go against user A's intentions as he may have wanted to add a reward duration and vesting period to be added. Which is now impossible due to the renewed rewardData.periodfinish. Even more gold will be distributrd than intended for this specific reward duration.

Impact

This makes the reward distribution to go beyond the intended time and makes it impossible to set a new reward duration and vesting period.

##Tools
Manual Review

Recommendation

Make it impossible for anyone to start Rewards distribution by ensuring only a single starter is supposed to do so.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

setRewardDuration and setVestingPeriod can be griefed from anyone when distributionStarter is unset

Support

FAQs

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