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 10 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!