In the function TempleGoldStaking::_notifyReward(), which is called every time the contract is distributing rewards to users, the state variable rewardData.periodFinish is updated further in the future, leading to wrong reward calculation overall, and allowing for malicious users to gain more TempleGold than the TempleDAO team intends.
Every time the _notifyReward function is executed, the rewardData.periodFinish is updated.
rewardData.periodFinish = uint40(block.timestamp + rewardDuration)
This leads to the end of the reward epoch being moved forward in the future with every call of distributeRewards()
. In this function, the values for therewardData.rewardRate
and nextRewardAmount
are set. As the periodFinish
will be larger than is intended, so will rewardRate
and nextRewardAmount
, leading to higher rewards being paid out to users than intended.
modifier updateReward
is called where we adjust the user's claimableRewards
by calling _earned()
. However, earned()
calls _rewardPerToken()
which takes the period finish into account, so the calculation of user rewards will be wrong.
The distribution of TempleGold rewards will not be as intended or documented. Users who know about this weakness can exploit it to receive more rewards than they have earned.
Manual review, Foundry
To ensure appropriate rewards calculation and distribution, periodFinish should stay constant for the duration of the rewards epoch. The line in question should be inside the if (block.timestamp >= rewardData.periodFinish)
block. Change the _notifyReward function as follows:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.