Why Custom Error gas cost is higher than require or assert?

Hi!

Based on this article at Solidity blog about Custom Errors, I’ve understood that this recent Solidity feature Custom Errors would behavior in the same way as a failed condition in require statement, since it says:

require(condition, “error message”) should be translated to if (!condition) revert CustomError().

However, as you can see in this verified contract on Goerli: https://goerli.etherscan.io/address/0xa69ff680173d7317a2bb482b2d00ca99323e01d5, which has the following three very simular functions, the testFailRevert gas cost is systematically higher than the other two functions.

Is there any explanation about it?

Thanks a lot!

  function testFailRequire() external {
        for (uint256 i = 0; i < 100; i++) {
            greeting = "consome gas";
        }
        require(false);
    }

    function testFailRevert() external {
        for (uint256 i = 0; i < 100; i++) {
            greeting = "consome gas";
        }
        revert UnevitactableError();
    }

    function testFailAssert() external {
        for (uint256 i = 0; i < 100; i++) {
            greeting = "consome gas";
        }
        assert(false);
    }

Your testFailRequire() will always be the cheapest because it reverts without any message. The returndata is empty so no memory needs to be allocated to store it. You can’t beat that in terms of gas. But you also have no way to tell what failed.

testFailRevert() on the other hand returns 4 bytes of data, i.e. 0x3a7aee6f, which is the selector of the UnevitactableError() error. In terms of gas this is comparable with returning a short error code. But it provides more information because an off-chain tool can match the selector with the error definition in your code and give the user its name. It’s obviously more expensive than not returning anything but still cheaper than using "Unevitactable Error" as a revert message.

1 Like