You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a user, when I execute forge verify-bytecode with the --constructor-args flag, a warning message appears and the verification succeeds (init and runtime code partially verifies):
The provided constructor args do not match the constructor args from etherscan (0x000000000000000000000000e07ea0436100918f157df35d01dce5c11b16d1f1).
When I remove the --constructor-args flag, the warning message disappears but the verification fails (init code partially succeeds but runtime code fails).
I believe that this is expected behavior for forge verify-bytecode because Etherscan seems to be returning the wrong constructor arguments for 0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969 . However, is there perhaps a different API we can use? Or an alternative, more accurate way to retrieve the constructor arguments?
Reproducing the failure
The quickest way to reproduce this failure is using the Optimism Github repo.
Verification fails when we remove the --constructor-args flag. This is because Etherscan is returning incorrect constructor arguments for 0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969.
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
git checkout c93958755b4f6ab7f95cc0b2459f39ca95c06684
nvm install 16.0.0 && nvm use 16.0.0
yarn install
cd packages/contracts-bedrock
FOUNDRY_EVM_VERSION=london forge verify-bytecode 0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969 OptimismMintableERC20Factory
Verifying the issue
Verification succeeds because we pass through the correct --constructor-args which takes preference over the Etherscan constructor args. Notice the warning message in the screenshot.
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
git checkout c93958755b4f6ab7f95cc0b2459f39ca95c06684
cd packages/contracts-bedrock
FOUNDRY_EVM_VERSION=london forge verify-bytecode 0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969 OptimismMintableERC20Factory --constructor-args 0x6d0f65D59b55B0FEC5d2d15365154DcADC140BF3
If we convert the value printed from the warning message to an address, we get 0xe07ea0436100918f157df35d01dce5c11b16d1f1 which is an L1StandardBridgeProxy contract of an entirely different rollup chain.
We can verify this is incorrect by inspecting 0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969 's creation transaction and looking at the last 20 bytes. The value you'll see is 6d0f65d59b55b0fec5d2d15365154dcadc140bf3. This is the address that Etherscan should return as part of the API call.
I think that if a similar contract has been deployed before, Etherscan references that contract source code and constructor arguments instead of the contract a user asks for.
See screenshot below (the address referenced in the screenshot 0xa2f9fcf9108d870d4a8249bf3b74e812a3bd39fb, contains the incorrect constructor args being returned i.e. 000000000000000000000000e07ea0436100918f157df35d01dce5c11b16d1f1:
Possible Resolution
One possible workaround while still using Etherscan could be as follows:
Use Etherscan's API to return the contract's creation transaction.
Once returned, extract the transaction's input data.
Using the data compiled in forge-artifacts (e.g., OptimismMintableERC20Factory.json file), extract the init code from bytecode.object:
With the transaction input data from step 2, remove the init code retrieved in step 3. The remaining part will be the constructor arguments. Here’s how to do it in TypeScript:
yeah, I think we just need to expose --guess-constructor-args option for forge vb. It does exactly what you've mentioned in the issue. Though this would only be possible in cases of full creation code match
@klkvr So I understand, would the default usage be to always pass constructor args via --constructor-ags and the alternative approach be to explicitly pass the --guess-contstructor-args argument, for when you don't have the constructor args in situ and you want forge vb to perform a best effort to guess them?
Component
Forge
Have you ensured that all of these are up to date?
What version of Foundry are you on?
forge 0.2.0 (bdd1137 2024-07-28T00:21:06.817030000Z)
What command(s) is the bug in?
forge verify-bytecode
Operating System
macOS (Apple Silicon)
Describe the bug
This issue is a follow-up to the previously closed issue foundry-rs/foundry#8505. Although the PR fix has ensured that the
--constructor-args
functionality now works, I believe Etherscan is returning incorrect constructor arguments for some contracts via the Get Contract Source Code for Verified Contract Source Codes API.As a user, when I execute
forge verify-bytecode
with the--constructor-args
flag, a warning message appears and the verification succeeds (init and runtime code partially verifies):When I remove the
--constructor-args
flag, the warning message disappears but the verification fails (init code partially succeeds but runtime code fails).I believe that this is expected behavior for
forge verify-bytecode
because Etherscan seems to be returning the wrong constructor arguments for0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969
. However, is there perhaps a different API we can use? Or an alternative, more accurate way to retrieve the constructor arguments?Reproducing the failure
The quickest way to reproduce this failure is using the Optimism Github repo.
Verification fails when we remove the
--constructor-args
flag. This is because Etherscan is returning incorrect constructor arguments for0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969
.Verifying the issue
Verification succeeds because we pass through the correct
--constructor-args
which takes preference over the Etherscan constructor args. Notice the warning message in the screenshot.If we convert the value printed from the warning message to an address, we get
0xe07ea0436100918f157df35d01dce5c11b16d1f1
which is anL1StandardBridgeProxy
contract of an entirely different rollup chain.When hitting Etherscan's API:
We can see that the
ConstructorArguments
field is indeed incorrect:We can verify this is incorrect by inspecting
0x0d3495a95eC5720453C0d70a88Bf14fe13ebe969
's creation transaction and looking at the last 20 bytes. The value you'll see is6d0f65d59b55b0fec5d2d15365154dcadc140bf3
. This is the address that Etherscan should return as part of the API call.I think that if a similar contract has been deployed before, Etherscan references that contract source code and constructor arguments instead of the contract a user asks for.
See screenshot below (the address referenced in the screenshot 0xa2f9fcf9108d870d4a8249bf3b74e812a3bd39fb, contains the incorrect constructor args being returned i.e.
000000000000000000000000e07ea0436100918f157df35d01dce5c11b16d1f1
:Possible Resolution
One possible workaround while still using Etherscan could be as follows:
OptimismMintableERC20Factory.json
file), extract the init code frombytecode.object
:The text was updated successfully, but these errors were encountered: