foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
8.31k stars 1.75k forks source link

bug(`forge verify-bytecode`): bytecode verification fails with solidity v0.8.26 optimization #9302

Open QGarchery opened 2 days ago

QGarchery commented 2 days ago

Component

Forge

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

What version of Foundry are you on?

forge 0.2.0 (58bf161 2024-11-07T00:20:40.732513260Z)

What command(s) is the bug in?

forge verify-bytecode

Operating System

Linux

Describe the bug

Sometimes some constants are appended at the end of the creation bytecode. Those constants are not values of immutable variables. Here is a run in a dedicated repository with a minimal example.

Notice how the SOME_SLOT bytes are appended in v0.8.26 but not in v0.8.25.

From personal testing that I can't share at the moment, this seems to be causing forge verify-bytecode to not be able to verify a deployed contract. Are the extra bytes at the end of the creation code something that forge verify-bytecode can handle ?

If full reproducibility is needed I can try to provide another example

zerosnacks commented 2 days ago

Hi @QGarchery, this is possibly related to a change in the optimizer steps in solc between the versions (https://soliditylang.org/blog/2024/05/21/solidity-0.8.26-release-announcement/ introduced a new default sequence).

For reference:

0.8.25:

0x60808060405234603f577faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa805460ff19166001179055603a908160458239f35b600080fdfe600080fdfea26469706673582212206faa8db067b12b11ab75292229ab41a8cba9c2210f1082d987398b1b9542958564736f6c63430008180033

0.8.26 (and above):

0x60808060405234603857600160ff196000805160206078833981519152541617600080516020607883398151915255603a9081603e8239f35b600080fdfe600080fdfea2646970667358221220e9a8ec4a7cc1719f937319b8f1f885eda9d75c51db5993d45baf54b06816e9fc64736f6c634300081a0033aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
grandizzy commented 1 day ago

Per @zerosnacks comment and 0.8.26 release notes,

If you observe significantly degraded optimization quality in your project, we recommend temporarily switching back to the old sequence and opening an issue so that we can investigate.
The default sequence in Solidity v0.8.25 included the following steps:

dhfoDgvulfnTUtnIf [ xa[r]EscLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LSsTFOtfDnca[r]Iulc ] jmul[jul] VcTOcul jmul : fDnTOcmu

so that would be equivalent with following foundry.toml setting

[profile.default.optimizer_details.yulDetails]
optimizerSteps = "dhfoDgvulfnTUtnIf[xa[r]EscLMcCTUtTOntnfDIulLculVcul[j]Tpeulxa[rul]xa[r]cLgvifCTUca[r]LSsTFOtfDnca[r]Iulc]jmul[jul]VcTOculjmul:fDnTOcmu"
QGarchery commented 1 day ago

Using solc-0.8.26 --bin src/Counter.sol --optimize --via-ir:

60808060405234603657600160ff195f8051602060748339815191525416175f8051602060748339815191525560399081603b8239f35b5f80fdfe5f80fdfea264697066735822122002cd0c349a1b02c9105d19d5372d6283072a2f38dc38f5e802aa601bfa43107e64736f6c634300081a0033aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

adding --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu' to the previous command, to switch back the old compiler sequence:

608060405234601b57600e6042565b604051603e9081606e8239f35b5f80fd5b90565b90602f601f603e92151590565b825460ff191660ff9091161790565b9055565b606b60017faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6022565b56fe60806040525f80fdfea2646970667358221220fecb2398062ab49a718d83949ccc0183f5fd698078ae114215c174c0b3ec254664736f6c634300081a0033
zerosnacks commented 1 day ago

@QGarchery if I understand you correctly, we can mark this as resolved / not planned? If not I think a more suitable place to flag issues around this is the Solidity compiler: https://github.com/ethereum/solidity/issues as Foundry does not control bytecode generation itself and relies entirely on the compiler.

I don't think we should make forge verify-bytecode, if compiled w/ the same version, lenient to changes in the optimization sequence (either changes by default or specified by the user).

QGarchery commented 1 day ago

To be clear: I found that compiling and verifying with the same default values (the ones of the linked repository) does not make forge verify-bytecode go through. I understand that if different optimization sequences or different parameters are passed, then it's ok to reject the verification. But this is not what happens here, and the same optimization sequence (the default one for solidity 0.8.26) and the same compilation parameters were used.

This means that some deployed contract onchain can't be verified using forge verify-bytecode, or at least I have not found how to do it. For that reason, I don't think we can mark this issue as resolved yet

zerosnacks commented 1 day ago

cc @yash-atreya