Bubbling Up Errors in Solidity
Saturday, 16 July 2022 · 6 min read · ethereum solidityLet’s say that you have a contract A which makes a low-level call
or delegatecall
to another contract B:
The target contract B reverts with a revert message or custom error:
How can you bubble the error up in contract A?
Low-level calls do not revert
First of all, it’s important to know that a low-level call
or delegatecall
doesn’t revert while calling a function that reverts:
In the above example, when contract A calls contract B with a low-level call, The success
variable signals whether the call was successful (true
) or unsuccessful (false
).
Using this, we could revert in the calling contract like so:
However, the above code swallows any errors returned from the target contract! We don’t know what went wrong because no errors are bubbled up even though contract B reverts.
Bubbling up errors
Let’s examine the following solution:
- An inline assembly block is marked by assembly
{ ... }
, where the code inside the curly braces is code in the Yul language. result
is a dynamic-size byte array. If the external contract call fails, the error object is returned inresult
.- The Yul
revert
function takes in two inputs: 1) the pointer of where the error byte array starts, and 2) how long the byte array is. - For dynamic-size byte arrays, the first 32 bit of the pointer stores its size.
- To fill in 1), we do
add(32, result)
to calculate the pointer where the byte array starts. - To fill in 2), we do
mload(result)
to retrieve this value. - Combining the above, we get
revert(add(32, result), mload(result))
, which reverts the error raised in contract B.
- To fill in 1), we do
- When there is no revert data returned by the target contract, we terminate early with an empty revert.
Now, when you call contract B from contract A you get the following revert message:
In unit tests, you can write the following (with Hardhat):
Nice! By bubbling up errors we ensure that contracts do not fail silently and fail with additional context when they are available.
📬 Get updates straight to your inbox.
Subscribe to my newsletter so you don't miss new content.