Core Contracts

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

Inaccurate reward calculations with `earned()` due to hardcoded address variable.

Summary

The earned amount returns the earmed value for address(this) regardless of who calls it because of the hardcoded address (address(this)).

Vulnerability Details

The BaseGauge contract is designed to manage reward distribution and boost calculations for users staking tokens. It utilizes functions such as _getBaseWeight() and getUserWeight() to determine the weight of a user's stake, which directly impacts the rewards they earn through the earned() function. However, both _getBaseWeight() and getUserWeight() are hardcoded to use address(this) instead of the actual user's address, leading to inaccurate reward calculations.

The root of the issue lies in the implementation of the _getBaseWeight() function, which retrieves the gauge weight using the controller's getGaugeWeight(address(this)). This means that the weight is always calculated based on the contract's address rather than the individual user's address. Consequently, when the earned() function calculates the rewards, it does so using an incorrect base weight, resulting in potentially inflated or deflated rewards for users.

The highest impact scenario occurs when multiple users stake tokens, but due to the hardcoded address, they all receive the same reward amount, regardless of their actual stake. This can lead to significant discrepancies in reward distribution, undermining the fairness and integrity of the staking mechanism. Users who expect to earn rewards proportional to their contributions may find themselves receiving incorrect amounts, leading to dissatisfaction and loss of trust in the system.

Impact

Proof of Concept

  1. User A calls stake(100e18) and their balance is updated correctly.

  2. User B calls stake(200e18) and their balance is also updated correctly.

  3. When rewards are calculated, both users call earned(User A's address) and earned(User B's address).

  4. Both _getBaseWeight() calls return the same weight because they use address(this), leading to the same reward calculation for both users.

  5. User A and User B receive the same reward amount, despite their different stakes.

Tools Used

Manual Review

Recommendations

To resolve this issue, the getBaseWeight() function should be modified to accept the user's address as a parameter, ensuring that the weight is calculated based on the actual user's stake. The following code change is recommended:

function _getBaseWeight(address account) internal view virtual returns (uint256) {
return IGaugeController(controller).getGaugeWeight(account);
}

This change will ensure that the weight is calculated correctly for each user, leading to accurate reward distributions based on their respective stakes.

Updates

Lead Judging Commences

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

BaseGauge._getBaseWeight ignores account parameter and returns gauge's total weight, allowing users to claim rewards from gauges they never voted for or staked in

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

BaseGauge._getBaseWeight ignores account parameter and returns gauge's total weight, allowing users to claim rewards from gauges they never voted for or staked in

Support

FAQs

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

Give us feedback!