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

feat: forge verify-bytecode <address> to verify that code at a commit hash matches on-chain code #6893

Closed
mds1 opened this issue Jan 24, 2024 · 6 comments
Labels
T-feature Type: feature

Comments

@mds1
Copy link
Collaborator

mds1 commented Jan 24, 2024

Component

Forge

Describe the feature you would like

Motivation

Users often want to make sure that bytecode at an address can be tied to a certain git commit. Common use cases of this are:

  1. Verifying that the code from the fix commit of an audit or security review matches the code that was actually deployed.
  2. Verifying that the code of a repo commit being proposed in a governance proposal matches the code that was actually deployed.

It's a lot of work for a contract verification service to also validate that the code being verified exists at a given commit, for all frameworks and languages. But it is easy for frameworks themselves to implement this feature on a case by case basis.

Solution

A new feature named forge verify-bytecode <address> (open to other names) to execute this check. It has the following syntax:

forge verify-bytecode <address> \
    [--block <blockTag>] \
    [--constructor-args <args> | --constructor-args-path <path> | --guess-constructor-args] \
    [--verification-type <full | partial>] \
    [--rpc-url <rpcUrl>]

And it behaves as follows:

  1. User clones some repo and checks out a commit.
  2. User executes forge verify-bytecode <address>.
    1. Similar to cast, ETH_RPC_URL is used as the default RPC, but an alternative can be provided using the --rpc-url flag.
    2. They can also optionally specify a build profile, or any other CLI flags allowed during forge build.
  3. Forge fetches the runtime bytecode at that address on the given chain. It also fetches the creation code from Etherscan or another verification service. This gives us the bytecodes we want to verify against.
  4. Forge compiles the repo using the given config. It now has build artifacts.
  5. Forge needs constructor arguments for the creation code. These can be obtained in multiple ways, in order of what should be preferred:
    1. User provides --constructor-args or --constructor-args-path, or uses --guess-constructor-args (from feat(forge verify-contract): --guess-constructor-args #6724)
    2. Constructor arguments are fetched from Etherscan/verification service.
  6. Creation code check can now be performed by appending the constructor arguments to the generated creation code and checking for a match. The metadata hash check defaults to using what’s specified in the build profile, but can be overridden with the --verification-type flag
  7. Runtime code check can now be performed by executing deployment of the creation code on a fork of the RPC URL. Metadata hash check is the same as above. For block number, in order of what should be preferred:
    1. If the user provided a --block <blockTag> arg, fork from the RPC at that block and simulate to get the runtime code.
    2. If the verification service returns the block number of deployment, use that

Additional context

No response

@mds1 mds1 added the T-feature Type: feature label Jan 24, 2024
@gakonst gakonst added this to Foundry Jan 24, 2024
@github-project-automation github-project-automation bot moved this to Todo in Foundry Jan 24, 2024
@maurelian
Copy link

I believe that this will also need to take into account whether the metadata hash is included.
If not, the above should suffice.

If the hash is included, then either full or partial verification can be performed.

This could be an additional flag --verification-type=full|partial, or else the existing metadata_hash config value could be used so that full verification is done whenever possible.

@mds1
Copy link
Collaborator Author

mds1 commented Jan 24, 2024

Good point. My understanding is the metadata hash will likely differ since the command will usually be run on a different machine than the one that originally compiled the code, and the hash can sometimes be machine-dependent in my experience.

I’d suggest the command defaults to the metadata hash setting specified in the build profile, but allow overriding it with a flag like you suggested. I’ll update the spec above accordingly

@mds1
Copy link
Collaborator Author

mds1 commented Jan 24, 2024

I could also imagine adding a --use-remote-solc-config flag to ignore the local build profile and use the solc config returned by the verification service. However, in most workflows there should be a profile that matches that config, so I don't think this is strictly necessary, but it might be nice to have as an alternate option

@yash-atreya
Copy link
Member

I can take a stab at this!

@DaniPopes
Copy link
Member

can this be closed? @yash-atreya

@mds1
Copy link
Collaborator Author

mds1 commented Apr 12, 2024

Yep this was closed by #7319

@mds1 mds1 closed this as completed Apr 12, 2024
@jenpaff jenpaff moved this from Todo to Completed in Foundry Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-feature Type: feature
Projects
Archived in project
Development

No branches or pull requests

4 participants