TempleGold

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

DOS of TempleGoldStaking functions

Summary

Anyone can call TempleGoldStaking.distributeRewards() if the distributionStarteris address(0). This is by design. In order for an account with elevated access(TRUESTED) to callTempleGoldStaking.setVestingPeriod() or TempleGoldStaking.setRewardDuration(), the reward epoch needs to have ended, otherwise, those txs revert.

Vulnerability Details

Scenario:

0) distributionStarter is address(0)

1) A trusted user with elevated access sends a tx to the mempool. It calls setVestingPeriodor setRewardDuration

2) An attacker monitors the mempool and frontruns those txs by calling distributeRewards(), which calls _notifyRewards() internally. rewardData.periodFinish is updated to be into the future

function _notifyReward(uint256 amount) private {
// skipped code block
rewardData.lastUpdateTime = uint40(block.timestamp);
@> rewardData.periodFinish = uint40(block.timestamp + rewardDuration); //@audit try to DOS setRewardDuration() by calling _notifyReward
}

3) The trusted user tx gets executed, and reverts because periodFinish is in the future. This could happen on every attempt to call those 2 functions(mentioned in 1 point).

function setVestingPeriod(uint32 _period) external override onlyElevatedAccess {
if (_period < WEEK_LENGTH) { revert CommonEventsAndErrors.InvalidParam(); }
// only change after reward epoch ends
@> if (rewardData.periodFinish >= block.timestamp) { revert InvalidOperation(); }//@audit-issue an attacker can dos by calling notifyReward()
vestingPeriod = _period;
emit VestingPeriodSet(_period);
}
function setRewardDuration(uint256 _duration) external override onlyElevatedAccess {
// minimum reward duration
if (_duration < WEEK_LENGTH) { revert CommonEventsAndErrors.InvalidParam(); }
// only change after reward epoch ends
@> if (rewardData.periodFinish >= block.timestamp) { revert InvalidOperation(); }//@audit-issue an attacker can dos by calling notifyReward()
rewardDuration = _duration;
emit RewardDurationSet(_duration);
}

4) setVestingPeriod() and setRewardDuration() can never be executed under those conditions

Code snippets:

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L95-L100

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L107-L114

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L527-L528

Impact

DOS of setVestingPeriod() and setRewardDuration()

Tools Used

Manual review

Recommendations

Maybe consider only trusted accounts to trigger: TempleGoldStaking.distributeRewards()

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year 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.