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

Hardhat and Truffle with same compiler options compile different bytecode #1147

Closed
Aleione opened this issue Jan 3, 2021 · 13 comments
Closed

Comments

@Aleione
Copy link

Aleione commented Jan 3, 2021

Issue

In the same repository i have set config file for truffle and hardhat. Compiler options (version, evm version, optimizer and runs) are the same. If i compare bytecode between truffle build folder and hardhat artifacts folder, for the same solidity contract, they are different. In this way we can not verify some contract with hardhat/etherscan since it can not detect the code deployed using truffle migration (since hardhat does not support migration). Other problem can be for developers that will use CREATE2 opcode in their solidity code.

Steps to Reproduce

You can reproduce it in this way:
clone code at this link: https://gitlab.com/jarvis-network/apps/exchange/mono-repo
move in branch: feature/uma-integration-part-2
yarn install
cd libs/contracts
yarn truffle compile
yarn hardhat compile

Expected Behavior

Same bytecode in artifacts folder (Truffle and Hardhat) for all contracts

Actual Results

There are differences in bytecode in some contracts (Ex. TICHelper, TICFactory, PerpetualLiquidatblePoolParty, PerpetualPoolPartyLib, PoolFactory, PoolLib)

Environment

Operating System: Ubuntu 18.04.5 LTS
Truffle version (truffle version): 5.1.49
node version (node --version): 14.9.0
yarn version (yarn --version): 1.22.4

@alcuadrado
Copy link
Member

Hey @Aleione,

Truffle and Hardhat use different artifacts structures. Hardhat's artifacts are mostly compatible with Truffle, but there's no strong guarantee of full compatibility. How are you comparing them?

@Aleione
Copy link
Author

Aleione commented Jan 5, 2021

I compare the two artifacts for a same contracts. I extract the deployed bytecode field from the artifacts and i compare the two bytecodes. And there are some differences. I have compared using both git diff and winMerge

@fvictorio
Copy link
Member

@Aleione where is the source for the getHardhatConfig that you get from the @jarvis-network/uma-common package? I would like to see the full hardhat configuration.

@alcuadrado
Copy link
Member

I compare the two artifacts for a same contracts. I extract the deployed bytecode field from the artifacts and i compare the two bytecodes. And there are some differences. I have compared using both git diff and winMerge

Can you post them here?

@Aleione
Copy link
Author

Aleione commented Jan 6, 2021

@cameel
Copy link

cameel commented Jan 11, 2021

@Aleione Are you sure you're using the same compiler version in both cases?

One difference that immediately stands out when you look at these files is that the output from Hardhat one has new-style linker references (which look like this: __$4f581643aba88594584518c6bd09698d13$__) while Truffle output has old-style ones (__PerpetualPositionManagerPoolPartyLib__). Your HardhatConfig.js has const solcVersion = "0.6.12" and your contracts have pragmas with that version but solc stopped producing the old-style references in 0.5.0. I'd say that your Truffle install must be using some ancient solc version but if this was the case, it would not compile at all due to pragmas.

Are you perhaps comparing with some older build output from Truffle? The bytecode is not stable between solc versions (even the minor releases). If you want to reproduce the bytecode, you have to use the same exact compiler version.

@Aleione
Copy link
Author

Aleione commented Jan 23, 2021

@cameel The compiler version, runs, optimizer and EVM version are the same. You can check in build folder (truffle) and artifact folder (hardhat) this infos, and check that are the same. The difference in library links are independent from the mismatch. You can see the mismatch also in TICHelper contract that does not include any reference with external libraries.

@PaulRBerg
Copy link
Contributor

@cameel
Copy link

cameel commented Dec 16, 2021

This unfortunately seems to be a bug in the compiler. Recently we got two issues with enough input that we could actually reproduce and investigate the problem (ethereum/solidity#12281, ethereum/solidity#12415) and it turns out that 0.6.12 and 0.7.0 can output different bytecode with the same metadata.

The problem only occurs if the sets of files you're compiling are not identical in both cases. When using a framework like Truffle or Hardhat this usually means that to reproduce the bytecode you need to include all the input files from your project, not just those that are actually used by the contract you want to reproduce. For example omitting Migrations.sol from Truffle might be enough to trigger it. The problem does not exist on solc 0.7.1 and newer.

@alcuadrado
Copy link
Member

Thanks for the update, @cameel. Is this bug also present if you don't use the optimizer?

@cameel
Copy link

cameel commented Dec 17, 2021

I think it isn't. I have only seen it happen with optimizer enabled. The differences in the bytecode all seem to come from different decisions made by the optimizer. Probably because things are sorted differently and processed in a different order.

@alcuadrado
Copy link
Member

That matches with our experience and this other issue.

I'm also seen the same happen when the name of top-level/entry-point files change. For example, if you have a file A.sol that imports lib/L.sol, which can have files with relative imports, renaming lib/L.sol to something like lib2/L.sol can lead to different compilation outputs. My suspicion is that it has to do with some kind of sorting and how it alters the optimizer's decisions.

@fvictorio
Copy link
Member

Hardhat has a workaround for the solc versions affected by this bug, so I'm closing this.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

5 participants