Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add abi.decodeCall reciprocal function of abi.encodeCall #15154

Open
CedarMist opened this issue May 28, 2024 · 0 comments
Open

Add abi.decodeCall reciprocal function of abi.encodeCall #15154

CedarMist opened this issue May 28, 2024 · 0 comments
Labels

Comments

@CedarMist
Copy link

Abstract

The abi.encodeCall function is very useful as the type information can be defined in common interfaces used across source files. For example:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface CommonInterface {
    struct Doop {
        uint256 a;
        bool[3] b;
        string c;
    }
    function blah(uint8 y, Doop calldata x) external;
}

contract EncodeExample {
    function encode() public pure returns (bytes memory) {
        return abi.encodeCall(CommonInterface.blah, (4, CommonInterface.Doop(1,[true,false,true],"c")));
    }
}

However, decoding the result is very awkward, abi.encodeCall returns bytes memory and includes the function selector, but you can't easily slice the result to skip the 4 byte function selector and must re-specify the arguments of the function which is being encoded.

In an ideal world, the following would work:

    function encodeDecode() public view returns (uint8, CommonInterface.Doop memory) {
        bytes memory data = abi.encodeCall(CommonInterface.blah, (4, CommonInterface.Doop(1,[true,false,true],"c")));
        return abi.decodeCall(CommonInterface.blah, data);
    }

Motivation

Many contracts pass function calls around or interpret them in one way or another, especially now that bridging protocols and account abstraction is pervasive. However, the need to explicitly specify the types used when decoding can lead to subtle errors where the data is decoded but is interpreted as the wrong type, or it can make refactoring tedious during development.

Using structures defined in common files is one way to address this problem, as is (ab)using the Solidity auto-generated function call dispatch routines in contracts.

But really, it would be useful to round-trip encoded calls.

Specification

  • abi.decodeCall(function functionPointer, (...), bytes memory) returns (...): ABI-decodes a call to functionPointer with the given data. Performs a full type-check ensuring the return types match the function signature. Encoded function signature must match the functionPointer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant