Core Contracts

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

In `FeeCollector::emergencyWithdraw` funds can be drained from undistributed period

Summary

FeeCollector::emergencyWithdraw allows draining of collected-but-undistributed fees, violating protocol fee distribution rules. When emergencyWithdrraw is called all raac tokens are transferred, including those that are collected but not yet distributed. If this happens before distribution, the collected fees would be sent to the treasury, and all fees including the veRAAC holders fees will be lost.

Vulnerability Details

during emergencies, there is No separation between collected fees and other balances. In case the fees hasnt been distributed to that period, veRAAC holder wont be able to claim fees. emergencyWithdraw sends entire RAAC balance without accounting for distribute

Affected Code:

function emergencyWithdraw(address token) external {
uint256 balance = raacToken.balanceOf(address(this)); // < === all balance sent without seperation
raacToken.safeTransfer(treasury, balance);
}

Poc

function testEmergencyWithdrawStealsFees() public {
// uint256 feeAmount = 3e18;
deal(kal, 500e18);
raacToken.mintTo(kal, 500e18);
console.log(raacToken.balanceOf(kal));
vm.startPrank(kal);
raacToken.approve(address(feeCollector), 500e18);
// Collect fees
feeCollector.collectFee(500e18, 0);
assertEq(raacToken.balanceOf(address(feeCollector)), 500e18);
vm.stopPrank();
// Emergency withdraw before distribution
vm.startPrank(admin);
feeCollector.pause(); // heyy i can see you
feeCollector.emergencyWithdraw(address(raacToken));
console.log("balance", raacToken.balanceOf(address(treasury)));
console.log("feeCollecter", raacToken.balanceOf(address(feeCollector)));
// Treasury gets the fees instead of stakeholders
assertEq(raacToken.balanceOf(address(treasury)), 500e18);
assertEq(raacToken.balanceOf(address(feeCollector)), 0);
// Distribution attempts to send 0 tokens
feeCollector.unpause();
feeCollector.distributeCollectedFees(); // Would fail
}

Impact

Protocol can lose all collected but undistributed fee.

veRAAC holders lose entitled rewards for that period

Tools Used

foundry, manual review

Recommendations

  • Track all funds sent to treasuary seperatly

  • call the distrubte function during emergencies

Updates

Lead Judging Commences

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

FeeCollector::emergencyWithdraw sends all tokens to treasury without resetting collectedFees, breaking rewards and future distributions

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

FeeCollector::emergencyWithdraw sends all tokens to treasury without resetting collectedFees, breaking rewards and future distributions

Support

FAQs

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

Give us feedback!