Skip to content

Commit

Permalink
Mask Immutables in Local Verify Task (#691)
Browse files Browse the repository at this point in the history
Fixes #689

The local verification task does not work correctly for contracts with
`immutable`s. This is because, `immutable` values get written when the
contract's init code executes on-chain, but uses `0` place holders in
the `deployedBytecode` compiler output.

This causes the code that is fetched from the deployed contract to
differ slightly from the compiler's byte code output (fetched code has
non-0 `immutable` values, while the compiler output has 0 `immutable`
values).

The fix is to mask the `immutable`s from the fetched code with 0's
before comparing.

With this fix, `local-verify` script now works for the
`SimulateTxAccessor` contract:

```
$ npx hardhat local-verify --network localhost
Verification status for CompatibilityFallbackHandler: SUCCESS
Verification status for CreateCall: SUCCESS
Verification status for MultiSend: SUCCESS
Verification status for MultiSendCallOnly: SUCCESS
Verification status for Safe: SUCCESS
Verification status for SafeL2: SUCCESS
Verification status for SafeProxyFactory: SUCCESS
Verification status for SignMessageLib: SUCCESS
Verification status for SimulateTxAccessor: SUCCESS
Verification status for TokenCallbackHandler: SUCCESS
```
  • Loading branch information
nlordell authored Nov 1, 2023
1 parent 357f55e commit fd05d21
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/tasks/local_verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,31 @@ task("local-verify", "Verifies that the local deployment files correspond to the
delete meta.compiler;
delete meta.output;
delete meta.version;
const sources = Object.values<any>(meta.sources);
const sources = Object.values<Record<string, unknown>>(meta.sources);
for (const source of sources) {
for (const key of Object.keys(source)) {
if (allowedSourceKey.indexOf(key) < 0) delete source[key];
}
}
meta.settings.outputSelection = {};
const targets = Object.entries(meta.settings.compilationTarget);
const targets = Object.entries<string>(meta.settings.compilationTarget);
for (const [key, value] of targets) {
meta.settings.outputSelection[key] = {};
meta.settings.outputSelection[key][value as string] = ["evm.bytecode", "evm.deployedBytecode", "metadata"];
meta.settings.outputSelection[key][value] = ["evm.deployedBytecode.object", "evm.deployedBytecode.immutableReferences"];
}
delete meta.settings.compilationTarget;
const compiled = solcjs.compile(JSON.stringify(meta));
const output = JSON.parse(compiled);
for (const [key, value] of targets) {
const compiledContract = output.contracts[key][value as string];
const onChainCode = await hre.ethers.provider.getCode(deployment.address);
const compiledContract = output.contracts[key][value];
const onChainCode = hre.ethers.getBytes(await hre.ethers.provider.getCode(deployment.address));
for (const references of Object.values<{ start: number; length: number }[]>(
compiledContract.evm.deployedBytecode.immutableReferences,
)) {
for (const { start, length } of references) {
onChainCode.fill(0, start, start + length);
}
}
const onchainBytecodeHash = hre.ethers.keccak256(onChainCode);
const localBytecodeHash = hre.ethers.keccak256(`0x${compiledContract.evm.deployedBytecode.object}`);
const verifySuccess = onchainBytecodeHash === localBytecodeHash ? "SUCCESS" : "FAILURE";
Expand Down

0 comments on commit fd05d21

Please sign in to comment.