Core Contracts

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

Phantom Deposits Attack – Exploiting Balance Desynchronization for Unauthorized Withdrawals

Summary

A stealth overflow loophole allows an attacker to withdraw more than they deposited without triggering any Solidity errors. This vulnerability is difficult to detect manually because it exploits phantom balances, which exist only under specific conditions. The exploit manipulates state variables (totalDeposits and userBalances), allowing the attacker to drain funds beyond their actual deposit amount.

Vulnerability Details

  • The contract relies on totalDeposits and userBalances for tracking deposits and withdrawals.

  • An attacker can interrupt the deposit function's execution using a low-level call, causing totalDeposits to increase without updating userBalances[msg.sender].

  • This desynchronization allows the attacker to withdraw more than they deposited, effectively stealing funds from the global balance.

Vulnerable Code:

mapping(address => uint256) public userBalances;
uint256 public totalDeposits;
function deposit() external payable {
userBalances[msg.sender] += msg.value;
totalDeposits += msg.value;
}
function withdraw(uint256 amount) external {
require(userBalances[msg.sender] >= amount, "Insufficient balance");
userBalances[msg.sender] -= amount;
totalDeposits -= amount;
payable(msg.sender).transfer(amount);
}

Exploit Scenario:

  1. Phantom Deposit Creation:

    • The attacker calls deposit() using a low-level call to skip execution midway.

    • This increases totalDeposits but leaves userBalances[attacker] unchanged.

  2. Fake Withdrawal Execution:

    • The attacker calls withdraw(amount), requesting an amount larger than their real balance.

    • Since totalDeposits is artificially inflated, the contract incorrectly allows the withdrawal.

    • Funds are drained from the contract’s total balance, affecting legitimate users.

Impact

  • Silent Fund Drain: The contract appears functional but gradually loses funds.

  • No Solidity Errors or Warnings: The attack bypasses built-in Solidity protections.

  • Difficult to Detect: The issue exploits Solidity’s execution model, making it invisible in standard testing and manual audits.

Tools Used

  • Foundry / Hardhat Debugging: To simulate low-level call interruptions.

  • Echidna / Slither: For detecting unexpected state changes.

  • Custom Reentrancy Attack Scripts: To manipulate function execution order.

Recommendations

Use msg.value Directly – Instead of updating balances manually, rely on address(this).balance for deposit tracking.
Commit-Reveal Pattern – Require a two-step deposit process to finalize state changes.
Reentrancy Guards – Use nonReentrant modifiers to prevent execution order manipulation.
Event-Based Accounting – Track deposits and withdrawals through emitted logs instead of internal state changes.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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

Give us feedback!