Core Contracts

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

GetBoostMultiplier always returns 25000 , missleading users that use this function.

Summary

BoostController.sol has a getter function for the user boost in the contract, but this function will always return 25000, i.e. 2.5x boost, missleading users and their decisions.

Vulnerability Details

In BoostController.sol:

function getBoostMultiplier(
address user,
address pool
) external view override returns (uint256) {
if (!supportedPools[pool]) revert PoolNotSupported();
UserBoost storage userBoost = userBoosts[user][pool];
if (userBoost.amount == 0) return MIN_BOOST;
uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;
return userBoost.amount * 10000 / baseAmount;
// This is (userBoost.amount * 10000) / (userboost.amount * 10000) / MAX_BOOST = MAX_BOOST
}

This can be checked via test:

it("getBoostMultiplier returns always 25000", async () => {
const amount = ethers.parseEther("100");
// Initial boost setup
await boostController.connect(user1).updateUserBoost(user1.address, mockPool.getAddress());
// Get boost
const initialBoost = await boostController.getWorkingBalance( // userBoost.amount
user1.address,
mockPool.getAddress()
);
// Here we simulate what 'getBoostMultipler' does
const baseAmount = initialBoost * BigInt(10000) / BigInt(25000); // MAXBOOST
const returnedBoost = initialBoost * BigInt(10000) / baseAmount;
console.log("----- Base %d , returned %d ----",baseAmount,returnedBoost);
// Increase veToken balance
await veToken.mint(user1.address, ethers.parseEther("1000"));
// Update boost
const tx = await boostController.connect(user1).updateUserBoost(user1.address, mockPool.getAddress());
// Get Boost
const postBoost = await boostController.getWorkingBalance(
user1.address,
mockPool.getAddress()
);
// boost Multiplier should have been updated
const post = postBoost * BigInt(10000) / BigInt(25000); // MAXBOOST
const postReturned = postBoost * BigInt(10000) / post;
console.log("----- Base %d , returned %d ----",post,postReturned);
expect(returnedBoost).to.be.closeTo(postReturned,2);
});
});

Impact

IMPACT: -> Low, its not a returned value that is used directly in the protocol calculations. But it may affect user decisions on how to interact with it, as it may make them think they have an amount of boost they dont actually have

LIKELIHOOD: -> High, users may always want to know their boost before doing any kind of operation in the protocol as boost is a core functionality in governance

Tools Used

Manual

Recommendations

Updates

Lead Judging Commences

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

BoostController::getBoostMultiplier always returns MAX_BOOST for any non-zero boost due to mathematical calculation error, defeating the incentive mechanism

Support

FAQs

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