Core Contracts

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

Treasury::deposit() => Treasury Balance Inflation Due to Unhandled Fee-On-Transfer/Tax-on-transfer Tokens

Summary

The Treasury contract fails to properly handle tokens with transfer deductions (both fee-on-transfer and tax-on-transfer tokens), leading to accounting discrepancies between recorded balances and actual token holdings.

Vulnerability Details

The Treasury contract's deposit and withdrawal functions assume that the amount of tokens specified in the transfer is equal to the amount actually received. However, for fee-on-transfer tokens, the received amount is less than the transferred amount due to fees being deducted during transfer.

The issue occurs in these functions:

/**
* @notice Deposits tokens into the treasury
* @dev Requires approval for token transfer
* @param token Address of token to deposit
* @param amount Amount of tokens to deposit
*/
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;
_totalValue += amount;
emit Deposited(token, amount);
}

When a fee-on-transfer token is deposited:

  1. User deposits 1000 tokens

  2. Contract receives 950 tokens (assuming 5% fee)

  3. Contract incorrectly records 1000 tokens in _balances

  4. Creates a 50 token discrepancy between recorded and actual balance

Impact

  1. Balance Inflation: The contract records higher balances than actually held

  2. Fund Locking: Withdrawals may fail when attempting to withdraw recorded balance amount that exceeds actual holdings

  3. Incorrect Total Value: _totalValue becomes inflated as it records pre-fee amounts

  4. Compounding Issues: The discrepancy grows with each deposit transaction

The severity is HIGH because:

  • Direct loss of funds through locked tokens

  • Core accounting functionality is compromised

  • Affects protocol's financial accuracy

  • Requires protocol changes to fix

Tools Used

Manual Review

Recommendations

Implement balance tracking to record actual received amounts:

function deposit(address token, uint256 amount) external override nonReentrant {
if (token == address(0)) revert InvalidAddress();
if (amount == 0) revert InvalidAmount();
uint256 trackedBalanceBefore = balances\[token];
IERC20(token).transferFrom(msg.sender, address(this), amount);
uint256 actualAmount = IERC20(token).balanceOf(address(this)) - trackedBalanceBefore;
balances\[token] += actualAmount;
totalValue += actualAmount;
emit Deposited(token, actualAmount);
}

This ensures:

  1. Accurate balance tracking based on actual received amounts

  2. Proper handling of fee-on-transfer tokens

  3. Correct total value calculations

  4. Prevention of withdrawal failures

Updates

Lead Judging Commences

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

Treasury::deposit increments _totalValue regardless of the token, be it malicious, different decimals, FoT etc.

Treasury::deposit increments _balances[token] with amount, not taking FoT or rebasing into account

Support

FAQs

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