foundry icon indicating copy to clipboard operation
foundry copied to clipboard

Etherscan verification fails for complex directory structure

Open haydenshively opened this issue 2 years ago • 8 comments

Component

Forge

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

  • [X] Foundry
  • [X] Foundryup

What version of Foundry are you on?

forge 0.2.0 (a44aa13 2023-01-09T00:10:29.992832Z)

What command(s) is the bug in?

forge script --broadcast --verify

Operating System

macOS (Apple Silicon)

Describe the bug

I've created a simple repo to reproduce the issue here. I've got a non-standard repository structure. It works perfectly for every command I've tried, with this one exception: Etherscan verification fails for any periphery contract that depends on files nested inside of core/src. i.e., it's fine for periphery/src/MyHelper.sol to import core/src/MyContract.sol, but if core/MyContract.sol imports something from core/src/<any-other-directory>/<any-other-file.sol>, verification fails (see error below).

Interestingly, the output build json for periphery/src/MyHelper.sol does list core/src/<any-other-directory>/<any-other-file.sol> as a source. For some reason it's just not being uploaded to Etherscan.

Submitted contract for verification:
        Response: `OK`
        GUID: `bjzmvh3dmrwgi3r5aizqkhwytv6psxefyzfvekppi84y5hynsp`
        URL:
        https://api-goerli.etherscan.io/apiaddress/0xddcfbbe2c2fbf750c472d354fc08e8d98f01651e
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Contract verification status:
Response: `NOTOK`
Details: `Fail - Unable to verify. Solidity Compilation Error: Source "lib/core/src/libraries/Foo.sol" not found: File not found. Searched the following locations: "".`
Contract failed to verify.

haydenshively avatar Jan 09 '23 21:01 haydenshively

We've run into this same issue now too, trying to run forge verify-contract. (version: forge 0.2.0 (7398b65 2023-03-29T00:20:50.782162Z))

Response: `NOTOK`
Details: `Fail - Unable to verify. Solidity Compilation Error: Source "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol" not found: File not found. Searched the following locations: "".`
Contract failed to verify.

We looked into it a bit and can provide some more insight into what the surface level cause is.

We output the JSON payload to examine (using the --show-standard-json-input flag) and get the following: verification-json

The project's top level remappings.txt actually only contains the following:

@openzeppelin-contracts=lib/openzeppelin-contracts/contracts

This corresponds to the payload's settings.remappings[1], with the settings.remappings[0] entry coming from the mock-contracts dependency which also uses the OZ lib.

Checking the contents of the values listed in the payloads sources map we see the imports are in their original form

import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";

It's not clear to me why etherscan would resolve that using settings.remappings[1] before settings.remappings[0], but nevertheless it does so, trying to find lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol only to return an error because there's no corresponding entry in the sources map.

We briefly experimented with manually modifying and submitting the payload JSON, such that we duplicated the lib/mock-contracts/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol entry and renamed the key to lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol. This resolved the missing file error, instead failing because the final bytecode didn't match due to the OZ lib version being different between the top level dep and the dep's dep.

To summarise, forge seems to be incorrectly de-duping dependencies based on either file or contract name, when it should be using their filepath instead.

Fiddlekins avatar May 17 '23 16:05 Fiddlekins

I've had a similar issue, what worked as a temporary fix is applying the following change to my foundry.toml:

[profile.default]
 src = 'contracts'
-libs = ['lib', '../../node_modules']
+libs = ['lib', '/full-path-to-project/my-monorepo/node_modules']

davidbrai avatar May 29 '23 16:05 davidbrai

+1 i am also having the same issue as @Fiddlekins

ryanio avatar May 31 '23 21:05 ryanio

Adding auto_detect_remappings = false to foundry.toml fixed this issue for me!

ryanio avatar Jun 02 '23 00:06 ryanio

So, this is expected behavior regarding ambiguous paths: https://book.getfoundry.sh/forge/deploying?highlight=verify-contra#known-issues ; sadly etherscan only really handle relative paths. @ryanio 's fix works!

Evalir avatar Jun 20 '23 18:06 Evalir

May I work on this issue, if it's still there?

ShubhSensei avatar Jul 12 '23 18:07 ShubhSensei

Adding auto_detect_remappings = false to foundry.toml fixed this issue for me!

This worked for me. No idea why it fixes it but adding a foundry.toml like this:

[profile.default]
 auto_detect_remappings = false

caused it to work.

charlescrain avatar Sep 01 '23 15:09 charlescrain

I spent some time running forge remappings with auto_detect_remappings = true and auto_detect_remappings = false and comparing the two outputs against the file Etherscan complained about,but for me, leaving auto_detect_remappings = false and explicitly adding a remapping from a submodule to my top level foundry.toml did the job.

DJViau avatar Sep 28 '23 15:09 DJViau

we're going to close this as it's a known and documented limitation, more work could be done post v1.0. thank you!

grandizzy avatar Oct 31 '24 12:10 grandizzy