Resources used:
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.
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:
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
.
Secondly, we multiply G memory
with a
= 3 * 32 = 96
Then we put the a into the square root and divide by → 32**2 = 1024
; 1024 / 512 = 2
Finally, we could finish the formula with final addition 96 + 2 = 98 gas
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
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.
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.
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.
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:
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.
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.