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

cast/forge: preserve contract types when generating interfaces from ABI #8837

Open
2 tasks done
mds1 opened this issue Sep 9, 2024 · 4 comments
Open
2 tasks done
Labels
C-cast Command: cast Cmd-forge-inspect Command: forge inspect T-feature Type: feature T-post-V1 Area: to tackle after V1

Comments

@mds1
Copy link
Collaborator

mds1 commented Sep 9, 2024

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (143abd6 2024-09-04T00:24:41.963834000Z)

What command(s) is the bug in?

cast interface / forge inspect

Operating System

None

Describe the bug

To reproduce, forge init a new project and add this contract:

contract Foo {
  function bar(Counter x) public view returns (Counter y) {
    return x;
  }
}

When generating an interface, the function inputs and return type both are converted to address, which strips information. You can see the Counter type is present in the ABI of Foo:

"abi": [
  {
    "type": "function",
    "name": "bar",
    "inputs": [
      {
        "name": "x",
        "type": "address",
        "internalType": "contract Counter"
      }
    ],
    "outputs": [
      {
        "name": "y",
        "type": "address",
        "internalType": "contract Counter"
      }
    ],
    "stateMutability": "view"
  }
],

But when generating interfaces:

$ forge inspect Foo abi --pretty
interface Foo {
    function bar(address x) external view returns (address y);
}

$ cast interface Foo
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.4;

interface Foo {
    function bar(address x) external view returns (address y);
}

I can see the rationale for this being that forge might not know what path to use for the Counter import. However, even if no import statement is provided, I would still prefer a stronger version of interface generation that preserves the internal Counter type. Perhaps this should be behind a --preserve-internal-types flag

cc @smartcontracts

@mds1 mds1 added T-bug Type: bug T-needs-triage Type: this issue needs to be labelled labels Sep 9, 2024
@yash-atreya yash-atreya added C-cast Command: cast Cmd-forge-inspect Command: forge inspect and removed T-needs-triage Type: this issue needs to be labelled labels Sep 10, 2024
@yash-atreya
Copy link
Member

@DaniPopes
Copy link
Member

There is no information about Counter in Foo, so I don't see the point in preserving this since we would have to generate an empty Counter interface; in any case they're ABI-equivalent

@DaniPopes DaniPopes added T-feature Type: feature and removed T-bug Type: bug labels Sep 10, 2024
@DaniPopes DaniPopes changed the title cast/forge: contract types not preserved when generating interface cast/forge: preserve contract types when generating interfaces from ABI Sep 10, 2024
@mds1
Copy link
Collaborator Author

mds1 commented Sep 10, 2024

Right, forge would generate an incomplete interface, and the user would have to fix it by importing Counter from the proper path. The value here is that having Counter in the interface is a stronger type than address, and currently the user must manually fix the interface to preserve the stronger typing. This manual fix is tedious and error prone for large interfaces

@smartcontracts
Copy link

I think you'd need to use the AST to figure this out correctly. My ideal version of this would generate a full interface file complete with imports, e.g.:

// Foo.sol
contract Foo {
  function bar(Counter x) public view returns (Counter y) {
    return x;
  }
}
// Counter.sol
contract Counter {
  function whatever() public view returns (whatever) {
    return whatever;
  }
}

Ideal generated file:

// IFoo.sol

import { Counter } from "./Counter.sol";

interface IFoo {
  function bar(Counter x) external view returns (Counter y);
}

@grandizzy grandizzy added the T-post-V1 Area: to tackle after V1 label Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-cast Command: cast Cmd-forge-inspect Command: forge inspect T-feature Type: feature T-post-V1 Area: to tackle after V1
Projects
None yet
Development

No branches or pull requests

5 participants