I'm fairly new to solidity so thanks in advance for your patience with this question.

I'm trying to implement a contract that uses the following line from the 0x sample provided here: https://github.com/0xProject/0x-api-starter-guide-code/blob/master/contracts/SimpleTokenSwap.sol#L90

I understand that the call won't revert itself, but will return a boolean "success" depending on whether or not it worked. However, the next line doesn't provide anything useful, as it has a hardcoded "SWAP_CALL_FAILED" string.

I'd like to bubble up the reason why it failed. According to the 0x documentation, the 0x protocol uses "rich revert" reasons that are not simply strings, but custom errors with custom params: https://0x.org/docs/guides/v3-specification#rich-reverts

My problem: How am I supposed to decode the bytes memory response without knowing in advance which error profile is in there? Is there any way to get meaningful error data from the swapTarget.call{value: msg.value}(swapCallData); call?

I should mention that I'm using a hardhat local fork, if that makes a difference.

2 Answers 2


The Solidity devs are working on supporting this more natively (you can read up on this on the try/catch docs).

Until then you would have to parse the response bytes similar how you parse a method id. An example for this can also be found on the array slices docs

Basically you would do the following:

// Check if the call failed
if (!success) {
  if (bytes4(response) == bytes4(keccak256("OrderStatus(bytes32,uint8)"))) {
     (bytes32 orderHash, uint8 orderStatus) = abi.decode(response[4:], (bytes32,uint8));
    // Custom error handling
  } else {
    revert("Unknown error");
  • Doesn't this mean I'd have to check against the keccack256 of every single error type listed here? 0x.org/docs/guides/v3-specification#rich-reverts Feels somewhat pointless to have these custom errors if they can't be surfaced to the user without the user knowing what the error is in the first place... Jan 3, 2022 at 19:27
  • Starting with Solidity 0.8.0 these are part of the abi and can be parse on client side more easily (blog.soliditylang.org/2021/04/21/custom-errors). Not sure how well the 0x errors and the Solidity errors interact with each other, but theoretically it should be quite easy to define them. Also there is 0x utils js lib that can handle this. Here an example in their tests: github.com/0xProject/protocol/blob/…
    – Richard
    Jan 3, 2022 at 19:52
  • That's a good tip, but in these examples the dev knows exactly what error to expect, so they can parse it. I'm calling 0x's external contract and have no idea which error to expect, so my only option seems to be to parse the response and loop through every possible error to check and see if the response matches a list of known errors. Seems like a super inefficient chicken-and-egg problem. What am I missing here? Jan 3, 2022 at 20:11
  • 1
    Hmm I would expect 0x to provide a library that abstracts this away, But not sure if there is one. So I would say worst case you need to write a big if-else ... sorry that I cannot help any further :/
    – Richard
    Jan 3, 2022 at 20:18

For 0x V3 these can be decoded with RevertError.decode(bytes) in the @0x/utils package. This will look at the Error bytes4 selector and decode the reason.

  • Not sure how I missed that! But how would I pass the revert error from Solidity to this? Is it safe to simply revert with the bytes memory response as the revert string? Jan 7, 2022 at 8:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.