Solidity Error Handling – How to Decode, Trace, and Search Custom Error Byte Code

bytessoliditysolidity-0.8.x

I ran into this Custom Error during my Foundry test:

[FAIL. Reason: Custom Error cd786059:(0xF628...)]

and I had no idea about what it means…
then I figured out where it went wrong after tracing back to this Solidity source code:

revert AddressInsufficientBalance(address(this));

Then I figured out how to confirm this error without using Foundry's expectRevert():

        bytes4 errorSignature = 0xcd786059;//must prefix "0x"
        bytes4 desiredSelector = bytes4(keccak256(bytes("AddressInsufficientBalance(address)")));
        console.log(errorSignature == desiredSelector);

But that is not an efficient way to solve this, especially if I have a large Solidity codebase.

How can I quickly search and find out where Solidity Custom Error codes come from?

Best Answer

According to the documentation, user error codes are selectors on them, encoded just as the function calls. That is, if you have an error defined

error InsufficientBalance(uint256 available, uint256 required);

The error data will be encoded in the same way as the ABI encoding for function calls, i.e.

abi.encodeWithSignature("InsufficientBalance(uint256,uint256)", balance[msg.sender], amount)

The compiler also includes all errors that the contract can generate in the ABI-JSON of the contract (Except for errors passed through external calls).

{
    "inputs": [
        {
            "internalType": "uint256",
            "name": "available",
            "type": "uint256"
        },
        {
            "internalType": "uint256",
            "name": "required",
            "type": "uint256"
        }
    ],
    "name": "InsufficientBalance",
    "type": "error"
},

How to track errors in Foundry, see here: https://ethereum.stackexchange.com/a/125296/99256.

Related Topic