TempleGold

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

`TempleGoldStaking._rewardPerToken` implicitly assumes the decimals of staking token is 18

Summary

TempleGoldStaking._rewardPerToken implicitly assumes the decimals of staking token is 18

Vulnerability Details

The return value of _rewardPerToken must have the decimals of the reward token.

return
rewardData.rewardPerTokenStored +
(((_lastTimeRewardApplicable(rewardData.periodFinish) -
rewardData.lastUpdateTime) *
// @audit Assumes decimal 18
rewardData.rewardRate * 1e18)
/ totalSupply);

https://github.com/Cyfrin/2024-07-templegold/blob/6873abd52ddee3502fdefd95b83304687feb515b/protocol/contracts/templegold/TempleGoldStaking.sol#L507-L512

I will split the return value into two parts:

  1. rewardData.rewardPerTokenStored has the decimals of the reward token.

  2. The latter after + has the decimals of (rewardTokenDecimals) + 18 - stakingTokenDecimals.

According to _notifyReward, rewardData.rewardRate has the decimals of the reward token.

rewardData.rewardRate = uint216(amount / rewardDuration);

https://github.com/Cyfrin/2024-07-templegold/blob/6873abd52ddee3502fdefd95b83304687feb515b/protocol/contracts/templegold/TempleGoldStaking.sol#L517
Therefore, the return value has decimals 18 if and only if stakingTokenDecimals is 18.

Impact

If the decimals of a reward token is not 18, the reward per token will be calculated incorrectly.

Tools Used

Manual review

Recommendations

Use tokens that support IERC20Metadata to get the decimals of the staking token and the reward token, and fix as below.

- rewardData.rewardRate * 1e18)
+ rewardData.rewardRate * 10 ** IERC20Metadata(rewardToken).decimals())
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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