Core Contracts

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

Missing Allocation Protection Allows Managers to Withdraw Already Allocated Funds

Summary

The Treasury's withdraw() function lacks protection for allocated funds, allowing managers to withdraw funds that are already allocated as guarantees to external addresses.

Vulnerability Details

The issue is that the withdraw() function only checks the total balance, not accounting for funds that have been allocated through allocateFunds(). This means:

  • When funds are allocated as guarantees, they remain withdrawable by managers

  • Allocated recipients could be left without their guaranteed funds

  • No protection for allocated funds against manager withdrawals

Example:

  1. Treasury has 1000 tokens

  2. 800 tokens are allocated as guarantees to recipient X

  3. Manager can still withdraw all 1000 tokens, breaking allocation guarantees

Impact

There is no guarantee that allocated funds will be available in the future for recipients as they are not accounted for in withdraw(). Some recipients can be left out with no funds to withdraw after working freelance for the protocol.

Tools Used

Manual

Recommendations

Add a global counter of total allocated funds that is checked in withdraw()

uint256 totalAllocated;
function allocateFunds(
address recipient,
uint256 amount
) external override onlyRole(ALLOCATOR_ROLE) {
if (recipient == address(0)) revert InvalidRecipient();
if (amount == 0) revert InvalidAmount();
_allocations[msg.sender][recipient] = amount;
+ totalAllocated += amount;
emit FundsAllocated(recipient, amount);
}
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();
+ if (_balances[token] - totalAllocated < amount) revert InsufficientBalance();
_balances[token] -= amount;
_totalValue -= amount;
IERC20(token).transfer(recipient, amount);
emit Withdrawn(token, amount, recipient);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!