Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Invalid

Incorrect Reward Calculation Due to Premature State Update in _updateReward

Summary

In the BaseGauge contract, _updateReward updates the global lastUpdateTime before calculating a user's earned rewards, leading to incorrect reward calculations because earned() uses the already updated `lastUpdateTime.

Vulnerability Details

In the _updateReward function:

function _updateReward(address account) internal {
rewardPerTokenStored = getRewardPerToken();
lastUpdateTime = lastTimeRewardApplicable(); // @audit Updates global state before earned calculation
if (account != address(0)) {
UserState storage state = userStates[account];
state.rewards = earned(account); // Uses updated lastUpdateTime
state.rewardPerTokenPaid = rewardPerTokenStored;
state.lastUpdateTime = block.timestamp;
emit RewardUpdated(account, state.rewards);
}
}

When calculating earned rewards:

function earned(address account) public view returns (uint256) {
return (getUserWeight(account) *
(getRewardPerToken() - userStates[account].rewardPerTokenPaid) / 1e18
) + userStates[account].rewards;
}
function getRewardPerToken() public view returns (uint256) {
if (totalSupply() == 0) {
return rewardPerTokenStored;
}
return rewardPerTokenStored + (
(lastTimeRewardApplicable() - lastUpdateTime) * rewardRate * 1e18 / totalSupply()
);
}

The issue is:

  1. lastUpdateTime is updated to current time

  2. Then earned() is called which uses getRewardPerToken()

  3. getRewardPerToken() calculates using (lastTimeRewardApplicable() - lastUpdateTime)

  4. This time difference will be 0 since lastUpdateTime was just updated
    Results in users losing rewards for the period between their last update and current update

Impact

Users lose rewards for the period between updates

Tools Used

Manual review

Recommendations

Calculate earned rewards before updating the global state.

Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

BaseGauge::_updateReward updates lastUpdateTime before calculating earned rewards, causing users to lose rewards for the period between their last update and current update

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

BaseGauge::_updateReward updates lastUpdateTime before calculating earned rewards, causing users to lose rewards for the period between their last update and current update

Support

FAQs

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