Core Contracts

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

FeeCollector's emergencyWithdraw() disrupts fee distribution by draining tokens without resetting accounting

Relevant GitHub Links

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/collectors/FeeCollector.sol#L269-L280

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/collectors/FeeCollector.sol#L180-L191

Summary

The emergencyWithdraw() function in FeeCollector withdraws all tokens to treasury without resetting collectedFees state. This causes fee distribution to revert after emergency withdrawal since there are no tokens to distribute despite non-zero accounting.

Vulnerability Details

The emergencyWithdraw() function transfers all tokens to treasury:

function emergencyWithdraw(address token) external override whenPaused {
if (!hasRole(EMERGENCY_ROLE, msg.sender)) revert UnauthorizedCaller();
if (token == address(0)) revert InvalidAddress();
uint256 balance;
if (token == address(raacToken)) {
balance = raacToken.balanceOf(address(this));
raacToken.safeTransfer(treasury, balance);
} else {
balance = IERC20(token).balanceOf(address(this));
SafeERC20.safeTransfer(IERC20(token), treasury, balance);
}
emit EmergencyWithdrawal(token, balance);
}

However, it doesn't reset collectedFees mapping. This means:

  1. Contract's token balance becomes 0

  2. collectedFees still shows non-zero amounts

  3. Next distributeCollectedFees() call will revert due to insufficient balance

Impact

Contract becomes unusable after emergency withdrawal since fee distribution will always revert. Requires redeployment or manual token return.

Tools Used

Manual Review

Recommendations

Track emergency withdrawn amounts in state variables to maintain accounting. This on-chain tracking ensures fee distribution can resume correctly after treasury returns the withdrawn tokens to the contract.

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!