Core Contracts

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

Unchecked ERC20 Transfer in Treasury::deposit Enables Phantom Balances and Temporary DoS

Likelihood: High

Severity: Medium

1. Summary

The Treasury contract’s deposit function calls IERC20(token).transferFrom(msg.sender, address(this), amount) without verifying its return value. This allows a malicious token that always returns false to inflate the Treasury’s internal accounting (_balances and _totalValue) without actually transferring any funds.


2. Technical Details

2.1. Protocol Context

The Treasury contract manages deposits of ERC20 tokens by transferring tokens from the user and updating its internal balance mappings. Accurate accounting is crucial for subsequent fund management and protocol operations.

2.2. Vulnerability

In the deposit function, the lack of return value checking means that even if transferFrom fails (i.e., returns false), the contract proceeds to update its state:

function deposit(address token, uint256 amount) external override nonReentrant {
if (token == address(0)) revert InvalidAddress();
if (amount == 0) revert InvalidAmount();
// No check is performed here
IERC20(token).transferFrom(msg.sender, address(this), amount);
_balances[token] += amount;
_totalValue += amount;
emit Deposited(token, amount);
}

An attacker can exploit this by depositing a token that deliberately fails on transferFrom, thereby inflating the Treasury’s reported balances.


3. Impact

  • Protocol Disruption: Causes a temporary denial-of-service on the treasury deposit function by reaching _totalValue.

  • Inaccurate Accounting: Inflated _balances and _totalValue misrepresent actual funds.

4. Tools used

Manual review

5. Recommended Fix

Implement safe transfer methods to ensure state updates occur only after successful token transfers. For example, use OpenZeppelin’s SafeERC20:

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);
+ IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
_balances[token] += amount;
_totalValue += amount;
emit Deposited(token, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[INVALID] SafeERC20 not used

LightChaser Low-60

Support

FAQs

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