foundry
foundry copied to clipboard
Etherscan verification fails for complex directory structure
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.
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:
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.
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']
+1 i am also having the same issue as @Fiddlekins
Adding auto_detect_remappings = false to foundry.toml fixed this issue for me!
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!
May I work on this issue, if it's still there?
Adding
auto_detect_remappings = falsetofoundry.tomlfixed 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.
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.
we're going to close this as it's a known and documented limitation, more work could be done post v1.0. thank you!