TempleGold

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

Precision loss in _rewardPerToken function.

Summary

_rewardPerToken() output value has been capped at uint256 which wrongfully converted into uin216 in updateReward modifier

Vulnerability Details

_rewardPerToken has a return value of data type uint256 as you can see here

function _rewardPerToken() internal view returns (uint256) {
if (totalSupply == 0) {
return rewardData.rewardPerTokenStored;
}
return
rewardData.rewardPerTokenStored +
(((_lastTimeRewardApplicable(rewardData.periodFinish) -
rewardData.lastUpdateTime) *
rewardData.rewardRate * 1e18)
/ totalSupply);
}

Issue arises when this function gets internally called whenever updateReward modifier is being used as in this modifier _rewardPerToken gets wrongfully casted into uint216.

modifier updateReward(address _account, uint256 _index) {
{
// stack too deep
rewardData.rewardPerTokenStored = uint216(_rewardPerToken()); // <------here
rewardData.lastUpdateTime = uint40(_lastTimeRewardApplicable(rewardData.periodFinish));
if (_account != address(0)) {
StakeInfo memory _stakeInfo = _stakeInfos[_account][_index];
uint256 vestingRate = _getVestingRate(_stakeInfo);
claimableRewards[_account][_index] = _earned(_stakeInfo, _account, _index);
userRewardPerTokenPaid[_account][_index] = vestingRate * uint256(rewardData.rewardPerTokenStored) / 1e18;
}
}
_;
}

Due to this precision loss happens leading to wrong rewardPerToken which leads to wrong balance updates.

Impact

Loss of precision in _rewardPerToken
This leads to wrong balance updates in the updateReward modifier.

Tools Used

Manual review

Recommendations

modifier updateReward(address _account, uint256 _index) {
{
// stack too deep
- rewardData.rewardPerTokenStored = uint216(_rewardPerToken());
+ rewardData.rewardPerTokenStored = uint256(_rewardPerToken());
rewardData.lastUpdateTime = uint40(_lastTimeRewardApplicable(rewardData.periodFinish));
if (_account != address(0)) {
StakeInfo memory _stakeInfo = _stakeInfos[_account][_index];
uint256 vestingRate = _getVestingRate(_stakeInfo);
claimableRewards[_account][_index] = _earned(_stakeInfo, _account, _index);
userRewardPerTokenPaid[_account][_index] = vestingRate * uint256(rewardData.rewardPerTokenStored) / 1e18;
}
}
_;
}
Updates

Lead Judging Commences

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

Appeal created

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