Summary
The updateReward
modifier is designed to update the reward information for a given account before executing the function it modifies. It ensures that the latest reward data is stored and applicable rewards are calculated accurately.
Vulnerability Details
The implementation lacks an event emission, which is crucial for tracking and auditing changes in reward calculations.
Impact
Without event logs, tracking changes to reward data becomes difficult for users and developers.
The absence of event hinders external auditors' ability to verify reward calculations and updates effectively.
Code Snippet
https://github.com/Cyfrin/2024-07-templegold/blob/57a3e597e9199f9e9e0c26aab2123332eb19cc28/protocol/contracts/templegold/TempleGoldStaking.sol#L589-L602
modifier updateReward(address _account, uint256 _index) {
{
rewardData.rewardPerTokenStored = uint216(_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;
}
}
_;
}
Tools Used
Manaual Review , Foundry
Recommendations
To address this vulnerability, the updateReward
modifier should include event emission.
modifier updateReward(address _account, uint256 _index) {
{
rewardData.rewardPerTokenStored = uint216(_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;
++ emit RewardUpdated(
++ rewardData.rewardPerTokenStored,
++ rewardData.lastUpdateTime,
++ vestingRate,
++ claimableRewards[_account][_index],
++ userRewardPerTokenPaid[_account][_index]
++ );
}
}
_;
}
++ event RewardUpdated(
uint256 rewardPerTokenStored,
uint40 lastUpdateTime,
uint256 vestingRate,
uint256 claimableRewards,
uint256 userRewardPerTokenPaid
);