Core Contracts

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

Reward Calculation Flaw in `BaseGauge::earned()` Incentivizes Users To Unstake Tokens

Summary

The reward calculation in the BaseGauge is based on the total supply of the gauge and user weight, but not on the staked token amount. This design incentivizes users to unstake tokens, reducing the totalSupply() and thus increasing the reward yield rate (getRewardPerToken()), enabling them to maximize rewards without staking tokens.

Vulnerability Details

In BaseGauge::earned(), the formula for calculating rewards uses getRewardPerToken(), which depends on the total supply of the gauge. A smaller totalSupply() results in a higher getRewardPerToken(), increasing the reward yield. This creates an incentive for users to unstake their tokens, thereby reducing the total supply and benefiting from a higher yield without having to stake tokens.

File: d:\workspace\sol\2025-02-raac\contracts\core\governance\gauges\BaseGauge.sol
568: function getRewardPerToken() public view returns (uint256) {
569: if (totalSupply() == 0) {
570: return rewardPerTokenStored;
571: }
572:
573: return rewardPerTokenStored + (
574:> (lastTimeRewardApplicable() - lastUpdateTime) * rewardRate * 1e18 / totalSupply()
575: );
576: }
577:
578: /**
579: * @notice Calculates earned rewards for account
580: * @param account Address to calculate earnings for
581: * @return Amount of rewards earned
582: */
583: function earned(address account) public view returns (uint256) {
584: return (getUserWeight(account) *
585: > (getRewardPerToken() - userStates[account].rewardPerTokenPaid) / 1e18
586: ) + userStates[account].rewards;
587: }

Impact

This vulnerability allows users to manipulate the system by unstaking tokens to maximize their reward yield.

Tools Used

vscode

Recommendations

The user’s staked token amount should be included in the reward calculation. This would prevent users from manipulating the total supply by simply unstaking their tokens.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BaseGauge::earned calculates rewards using getUserWeight instead of staked balances, potentially allowing users to claim rewards by gaining weight without proper reward checkpoint updates

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BaseGauge::earned calculates rewards using getUserWeight instead of staked balances, potentially allowing users to claim rewards by gaining weight without proper reward checkpoint updates

Support

FAQs

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

Give us feedback!