Return-bomb attack
June 15th, 2024

Resources used:

  1. What is returnBomb

  2. What is the memory expansion cost?

  3. Return Bomb Example

  4. Excessive Safe Call


Let’s dive into the Ethereum Yelow Paper for a moment, so it would be easier to understand the details of the return bomb attack.

Part #1 - Memory Expansion Cost

The formula calculates the extra gas required by a contract's memory consumption

Where:

  • a - This represents the highest memory index (denoted in 32-byte words) that your contract call writes to. If your contract writes to memory slot 0, 1, 2, ..., a, then a is the maximum index written.

  • G memory - is the gas cost per memory word, which is 3 according to the Ethereum yellow paper.

To calculate the extra gas required:

  1. Firstly, we should find the a by dividing the maximum memory used in our function in bytes by 32 (since 1 word = 32 bytes). For example, if your contract uses 1,024 bytes of memory, a = 1024 / 32 = 32.

  2. Secondly, we multiply G memory with a = 3 * 32 = 96

  3. Then we put the a into the square root and divide by → 32**2 = 1024; 1024 / 512 = 2

  4. Finally, we could finish the formula with final addition 96 + 2 = 98 gas

General Observations

  • The cost of memory expansion increases significantly as the memory used increases, especially for larger memory sizes due to the quadratic term.

  • For most contract calls using a few kilobytes of memory, the memory expansion cost remains relatively small compared to other costs like modifying storage variables.

  • Structs and arrays increase memory consumption more significantly than basic variables like bytes32 or uint256.

Also, it worth to remember about edge case (described below). No need to rephrase so i leave as it is

Part #2 - Return Bomb Attack

A return bomb attack is a type of Denial-of-Service (DoS) attack in Ethereum smart contracts. It exploits the way memory and gas work in the Ethereum Virtual Machine (EVM) during low-level function calls.

How It Works:

  1. Low-Level Call:

    In Solidity, a low-level call is performed using <address>.call(). This allows a contract to call another contract, but it doesn't check the size of the data returned by the callee.

  2. Memory and Gas Costs:

    When a contract performs a call, any data returned by the callee is automatically copied into memory.

    Expanding memory in the EVM costs gas. The more memory you use, the more gas you have to pay. This cost increases significantly as more memory is used.

  3. The Attack:

    A malicious contract (the callee) can exploit this by returning an excessively large amount of data.

    The caller contract tries to copy this large data into memory, rapidly increasing gas usage.

    If the gas limit is reached, the transaction fails, causing the caller contract's execution to halt.

    Example:

Solution: Excessively Safe Calls

To prevent return bomb attacks, you can use the ExcessivelySafeCall library, which limits the amount of data copied into memory.

  • Safe Call: By limiting the number of bytes copied (e.g., 32 bytes), you prevent the caller from running out of gas due to large return data.

  • Cleanup Execution: Ensuring that the caller has enough gas to complete important cleanup operations after the call.


Part #3 - Real example by Arbitrum

When i studied the topic, i found out a great article, written by tincho. He has audited the Arbitrum cross-chain bridge, and found out that Arbitrum has no preventive checks against return bomb attack and Arbitrum states that it is “intended behavior”. Let’s see.

Subscribe to Arsen
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.