0

Consider the following Solidity code:

        (bool success, ) = address(_token).call(
            abi.encodePacked(
                _RECEIVE_WITH_AUTHORIZATION_SELECTOR,
                receiveAuthorization
            )
        );

This uses call() for an external contract call.

However, as we know, call does not bubble any revert reason, and thus loses important debug information.

Is there a way to do call-equivalent but directly raise any revert as a passthrough instead of absorbing and losing the revert message?

1 Answer 1

1

Here's a code snippet that checks if a call reverts, loads the revert string message if true and raises it correctly.

Side note: Using abi.encodePacked can lead to incorrect input encoding if you are using solidity types < 32 bytes (i.e. address, uint8 ...). Instead use abi.encodeWithSelector for this end.

    (bool success, bytes memory data) = address(_token).call(
        abi.encodeWithSelector(
            _RECEIVE_WITH_AUTHORIZATION_SELECTOR,
            receiveAuthorization
        )
    );

    if(!success) {
        assembly{
            let revertStringLength := mload(data)
            let revertStringPtr := add(data, 0x20)
            revert(revertStringPtr, revertStringLength)
        }
    }

However I would discourage using assembly or even the call() method overall. Instead use interfaces for cleaner, easier and more readable code that handles these aspects:

interface ITokenAuth {
    function receiveAuthorization(bool _auth) external;
}

contract Example {
    function callMe(address _token, bool _auth) external {
       ITokenAuth(_token).receiveAuthorization(_auth);
    }
}
1
  • Thank you. In this case it is related to EIP-3009, the example code was directly from the spec. It's using call() passthrough of parameters, because it simplifies the process a lot (and likely saves tons of gas.) Here is the spec github.com/ethereum/EIPs/issues/3010 May 17, 2023 at 15:20

Your Answer

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

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