Core Contracts

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

Unsafe ERC20 Transfer in `Treasury.withdraw` Allows Permanent Accounting Corruption

Summary

The Treasury.withdraw function contains a critical flaw in its ERC20 transfer handling. The implementation updates internal accounting balances without properly validating token transfer success. This allows the contract's financial state to become permanently inconsistent with actual token holdings when transfers silently fail. The vulnerability affects all non-reverting ERC20 asset withdrawals and creates systemic risks to protocol accounting integrity.

Vulnerability Details

The Treasury.withdraw function (Treasury.sol#L75) contains an unsafe ERC20 token transfer pattern that fails to properly handle transfer results, performing the token transfer without verifying its success:

  • Uses IERC20.transfer() without checking return value

  • Fails to handle non-reverting ERC20 implementations that return false on failure

contract Treasury is ITreasury, AccessControl, ReentrancyGuard {
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;
_totalValue -= amount;
@> IERC20(token).transfer(recipient, amount);
emit Withdrawn(token, amount, recipient);
}
}

This creates a critical inconsistency where the contract's internal accounting reflects withdrawn funds even when the actual token transfer fails. Malicious actors could potentially exploit this to:

  • Create false accounting records

  • Lock protocol funds through repeated failed withdrawals

  • Disrupt treasury balance tracking mechanisms

The vulnerability particularly affects tokens that implement non-reverting ERC20 transfers (as permitted by the standard) and contracts with special transfer logic. The lack of state reversal on failed transfers makes this a persistent accounting error that could compound over multiple transactions.

Impact

This vulnerability poses critical risks to protocol financial integrity:

  1. Permanent Accounting Corruption
    Failed transfers leave treasury balances permanently out-of-sync with actual token holdings, creating unrecoverable discrepancies in protocol bookkeeping

  2. Fund Locking Vectors
    Repeated failed withdrawals could progressively reduce recorded balances while keeping tokens trapped in the contract, effectively freezing protocol liquidity

  3. Attack Surface Expansion
    Malicious actors could:

    • Craft token contracts that intentionally fail transfers

    • Exploit balance inconsistencies to bypass financial controls

Affected Components

  • All treasury-managed ERC20 assets

  • Systems relying on treasury balance reporting

Tools Used

Manual Review

Recommendations

Check token transfer returned status and revert if transfer failed:

bool success = IERC20(token).transfer(recipient, amount);
if (!success) revert WithdrawTokenTransferFailed();
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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