Core Contracts

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

Users will not be able to delegate their boost to more than one address as a result of an invalid check

Details

Protocol allow for users to be able to delegate a portion of their veToken balance. However, in a situation where users attemts to delegate any of the remaining portion of their veToken balance to another user, the below checks in BoostController::delegateBoost makes it impossible for that action to be taken.

if (delegation.amount > 0) revert BoostAlreadyDelegated();

POC

contract POC is Test {
RAACGauge raacGauge;
MockToken rewardToken;
MockToken stakingToken;
BoostController boostController;
RAACToken raacToken;
veRAACToken veRAAC;
address owner = makeAddr("owner");
address user = makeAddr("user");
address user2 = makeAddr("user2");
address pool = makeAddr("pool");
function setUp() public {
vm.startPrank(owner);
raacToken = new RAACToken( owner, 0, 0);
veRAAC = new veRAACToken(address(raacToken));
stakingToken = new MockToken("STAKING TOKEN","STT", 18);
rewardToken = new MockToken("REWARD TOKEN","RWD", 18);
boostController = new BoostController((address(veRAAC)));
raacGauge = new RAACGauge( address(rewardToken), address(stakingToken), address(boostController));
raacToken.setMinter(owner);
boostController.modifySupportedPool(pool, true);
raacToken.mint(user, 10 ether);
stakingToken.mint(user, 10 ether);
raacToken.mint(user2, 10 ether);
stakingToken.mint(user2, 10 ether);
vm.stopPrank();
}
function test_POC() public {
vm.startPrank(user);
raacToken.approve(address(veRAAC), 2 ether);
veRAAC.lock(2 ether, 366 days);
vm.stopPrank();
vm.startPrank(user2);
raacToken.approve(address(veRAAC), 2 ether);
veRAAC.lock(2 ether, 366 days);
vm.stopPrank();
vm.warp(2 weeks);
vm.startPrank(user);
uint256 remainder = veRAAC.balanceOf(user) - 0.1 ether;
boostController.delegateBoost(owner, 0.1 ether, 8 days);
vm.expectRevert();
boostController.delegateBoost(owner, remainder, 8 days);
vm.stopPrank();
}
}

Recommendation

Since partial delegation is allowed, there should be a variable that tracks the total tokens delegated by a user, and that the total amount delegated at anytime should be less than the user balance
Example:

+ mapping(address => uint256) public totalDelegatedByUser;
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();
if (totalDelegatedByUser[msg.sender] + amount > userBalance) revert BoostAlreadyDelegated();
delegation.amount = amount;
delegation.expiry = block.timestamp + duration;
delegation.delegatedTo = to;
delegation.lastUpdateTime = block.timestamp;
+ totalDelegatedByUser[msg.sender] += amount;
emit BoostDelegated(msg.sender, to, amount, duration);
}
Updates

Lead Judging Commences

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

BoostController::delegateBoost prevents multiple delegations to the same address due to absolute delegation check, restricting users from efficiently managing partial delegations over time

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

BoostController::delegateBoost prevents multiple delegations to the same address due to absolute delegation check, restricting users from efficiently managing partial delegations over time

Support

FAQs

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

Give us feedback!