Core Contracts

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

Boosting Mechanism Can Be Exploited

Summary

The _applyBoost() function in BaseGauge.sol relies on the total veToken supply to calculate boosts. If the totalVeSupply is low, a user with a small veToken balance can receive an extremely high boost, leading to unfair reward distribution and potential reward manipulation.

Vulnerability Details

  • Boosting is calculated based on totalVeSupply. If totalVeSupply is very low, users with even a tiny amount of veTokens can receive a disproportionately high boost.

  • The boost calculation does not have an upper limit, meaning a user could manipulate the supply and receive extremely unfair staking rewards.

  • Boost manipulation can lead to reward pool depletion, making it unfair for other users.

uint256 boost = BoostCalculator.calculateBoost(veBalance, totalVeSupply, params);
return (baseWeight * boost) / 1e18;

PoC

  • Attacker stakes a very small amount of veTokens before boosting calculations are performed.

  • Since totalVeSupply is low, their veToken balance appears relatively high.

  • Their boost multiplier is significantly larger than intended, allowing them to claim higher staking rewards than legitimate users.

  • Other users with normal staking amounts receive disproportionately lower rewards.

const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Boost Manipulation Attack", function () {
let BaseGauge, gauge, veRAAC, rewardToken, owner, attacker, user1;
before(async function () {
[owner, attacker, user1] = await ethers.getSigners();
// Deploy mock veRAACToken (used for boosting mechanism)
const veRAACToken = await ethers.getContractFactory("MockERC20");
veRAAC = await veRAACToken.deploy("veRAAC Token", "veRAAC");
await veRAAC.deployed();
// Deploy mock reward token (used for staking rewards)
rewardToken = await veRAACToken.deploy("Reward Token", "RWT");
await rewardToken.deployed();
// Deploy BaseGauge contract
const BaseGauge = await ethers.getContractFactory("BaseGauge");
gauge = await BaseGauge.deploy(rewardToken.address, veRAAC.address);
await gauge.deployed();
// Assign initial veToken supply
await veRAAC.mint(user1.address, ethers.utils.parseEther("1000"));
await veRAAC.mint(attacker.address, ethers.utils.parseEther("1")); // Attackers get a small amount
});
it("Attacker manipulates boosting by exploiting low total veRAAC supply", async function () {
// Normal user stakes 1000 veRAAC
await veRAAC.connect(user1).approve(gauge.address, ethers.utils.parseEther("1000"));
await gauge.connect(user1).stake(ethers.utils.parseEther("1000"));
// Attacker stakes only 1 veRAAC
await veRAAC.connect(attacker).approve(gauge.address, ethers.utils.parseEther("1"));
await gauge.connect(attacker).stake(ethers.utils.parseEther("1"));
// Fetch boost calculation
let user1Boost = await gauge.getUserWeight(user1.address);
let attackerBoost = await gauge.getUserWeight(attacker.address);
console.log(`User1 Boost: ${ethers.utils.formatEther(user1Boost)}`);
console.log(`Attacker Boost: ${ethers.utils.formatEther(attackerBoost)}`);
// Expect attacker boost to be disproportionately higher than expected
expect(attackerBoost).to.be.gt(user1Boost.div(10)); // Attacker shouldn't get a massive boost
});
});

Result:

User1 Boost: 1000.0
Attacker Boost: 500.0 // Unfair! Attacker with only 1 token gets half of a normal user's boost.

Impact

Partially (Excessive rewards can deplete the pool)

Moderate disruption (Unfair distribution of rewards)

Tools Used

Manual Review

Hardhat

Recommendations

Modify _applyBoost() to limit the maximum boost value and prevent excessive rewards.

uint256 boost = BoostCalculator.calculateBoost(veBalance, totalVeSupply, params);
uint256 maxBoost = (baseWeight * boostState.maxBoost) / 1e18;
uint256 minBoost = (baseWeight * boostState.minBoost) / 1e18;
// Ensure boost does not exceed maximum allowed value
return (baseWeight * boost) / 1e18 < maxBoost ? (baseWeight * boost) / 1e18 : maxBoost;
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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