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

Function pointer types produce invalid Solidity output #76

Closed
gnidan opened this issue Jul 17, 2022 · 2 comments
Closed

Function pointer types produce invalid Solidity output #76

gnidan opened this issue Jul 17, 2022 · 2 comments
Labels
bug Something isn't working

Comments

@gnidan
Copy link
Owner

gnidan commented Jul 17, 2022

Originally raised by @esaulpaugh in #67.

For type "function" parameters, abi-to-sol only outputs function <identifier> rather than proper Solidity syntax which includes arguments and return type.

e.g., the following Solidity:

Map.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.11;

contract Map {
    function map(
        function (uint256) external pure returns (uint256) f,
        uint256[] calldata list
    )
        public
        pure
        returns (uint256[] memory)
    {
        uint256[] memory mapped = new uint256[](list.length);

        for (uint256 i = 0; i < list.length; i++) {
            mapped[i] = f(list[i]);
        }

        return mapped;
    }
}

This contract defines function map(function (uint256) external pure returns (uint256) f, uint256[]) to accept an external function pointer as argument. As @esaulpaugh has also stated in the other issue, the output ABI JSON for this contract defines type and internalType, where type specifies merely function and no other information, and internalType does provide enough information but is not spec-compliant.

See full ABI JSON:

Corresponding ABI JSON for contract `Map`
[
  {
    "inputs": [
      {
        "internalType": "function (uint256) pure external returns (uint256)",
        "name": "f",
        "type": "function"
      },
      {
        "internalType": "uint256[]",
        "name": "list",
        "type": "uint256[]"
      }
    ],
    "name": "map",
    "outputs": [
      {
        "internalType": "uint256[]",
        "name": "",
        "type": "uint256[]"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  }
]

And see what abi-to-sol produces:

abi-to-sol output for this ABI JSON (hand-prettified)
// SPDX-License-Identifier: UNLICENSED
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.2. SEE SOURCE BELOW. !!
pragma solidity >=0.7.0 <0.9.0;

interface MyInterface {
    function map(
        function f,
        uint256[] memory list
    ) external pure returns (uint256[] memory);
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"function (uint256) pure external returns (uint256)","name":"f","type":"function"},{"internalType":"uint256[]","name":"list","type":"uint256[]"}],"name":"map","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"pure","type":"function"}]
*/

Since abi-to-sol already uses internalType extensively when it is available, the trick here, I suppose, will be to identify appropriate fallback behavior when internalType is not available... should abi-to-sol just fail in this situation? Or maybe it's fine? I'll have to do some testing.

Anyway, thanks @esaulpaugh for bringing this to my attention!

@gnidan gnidan added the bug Something isn't working label Jul 17, 2022
@gnidan
Copy link
Owner Author

gnidan commented Jul 17, 2022

Consideration for what to do about input ABI JSONs where internalType isn't provided:

If abi-to-sol outputs just function() f for the parameter, then in theory one could use abi.encodePacked() alongside Solidity's f.address and f.selector syntax (defined in their Function types documentation) to interact with the function correctly. This would require actually knowing the parameter and return types ahead of time, and there'd be no type safety, but it's probably still better than throwing an exception. Maybe abi-to-sol should output a warning comment inline in this situation?

This is what I'll go with when I implement the fix for this.

@gnidan
Copy link
Owner Author

gnidan commented Jul 17, 2022

This is now fixed and released in abi-to-sol v0.6.3 (and deployed to the gh-page). Thanks again!

@gnidan gnidan closed this as completed Jul 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant