Core Contracts

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

All treasury fees are lost

Summary

FeeCollector sends all treasury fees via a direct transfer instead of depositing them, making them unaccounted for and unable to be retrieved.

Details

Let's see how _processDistributions sends fees towards the treasury

if (shares[1] > 0) raacToken.burn(shares[1]);
if (shares[2] > 0) raacToken.safeTransfer(repairFund, shares[2]);
if (shares[3] > 0) raacToken.safeTransfer(treasury, shares[3]);

A direct transfer is incorrect here due to the Treasury.sol having dedicated deposit-withdraw methods which also perform internal accounting of all funds that enter.

function deposit(address token, uint256 amount) external override nonReentrant {
if (token == address(0)) revert InvalidAddress();
if (amount == 0) revert InvalidAmount();
IERC20(token).transferFrom(msg.sender, address(this), amount);
_balances[token] += amount; // @note all deposits are tracked via _balances
_totalValue += amount; // @note all deposits are tracked via totalValue
emit Deposited(token, amount);
}

Withdrawing the funds sent from FeeCollector towards the Treasury is impossible as they were never accounted for in _balances and _totalValue, leading to underflows when performing subtraction calculations in withdraw.

function withdraw(
address token,
uint256 amount,
address recipient
) external override nonReentrant onlyRole(MANAGER_ROLE) {
if (token == address(0)) revert InvalidAddress();
if (recipient == address(0)) revert InvalidRecipient();
if (_balances[token] < amount) revert InsufficientBalance();
_balances[token] -= amount; // @audit-issue since they were not properly deposited
_totalValue -= amount; // they also can't be withdrawn
IERC20(token).transfer(recipient, amount);
emit Withdrawn(token, amount, recipient);
}

Impact

Permanently stuck funds, loss for the protocol

Mitigation

Use the deposit method instead of direct transfer

Updates

Lead Judging Commences

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

FeeCollector::_processDistributions and emergencyWithdraw directly transfer funds to Treasury where they get permanently stuck

Support

FAQs

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

Give us feedback!