From 4c0e566a9d6274c21d008e99374311ffac005c6e Mon Sep 17 00:00:00 2001 From: Raid5594 <52794079+Raid5594@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:36:17 +0200 Subject: [PATCH 01/42] extend utils & update compilation process (#396) Co-authored-by: Raid Ateir --- .gitignore | 1 + system-contracts/package.json | 2 +- system-contracts/scripts/compile-yul.ts | 44 +++++++++-- .../scripts/preprocess-system-contracts.ts | 14 ++++ system-contracts/scripts/utils.ts | 73 +++++++++++++++++++ 5 files changed, 127 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 356147e7b..6cb7fef4f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ l1-contracts/out/* l1-contracts-foundry/broadcast/* l1-contracts-foundry/script-out/* !l1-contracts-foundry/script-out/.gitkeep +*.timestamp diff --git a/system-contracts/package.json b/system-contracts/package.json index aed76a397..ca1d7490e 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -62,7 +62,7 @@ "compile-zasm": "ts-node scripts/compile-zasm.ts", "deploy-preimages": "ts-node scripts/deploy-preimages.ts", "preprocess:bootloader": "rm -rf ./bootloader/build && yarn ts-node scripts/preprocess-bootloader.ts", - "preprocess:system-contracts": "rm -rf ./contracts-preprocessed && ts-node scripts/preprocess-system-contracts.ts", + "preprocess:system-contracts": "ts-node scripts/preprocess-system-contracts.ts", "test": "yarn build:test-system-contracts && hardhat test --network zkSyncTestNode", "test-node": "hardhat node-zksync --tag v0.0.1-vm1.5.0", "test:bootloader": "cd bootloader/test_infra && cargo run" diff --git a/system-contracts/scripts/compile-yul.ts b/system-contracts/scripts/compile-yul.ts index 589a3a8ea..6c75cf3ef 100644 --- a/system-contracts/scripts/compile-yul.ts +++ b/system-contracts/scripts/compile-yul.ts @@ -1,11 +1,23 @@ // hardhat import should be the first import in the file import type { CompilerPaths } from "./utils"; -import { spawn, compilerLocation, prepareCompilerPaths, getSolcLocation } from "./utils"; +import { + spawn, + compilerLocation, + prepareCompilerPaths, + getSolcLocation, + needsRecompilation, + setCompilationTime, +} from "./utils"; import * as fs from "fs"; import { Command } from "commander"; +import * as _path from "path"; const COMPILER_VERSION = "1.3.18"; const IS_COMPILER_PRE_RELEASE = true; +const CONTRACTS_DIR = "contracts-preprocessed"; +const BOOTLOADER_DIR = "bootloader"; +const TIMESTAMP_FILE_YUL = "last_compilation_yul.timestamp"; +const TIMESTAMP_FILE_BOOTLOADER = "last_compilation_bootloader.timestamp"; export async function compileYul(paths: CompilerPaths, file: string) { const solcCompilerPath = await getSolcLocation(); @@ -30,14 +42,34 @@ async function main() { program.version("0.1.0").name("compile yul").description("publish preimages for the L2 contracts"); program.command("compile-bootloader").action(async () => { - await compileYulFolder("bootloader/build"); - await compileYulFolder("bootloader/tests"); + const timestampFilePath = _path.join(process.cwd(), TIMESTAMP_FILE_BOOTLOADER); + const folderToCheck = _path.join(process.cwd(), BOOTLOADER_DIR); + + if (needsRecompilation(folderToCheck, timestampFilePath)) { + console.log("Compilation needed."); + await compileYulFolder("bootloader/build"); + await compileYulFolder("bootloader/tests"); + setCompilationTime(timestampFilePath); + } else { + console.log("Compilation not needed."); + return; + } }); program.command("compile-precompiles").action(async () => { - await compileYulFolder("contracts-preprocessed"); - await compileYulFolder("contracts-preprocessed/precompiles"); - await compileYulFolder("contracts-preprocessed/precompiles/test-contracts"); + const timestampFilePath = _path.join(process.cwd(), TIMESTAMP_FILE_YUL); + const folderToCheck = _path.join(process.cwd(), CONTRACTS_DIR); + + if (needsRecompilation(folderToCheck, timestampFilePath)) { + console.log("Compilation needed."); + await compileYulFolder("contracts-preprocessed"); + await compileYulFolder("contracts-preprocessed/precompiles"); + await compileYulFolder("contracts-preprocessed/precompiles/test-contracts"); + setCompilationTime(timestampFilePath); + } else { + console.log("Compilation not needed."); + return; + } }); await program.parseAsync(process.argv); diff --git a/system-contracts/scripts/preprocess-system-contracts.ts b/system-contracts/scripts/preprocess-system-contracts.ts index acecee1ac..0b3690a9e 100644 --- a/system-contracts/scripts/preprocess-system-contracts.ts +++ b/system-contracts/scripts/preprocess-system-contracts.ts @@ -3,9 +3,11 @@ import path from "path"; import { renderFile } from "template-file"; import { glob } from "fast-glob"; import { Command } from "commander"; +import { needsRecompilation, deleteDir, setCompilationTime, isFolderEmpty } from "./utils"; const CONTRACTS_DIR = "contracts"; const OUTPUT_DIR = "contracts-preprocessed"; +const TIMESTAMP_FILE = "last_compilation_preprocessing.timestamp"; // File to store the last compilation time const params = { SYSTEM_CONTRACTS_OFFSET: "0x8000", @@ -17,6 +19,18 @@ async function preprocess(testMode: boolean) { params.SYSTEM_CONTRACTS_OFFSET = "0x9000"; } + const timestampFilePath = path.join(process.cwd(), TIMESTAMP_FILE); + const folderToCheck = path.join(process.cwd(), CONTRACTS_DIR); + + if ((await isFolderEmpty(OUTPUT_DIR)) || needsRecompilation(folderToCheck, timestampFilePath) || testMode) { + console.log("Preprocessing needed."); + deleteDir(OUTPUT_DIR); + setCompilationTime(timestampFilePath); + } else { + console.log("Preprocessing not needed."); + return; + } + const contracts = await glob( [`${CONTRACTS_DIR}/**/*.sol`, `${CONTRACTS_DIR}/**/*.yul`, `${CONTRACTS_DIR}/**/*.zasm`], { onlyFiles: true } diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts index 3a4e7bad4..3314abb83 100644 --- a/system-contracts/scripts/utils.ts +++ b/system-contracts/scripts/utils.ts @@ -7,6 +7,7 @@ import type { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import type { BigNumberish, BytesLike } from "ethers"; import { BigNumber, ethers } from "ethers"; import * as fs from "fs"; +import * as fsPr from "fs/promises"; import { hashBytecode } from "zksync-web3/build/src/utils"; import type { YulContractDescription, ZasmContractDescription } from "./constants"; import { Language, SYSTEM_CONTRACTS } from "./constants"; @@ -253,3 +254,75 @@ export function prepareCompilerPaths(path: string): CompilerPaths { return new CompilerPaths(absolutePathSources, absolutePathArtifacts); } + +// Get the latest file modification time in the watched folder +function getLatestModificationTime(folder: string): Date | null { + const files = fs.readdirSync(folder); + let latestTime: Date | null = null; // Initialize to null to avoid uninitialized variable + + files.forEach((file) => { + const filePath = path.join(folder, file); + const stats = fs.statSync(filePath); + if (stats.isDirectory()) { + const dirLatestTime = getLatestModificationTime(filePath); + if (dirLatestTime && (!latestTime || dirLatestTime > latestTime)) { + latestTime = dirLatestTime; + } + } else if (stats.isFile()) { + if (!latestTime || stats.mtime > latestTime) { + latestTime = stats.mtime; + } + } + }); + + return latestTime; +} + +// Read the last compilation timestamp from the file +export function getLastCompilationTime(timestampFile: string): Date | null { + try { + if (fs.existsSync(timestampFile)) { + const timestamp = fs.readFileSync(timestampFile, "utf-8"); + return new Date(parseInt(timestamp, 10)); + } + } catch (error) { + const err = error as Error; // Cast `error` to `Error` + console.error(`Error reading timestamp: ${err.message}`); + } + return null; +} + +// Write the current time to the timestamp file +export function setCompilationTime(timestampFile: string) { + fs.writeFileSync(timestampFile, Date.now().toString()); +} + +// Determine if recompilation is needed +export function needsRecompilation(folder: string, timestampFile: string): boolean { + const lastCompilationTime = getLastCompilationTime(timestampFile); + const latestModificationTime = getLatestModificationTime(folder); + if (!lastCompilationTime) { + return true; // If there's no history, always recompile + } + + return latestModificationTime! > lastCompilationTime; +} + +export function deleteDir(path: string): void { + try { + fs.rmSync(path, { recursive: true, force: true }); // 'recursive: true' deletes all contents, 'force: true' prevents errors if the directory doesn't exist + console.log(`Directory '${path}' deleted successfully.`); + } catch (error) { + console.error(`Error deleting directory '${path}':`, error); + } +} + +export async function isFolderEmpty(folderPath: string): Promise { + try { + const files = await fsPr.readdir(folderPath); // Get a list of files in the folder + return files.length === 0; // If there are no files, the folder is empty + } catch (error) { + console.error("No target folder with artifacts."); + return true; // Return true if an error, as folder doesn't exist. + } +} From 360164871658e7765fadaeadd800e36191afc074 Mon Sep 17 00:00:00 2001 From: Neo <128649481+neotheprogramist@users.noreply.github.com> Date: Thu, 16 May 2024 13:33:17 +0200 Subject: [PATCH 02/42] NonceHolder Tests (#176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Uacias Co-authored-by: Mateusz Zając Co-authored-by: Mateusz Zając <60236390+matzayonc@users.noreply.github.com> --- system-contracts/test/NonceHolder.spec.ts | 257 ++++++++++++++++++++++ system-contracts/test/shared/mocks.ts | 2 + 2 files changed, 259 insertions(+) create mode 100644 system-contracts/test/NonceHolder.spec.ts diff --git a/system-contracts/test/NonceHolder.spec.ts b/system-contracts/test/NonceHolder.spec.ts new file mode 100644 index 000000000..91e9e3ba4 --- /dev/null +++ b/system-contracts/test/NonceHolder.spec.ts @@ -0,0 +1,257 @@ +import { expect } from "chai"; +import type { NonceHolder } from "../typechain"; +import { NonceHolderFactory } from "../typechain"; +import { + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, + TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS, +} from "./shared/constants"; +import { prepareEnvironment, setResult } from "./shared/mocks"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; +import { ethers, network } from "hardhat"; +import { BigNumber } from "ethers"; + +describe("NonceHolder tests", () => { + const wallet = getWallets()[0]; + let nonceHolder: NonceHolder; + let systemAccount: ethers.Signer; + let deployerAccount: ethers.Signer; + + before(async () => { + await prepareEnvironment(); + await deployContractOnAddress(TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, "NonceHolder"); + nonceHolder = NonceHolderFactory.connect(TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, wallet); + + // Using a system account to satisfy the `onlySystemCall` modifier. + systemAccount = await ethers.getImpersonatedSigner(TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS); + deployerAccount = await ethers.getImpersonatedSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + }); + + after(async () => { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS], + }); + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS], + }); + }); + + describe("increaseMinNonce and getters", () => { + it("should increase account minNonce by 1", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).increaseMinNonce(1); + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceAfter).to.equal(nonceBefore.add(1)); + expect(rawNonceAfter).to.equal(rawNonceBefore.add(1)); + }); + + it("should stay the same", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).increaseMinNonce(0); + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceBefore).to.equal(nonceAfter); + expect(rawNonceBefore).to.equal(rawNonceAfter); + }); + + it("should increase account minNonce by many", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).increaseMinNonce(2 ** 4); + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceAfter).to.equal(nonceBefore.add(2 ** 4)); + expect(rawNonceAfter).to.equal(rawNonceBefore.add(2 ** 4)); + }); + + it("should fail with too high", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + + await expect( + nonceHolder.connect(systemAccount).increaseMinNonce(BigNumber.from(2).pow(32).add(1)) + ).to.be.rejectedWith("The value for incrementing the nonce is too high"); + + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceAfter).to.equal(nonceBefore); + expect(rawNonceAfter).to.equal(rawNonceBefore); + }); + + it("should revert This method require system call flag", async () => { + await expect(nonceHolder.increaseMinNonce(123)).to.be.rejectedWith("This method require system call flag"); + }); + }); + + describe("incrementMinNonceIfEquals", async () => { + it("should revert This method require system call flag", async () => { + const expectedNonce = await nonceHolder.getMinNonce(systemAccount.address); + await expect(nonceHolder.incrementMinNonceIfEquals(expectedNonce)).to.be.rejectedWith( + "This method require system call flag" + ); + }); + + it("should revert Incorrect nonce", async () => { + await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.rejectedWith( + "Incorrect nonce" + ); + }); + + it("should increment minNonce if equals to expected", async () => { + const expectedNonce = await nonceHolder.getMinNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(expectedNonce); + const result = await nonceHolder.getMinNonce(systemAccount.address); + expect(result).to.equal(expectedNonce.add(1)); + }); + }); + + describe("incrementDeploymentNonce", async () => { + it("should revert Only the contract deployer can increment the deployment nonce", async () => { + await expect(nonceHolder.incrementDeploymentNonce(deployerAccount.address)).to.be.rejectedWith( + "Only the contract deployer can increment the deployment nonce" + ); + }); + + it("should increment deployment nonce", async () => { + const nonceBefore = await nonceHolder.getDeploymentNonce(wallet.address); + const rawNonceBefore = await nonceHolder.getRawNonce(wallet.address); + await nonceHolder.connect(deployerAccount).incrementDeploymentNonce(wallet.address); + const nonceAfter = await nonceHolder.getDeploymentNonce(wallet.address); + const rawNonceAfter = await nonceHolder.getRawNonce(wallet.address); + + expect(nonceAfter).to.equal(nonceBefore.add(BigNumber.from(1))); + expect(rawNonceAfter).to.equal(rawNonceBefore.add(BigNumber.from(2).pow(128))); + }); + }); + + describe("setValueUnderNonce and getValueUnderNonce", async () => { + it("should revert Nonce value cannot be set to 0", async () => { + const accountInfo = [1, 0]; + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [accountInfo]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(124, 0)).to.be.rejectedWith( + "Nonce value cannot be set to 0" + ); + }); + + it("should revert Previous nonce has not been used", async () => { + const accountInfo = [1, 0]; + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [accountInfo]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(443, 111)).to.be.rejectedWith( + "Previous nonce has not been used" + ); + }); + + it("should emit ValueSetUnderNonce event", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const valueBefore = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce); + const value = valueBefore.add(42); + + const accountInfo = [1, 0]; + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [accountInfo]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce, value)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce, value); + + const valueAfter = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce); + expect(valueAfter).to.equal(value); + }); + + it("should emit ValueSetUnderNonce event arbitrary ordering", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [[1, 1]]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + + const firstValue = (await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce)).add(111); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce, firstValue)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce, firstValue); + + const secondValue = (await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(2))).add(333); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce.add(2), secondValue)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce.add(2), secondValue); + + const thirdValue = (await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(1))).add(222); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce.add(1), thirdValue)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce.add(1), thirdValue); + + const storedValue = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce); + expect(storedValue).to.equal(firstValue); + const storedValueNext = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(1)); + expect(storedValueNext).to.equal(thirdValue); + const storedAfterNext = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(2)); + expect(storedAfterNext).to.equal(secondValue); + }); + }); + + describe("isNonceUsed", () => { + it("used nonce because it too small", async () => { + const isUsed = await nonceHolder.isNonceUsed(systemAccount.address, 1); + expect(isUsed).to.equal(true); + }); + + it("used nonce because set", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const checkedNonce = currentNonce.add(1); + await nonceHolder.connect(systemAccount).setValueUnderNonce(checkedNonce, 5); + + const isUsed = await nonceHolder.isNonceUsed(systemAccount.address, checkedNonce); + expect(isUsed).to.equal(true); + }); + + it("not used nonce", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const checkedNonce = currentNonce.add(2137 * 2 ** 10); + + const isUsed = await nonceHolder.isNonceUsed(systemAccount.address, checkedNonce); + expect(isUsed).to.be.false; + }); + }); + + describe("validateNonceUsage", () => { + it("used nonce & should not be used", async () => { + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 1, false)).to.be.rejectedWith( + "Reusing the same nonce twice" + ); + }); + + it("used nonce & should be used", async () => { + await nonceHolder.validateNonceUsage(systemAccount.address, 1, true); + }); + + it("not used nonce & should be used", async () => { + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, true)).to.be.rejectedWith( + "The nonce was not set as used" + ); + }); + + it("not used nonce & should not be used", async () => { + await nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, false); + }); + }); +}); diff --git a/system-contracts/test/shared/mocks.ts b/system-contracts/test/shared/mocks.ts index 2b8c35654..4dd51671e 100644 --- a/system-contracts/test/shared/mocks.ts +++ b/system-contracts/test/shared/mocks.ts @@ -2,6 +2,7 @@ import { ethers } from "hardhat"; import type { MockContract } from "../../typechain"; import { MockContractFactory } from "../../typechain"; import { + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, TEST_BOOTLOADER_FORMAL_ADDRESS, TEST_BASE_TOKEN_SYSTEM_CONTRACT_ADDRESS, @@ -26,6 +27,7 @@ type CallResult = { const TEST_SYSTEM_CONTRACTS_MOCKS = { Compressor: TEST_COMPRESSOR_CONTRACT_ADDRESS, SystemContext: TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS, + ContractDeployer: TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, NonceHolder: TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, L1Messenger: TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, KnownCodesStorage: TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, From 2840540271838df29351ce7e5b7e033431b6c0a1 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 09:55:30 -0400 Subject: [PATCH 03/42] chore(scripts): remove unconditionally removed facets (#448) --- .github/workflows/slither.yaml | 4 +++- l1-contracts/src.ts/diamondCut.ts | 8 +------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/slither.yaml b/.github/workflows/slither.yaml index 652822dfd..fa253e159 100644 --- a/.github/workflows/slither.yaml +++ b/.github/workflows/slither.yaml @@ -43,4 +43,6 @@ jobs: rm -rf ./l1-contracts/contracts/dev-contracts/test/VerifierRecursiveTest.sol - name: Run Slither - run: slither --config ./l1-contracts/slither.config.json ./l1-contracts + run: | + cd l1-contracts + slither --config ./slither.config.json . diff --git a/l1-contracts/src.ts/diamondCut.ts b/l1-contracts/src.ts/diamondCut.ts index f9eaadf0e..c2a8e8728 100644 --- a/l1-contracts/src.ts/diamondCut.ts +++ b/l1-contracts/src.ts/diamondCut.ts @@ -6,9 +6,6 @@ import { ethers } from "ethers"; import { IZkSyncHyperchainFactory } from "../typechain/IZkSyncHyperchainFactory"; import { IZkSyncHyperchainBaseFactory } from "../typechain/IZkSyncHyperchainBaseFactory"; -// Some of the facets are to be removed with the upcoming upgrade. -const UNCONDITIONALLY_REMOVED_FACETS = ["DiamondCutFacet", "GovernanceFacet"]; - export enum Action { Add = 0, Replace = 1, @@ -131,10 +128,7 @@ export async function getFacetCutsForUpgrade( namesOfFacetsToBeRemoved?: string[] ) { const newFacetCuts = await getCurrentFacetCutsForAdd(adminAddress, gettersAddress, mailboxAddress, executorAddress); - namesOfFacetsToBeRemoved = namesOfFacetsToBeRemoved || [ - ...UNCONDITIONALLY_REMOVED_FACETS, - ...Object.keys(newFacetCuts), - ]; + namesOfFacetsToBeRemoved = namesOfFacetsToBeRemoved || [...Object.keys(newFacetCuts)]; const oldFacetCuts = await getDeployedFacetCutsForRemove(wallet, zkSyncAddress, namesOfFacetsToBeRemoved); return [...oldFacetCuts, ...Object.values(newFacetCuts)]; } From 622638a43ecee3211b01ab3e43952b7705f5955b Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 09:59:09 -0400 Subject: [PATCH 04/42] chore(contracts): remove usage of ergs (#454) --- l2-contracts/src/upgrade-bridge-impl.ts | 2 +- system-contracts/SystemContractsHashes.json | 54 +++++++++---------- system-contracts/contracts/Constants.sol | 2 +- system-contracts/contracts/GasBoundCaller.sol | 4 +- .../test-contracts/GasBoundCallerTester.sol | 4 +- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/l2-contracts/src/upgrade-bridge-impl.ts b/l2-contracts/src/upgrade-bridge-impl.ts index 99c7475c7..af21fbac0 100644 --- a/l2-contracts/src/upgrade-bridge-impl.ts +++ b/l2-contracts/src/upgrade-bridge-impl.ts @@ -352,7 +352,7 @@ async function main() { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT ); - console.log(`Base cost for priority tx with max ergs: ${ethers.utils.formatEther(neededValue)} ETH`); + console.log(`Base cost for priority tx with max gas: ${ethers.utils.formatEther(neededValue)} ETH`); }); await program.parseAsync(process.argv); diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index eeb4a80f3..79fba0a88 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,49 +3,49 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x0100007549287362e4263ea5b204f01fc3c7f2ac09d71e6eb21029698220f01a", + "bytecodeHash": "0x01000075076d9e9ca73d51f8ef0af1bb2e7f74fd8377876ab6bc470a2900a4bf", "sourceCodeHash": "0xfbf66e830201c4b7fda14f0ddf28a53beb7fbb48a8406392bcfd0ef7ea9265c8" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007d1e53f2dca05f7e27ae5b7062291ed3a1470ca511140b8e786aae7eb77", + "bytecodeHash": "0x010007d1e60e441b0b776e8f6b1c8a9e0fdd787a944a9d851cd093a3b65b3daa", "sourceCodeHash": "0x9ff5a2da00acfa145ee4575381ad386587d96b6a0309d05015974f4726881132" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x01000055c1f27b8316ba61bf07959b11cf3b2a418aa357ccc5531c0914a2da27", + "bytecodeHash": "0x0100005576cef4b90577db7ca2e5cc02340a0b56ee9473b34756502963551a97", "sourceCodeHash": "0x0aa5d7ed159e783acde47856b13801b7f2268ba39b2fa50807fe3d705c506e96" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x01000179842b5aa1c76036f5b90652fe614dacb28438a89649d6ca48131bd402", + "bytecodeHash": "0x0100017924bee877f2ab925cfb1c161ef3c19a8a3034da5d4fd76d0c377a3749", "sourceCodeHash": "0xd43ac120a50398e0d6bdcfcf807154bfeece0c231509a0eb2e00bcad744e60cd" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010005215fda00bfbf95847a13078bd16cdcb1b875534261c1dda9940c7754fe", + "bytecodeHash": "0x010005217819daf0124b7ccb96aca43053d0d13c0c8ad8ae7568d811eecbc3bf", "sourceCodeHash": "0x635301b824f927b4d17b3d9974cf6abbf979dda49e610805637db7c677d5f522" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x0100004bc85f45ebf0f0bf004752bcbff1bb99792d6cc6494227970ec77fe53b", + "bytecodeHash": "0x0100004b3ac74b1706466d4b2f2b401addad6f17fabb7c8b979cea2fe700cbaf", "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32", + "bytecodeHash": "0x01000563e438856e95e453dd4380fbcbb2d8657320ebe7b067f88d7e7898d6bb", "sourceCodeHash": "0xa42423712ddaa8f357d26e46825fda80a9a870d0ac7ff52c98884355f1173ec7" }, { @@ -59,63 +59,63 @@ "contractName": "GasBoundCaller", "bytecodePath": "artifacts-zk/contracts-preprocessed/GasBoundCaller.sol/GasBoundCaller.json", "sourceCodePath": "contracts-preprocessed/GasBoundCaller.sol", - "bytecodeHash": "0x010000b5e930829f22bd5df4fac3cb37b599cf9733554124bfb7e717fa4a726b", - "sourceCodeHash": "0x68db837d79ab575450f9123d97c7e566f311fb2e8d91c0d43dc9769ca895ccd3" + "bytecodeHash": "0x010000b51b2bae505be6deb2294505457c6e8df65d6b8d08f32d0d85f8610c60", + "sourceCodeHash": "0xd6877ecfd598bcf8abe26ec344949ae8f992d9a8ab1ac8d529a21da521f77923" }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003de00c5ceaa3fdf4566a9822ce94abe676f68b17a6ae11c453e14455fd", + "bytecodeHash": "0x0100003dc7171a0acf2c4290f0ed222e9d2496b02a47202862e2b2dc70436c4a", "sourceCodeHash": "0x30df621c72cb35b8820b902b91057f72d0214a0e4a6b7ad4c0847e674e8b9df8" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100007d82d4a2eb62e539e3c89cc641f507132b247022ba05ef1ddfed2b0073", + "bytecodeHash": "0x0100007d6f907a56f64d3c054ae5e4a8f73499e1d9fdfea09684fc9de9542941", "sourceCodeHash": "0x51d388adc58f67ef975a94a7978caa60ed8a0df9d3bd9ac723dfcfc540286c70" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002b97ebf3c481ead775617590ffca139bee428e443aa49eb38b6a5b83657", + "bytecodeHash": "0x010002b9ed3fe658cc5fbc4c2d8b4b5325f47a417f9df02e7dba4360f290141c", "sourceCodeHash": "0x35c189f3babf5c7a9ce2590bed9eb62b59766e358b7733fdb1bc33f4c232f765" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x010001039329e4bb55b24531c7e7d27ed40d2c82ad145033fdd5ed5b8ea86cf3", + "bytecodeHash": "0x010001035dc295d66d39f6f5ae560801400c6ac1141fd1556acabff84c79c22c", "sourceCodeHash": "0x76ac95c12820d9a02cd1f177eab59092d99463816f2616e1e0f44637bf791a43" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x010000695a1e821b6d5fcb25e25793b81de0bdca3ff8277e3ac93a38e729e0a1", + "bytecodeHash": "0x01000069227f9b9d7666a4fc7ac51a280f33fd92021f2e8f06a2d5a458930563", "sourceCodeHash": "0x3f9e0af527875bebcdc20ca4ecb6822305877fd6038e4c4c58854d000b9ac115" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000e563d4ad7b4822cc19d8f74f2c41ee3d3153379be4b02b27d4498d52b6", + "bytecodeHash": "0x010000e5e7614688d2be15699477b56c66e3596a16b60c206f3c3e8a4763e6b4", "sourceCodeHash": "0x91847512344ac5026e9fd396189c23ad9e253f22cb6e2fe65805c20c915797d4" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x01000049eb6d79244e74e5286ed4d3f6eef2b5eb746b67d98691dbc28fa16984", + "bytecodeHash": "0x01000049d12af64a260c7dbfa32b778e60fe6793b73d50388cfdb0d38df4a97c", "sourceCodeHash": "0xbc62d673c2cf9ba2d2148e5e2f99ea577cd357c6fd3ad7d248f670c750050faa" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001b3f2c3a6bdd5ad00ae29a7cbbb32dca3c31fb608b5cd52f8f3056a3847", + "bytecodeHash": "0x010001b38acd12ee43d880840d48bd0474c519a8076cf28c8930489117e9bc73", "sourceCodeHash": "0xb90284d78f48a958d082c4c877fc91ec292d05f0e388c6c78e6cce6d3b069a63" }, { @@ -185,35 +185,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb722f6b3ac4928fadcb3ad05bb76a7e2497a5635efffb7bbc40f23d29", - "sourceCodeHash": "0x818032f314539edf7b5569c70099f27e2336199ce24313a3f1968e27082c18ae" + "bytecodeHash": "0x010003cb38a53b3466209bf803fc2cacd06f9dc4ff9b123a38f6ba41928f735b", + "sourceCodeHash": "0xd5b248e75ad4a0a433c47de88b5a6eb30c3b7b540e0a716e953c07903233c2d1" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x01000951a10ba35cd1fd7ea05039e53a06037213a162e6a3cfddf81ff6e54ad5", - "sourceCodeHash": "0x2cadacf92b4db89ecd699426b769526e5482e565d6d86ed287c9cc36cfe2cc2f" + "bytecodeHash": "0x010009519002105dd21a44bde50b697ffbc607baf3196d2eac80ad06f99e0f4c", + "sourceCodeHash": "0xbecdcccce351008db583c0447c7e1c7e8c69b5806abee65f22119e699e908e9d" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d750d8f3fa01d99a747a5113d133594b72f26f0dce3243b225f5b91f9a", - "sourceCodeHash": "0x9a3aead2fe745861da43b8f43028821f7d592ffd16da70f38af19d3b24ae5ef7" + "bytecodeHash": "0x010008d7d5b5c05e49761c406b847fe3ad0db839525b3e4370e9a5b86f2062af", + "sourceCodeHash": "0x533349c05727f117c00727ddcc25814055571afe74827a1d7130b037e131362b" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x010009579942207c3a46a48ad0e66d9f73b6141bb5a2435a8fdce6ee8dfdd17d", - "sourceCodeHash": "0x2302636e39803befa5438f557bfc24b7e1587cfd8edead02dc41a0bb4002f15f" + "bytecodeHash": "0x01000957163c0f203bb8a7d3eda31cd9024e0572d212cdefc3046d740cd35afc", + "sourceCodeHash": "0xcf9c1d03c4d5c087b5c80b2ced7eff33067121a9ae78e1b0ff4b3eba4b5fbe1d" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e7f0f15ed191392960117f88fe371348982b28a033c7207ed2c09bc0f4", - "sourceCodeHash": "0x55ce91a28b1d143ecba38dfe1b64d4877ad8f510256f47e5155fd4fd138840ea" + "bytecodeHash": "0x010008e7d48764fc25121571a4139372fb3dbfd326416ed4bf5c5857cb7affc4", + "sourceCodeHash": "0x5acea8e48b7e840467552341bcf15670856fa5d671614b398e6bd7141052671d" } ] diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index 0f8e2307f..fde7a5de5 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -35,7 +35,7 @@ address constant ECMUL_SYSTEM_CONTRACT = address(0x07); address constant ECPAIRING_SYSTEM_CONTRACT = address(0x08); -/// @dev The number of ergs that need to be spent for a single byte of pubdata regardless of the pubdata price. +/// @dev The number of gas that need to be spent for a single byte of pubdata regardless of the pubdata price. /// This variable is used to ensure the following: /// - That the long-term storage of the operator is compensated properly. /// - That it is not possible that the pubdata counter grows too high without spending proportional amount of computation. diff --git a/system-contracts/contracts/GasBoundCaller.sol b/system-contracts/contracts/GasBoundCaller.sol index d45f64163..67a43883e 100644 --- a/system-contracts/contracts/GasBoundCaller.sol +++ b/system-contracts/contracts/GasBoundCaller.sol @@ -13,10 +13,10 @@ import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; * system contracts have and it can relay call to any contract, breaking potential trust in system contracts. */ contract GasBoundCaller { - /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` ergs are used for the O(1) operations at the start + /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` gas are used for the O(1) operations at the start /// of execution of the contract, such as abi decoding the parameters, jumping to the correct function, etc. uint256 constant CALL_ENTRY_OVERHEAD = 800; - /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` ergs are used for the O(1) operations at the end of the execution, + /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, /// as such relaying the return. uint256 constant CALL_RETURN_OVERHEAD = 200; diff --git a/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol b/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol index 351a55f46..8a86c2e39 100644 --- a/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol +++ b/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol @@ -50,8 +50,8 @@ contract GasBoundCallerTester is GasBoundCaller { lastRecordedGasLeft = gasbefore - gasleft(); } - function spender(uint32 _ergsToBurn, uint32 _pubdataToUse) external { - SystemContractHelper.burnGas(_ergsToBurn, _pubdataToUse); + function spender(uint32 _gasToBurn, uint32 _pubdataToUse) external { + SystemContractHelper.burnGas(_gasToBurn, _pubdataToUse); } function gasBoundCallRelayer( From bd9bec52933fae9a8a84542994a84c88aaf32c56 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 10:26:31 -0400 Subject: [PATCH 05/42] chore(verifier): update generation to include vk hash (#453) --- .../contracts/state-transition/Verifier.sol | 1 + tools/Cargo.lock | 6832 ++++++++++++++++- tools/Cargo.toml | 5 + tools/data/verifier_contract_template.txt | 1 + tools/rust-toolchain | 1 - tools/rust-toolchain.toml | 2 + tools/src/main.rs | 18 +- 7 files changed, 6615 insertions(+), 245 deletions(-) delete mode 100644 tools/rust-toolchain create mode 100644 tools/rust-toolchain.toml diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 861f7e850..4f0b1d043 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -9,6 +9,7 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. /// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. +/// @dev Contract was generated from a verification key with a hash of 0x1d485be42d712856dfe85b3cf7823f020fa5f83cb41c83f9da307fdc2089beee /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: diff --git a/tools/Cargo.lock b/tools/Cargo.lock index 90d7c01b3..da25711f1 100644 --- a/tools/Cargo.lock +++ b/tools/Cargo.lock @@ -3,455 +3,6803 @@ version = 3 [[package]] -name = "ansi_term" -version = "0.12.1" +name = "Inflector" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" dependencies = [ - "winapi", + "lazy_static", + "regex", ] [[package]] -name = "atty" -version = "0.2.14" +name = "addchain" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "num-bigint 0.3.3", + "num-integer", + "num-traits", ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "addr2line" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "cfg-if" -version = "1.0.0" +name = "aes" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] [[package]] -name = "clap" -version = "2.34.0" +name = "aho-corasick" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", + "memchr", ] [[package]] -name = "cpufeatures" -version = "0.2.9" +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] [[package]] -name = "crypto-common" -version = "0.1.6" +name = "ansi_term" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "generic-array", - "typenum", + "winapi", ] [[package]] -name = "digest" -version = "0.10.7" +name = "anstream" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ - "block-buffer", - "crypto-common", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "anstyle" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ - "typenum", - "version_check", + "utf8parse", ] [[package]] -name = "handlebars" -version = "4.4.0" +name = "anstyle-query" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ - "log", - "pest", - "pest_derive", - "serde", - "serde_json", - "thiserror", + "windows-sys 0.52.0", ] [[package]] -name = "heck" -version = "0.3.3" +name = "anstyle-wincon" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ - "unicode-segmentation", + "anstyle", + "windows-sys 0.52.0", ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "anyhow" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arr_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a105bfda48707cf19220129e78fca01e9639433ffaef4163546ed8fb04120a5" dependencies = [ - "libc", + "arr_macro_impl", + "proc-macro-hack", ] [[package]] -name = "itoa" -version = "1.0.9" +name = "arr_macro_impl" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "0609c78bd572f4edc74310dfb63a01f5609d53fa8b4dd7c4d98aef3b3e8d72d1" +dependencies = [ + "proc-macro-hack", + "quote 1.0.33", + "syn 1.0.109", +] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "arrayref" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] -name = "libc" -version = "0.2.148" +name = "arrayvec" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] [[package]] -name = "log" -version = "0.4.20" +name = "arrayvec" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] -name = "memchr" -version = "2.6.3" +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] -name = "once_cell" -version = "1.18.0" +name = "ascii-canvas" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] [[package]] -name = "pest" -version = "2.7.3" +name = "async-trait" +version = "0.1.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ - "memchr", - "thiserror", - "ucd-trie", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", ] [[package]] -name = "pest_derive" -version = "2.7.3" +name = "async_io_stream" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ - "pest", - "pest_generator", + "futures", + "pharos", + "rustc_version", ] [[package]] -name = "pest_generator" -version = "2.7.3" +name = "atty" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.33", + "hermit-abi 0.1.19", + "libc", + "winapi", ] [[package]] -name = "pest_meta" -version = "2.7.3" +name = "auto_impl" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4" dependencies = [ - "once_cell", - "pest", - "sha2", + "proc-macro-error", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "auto_impl" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "autocfg" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", ] [[package]] -name = "proc-macro2" -version = "1.0.67" +name = "axum-core" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ - "unicode-ident", + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", ] [[package]] -name = "quote" -version = "1.0.33" +name = "backtrace" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ - "proc-macro2", + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", ] [[package]] -name = "ryu" -version = "1.0.15" +name = "base16ct" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] -name = "serde" -version = "1.0.188" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" -dependencies = [ - "serde_derive", -] +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] -name = "serde_derive" -version = "1.0.188" +name = "base58" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.33", -] +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" [[package]] -name = "serde_json" -version = "1.0.107" +name = "base58check" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "2ee2fe4c9a0c84515f136aaae2466744a721af6d63339c18689d9e995d74d99b" dependencies = [ - "itoa", - "ryu", - "serde", + "base58", + "sha2 0.8.2", ] [[package]] -name = "sha2" -version = "0.10.7" +name = "base64" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] -name = "strsim" -version = "0.8.0" +name = "base64" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] -name = "structopt" -version = "0.3.26" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "structopt-derive" -version = "0.4.18" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "syn" -version = "1.0.109" +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] -name = "syn" -version = "2.0.33" +name = "bech32" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bellman_ce" +version = "0.3.2" +source = "git+https://github.com/matter-labs/bellman?branch=snark-wrapper#e01e5fa08a97a113e76ec8a69d06fe6cc2c82d17" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "arrayvec 0.7.4", + "bit-vec", + "blake2s_const", + "blake2s_simd", + "byteorder", + "cfg-if 1.0.0", + "crossbeam 0.7.3", + "futures", + "hex", + "lazy_static", + "num_cpus", + "pairing_ce 0.28.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6", + "serde", + "smallvec", + "tiny-keccak 1.5.0", ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "bigdecimal" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ - "unicode-width", + "num-bigint 0.4.5", + "num-integer", + "num-traits", ] [[package]] -name = "thiserror" -version = "1.0.48" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "thiserror-impl", + "serde", ] [[package]] -name = "thiserror-impl" -version = "1.0.48" +name = "bit-set" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.33", + "bit-vec", ] [[package]] -name = "typenum" -version = "1.16.0" +name = "bit-vec" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +dependencies = [ + "serde", +] [[package]] -name = "ucd-trie" -version = "0.1.6" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "bitflags" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] -name = "unicode-segmentation" -version = "1.10.1" +name = "bitvec" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium 0.3.0", +] [[package]] -name = "unicode-width" -version = "0.1.10" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium 0.7.0", + "tap", + "wyz", +] [[package]] -name = "vec_map" -version = "0.8.2" +name = "blake2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +dependencies = [ + "crypto-mac", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e#1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2-rfc_bellman_edition" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc60350286c7c3db13b98e91dbe5c8b6830a6821bc20af5b0c310ce94d74915" +dependencies = [ + "arrayvec 0.4.12", + "byteorder", + "constant_time_eq", +] + +[[package]] +name = "blake2s_const" +version = "0.6.0" +source = "git+https://github.com/matter-labs/bellman?branch=snark-wrapper#e01e5fa08a97a113e76ec8a69d06fe6cc2c82d17" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding 0.1.5", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "boojum" +version = "0.2.0" +source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" +dependencies = [ + "arrayvec 0.7.4", + "bincode", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "const_format", + "convert_case 0.6.0", + "crossbeam 0.8.4", + "crypto-bigint 0.5.5", + "cs_derive", + "derivative", + "ethereum-types", + "firestorm", + "itertools 0.10.5", + "lazy_static", + "num-modular", + "num_cpus", + "packed_simd", + "pairing_ce 0.28.5 (git+https://github.com/matter-labs/pairing.git)", + "rand 0.8.5", + "rayon", + "serde", + "sha2 0.10.8", + "sha3 0.10.6", + "smallvec", + "unroll", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.5", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "circuit_definitions" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.0#39665dffd576cff5007c80dd0e1b5334e230bd3b" +dependencies = [ + "circuit_encodings 0.1.40", + "crossbeam 0.8.4", + "derivative", + "seq-macro", + "serde", + "snark_wrapper", + "zk_evm 1.4.0", + "zkevm_circuits 1.4.0", +] + +[[package]] +name = "circuit_definitions" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.5.0#394e1c7d1aec06d2f3abd63bdc2ddf0efef5ac49" +dependencies = [ + "circuit_encodings 0.1.50", + "crossbeam 0.8.4", + "derivative", + "seq-macro", + "serde", + "snark_wrapper", +] + +[[package]] +name = "circuit_encodings" +version = "0.1.40" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.0#39665dffd576cff5007c80dd0e1b5334e230bd3b" +dependencies = [ + "derivative", + "serde", + "zk_evm 1.4.0", + "zkevm_circuits 1.4.0", +] + +[[package]] +name = "circuit_encodings" +version = "0.1.50" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.5.0#394e1c7d1aec06d2f3abd63bdc2ddf0efef5ac49" +dependencies = [ + "derivative", + "serde", + "zk_evm 1.5.0", + "zkevm_circuits 1.5.0", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "codegen" +version = "0.1.0" +source = "git+https://github.com/matter-labs/solidity_plonk_verifier.git?branch=snark_wrapper#5fb698f5118990bf53648bfd7027363bc4b03ff2" +dependencies = [ + "ethereum-types", + "franklin-crypto", + "handlebars", + "hex", + "paste", + "rescue_poseidon", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "coins-bip32" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634c509653de24b439672164bbf56f5f582a2ab0e313d3b0f6af0b7345cf2560" +dependencies = [ + "bincode", + "bs58", + "coins-core", + "digest 0.10.7", + "getrandom", + "hmac", + "k256 0.11.6", + "lazy_static", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a11892bcac83b4c6e95ab84b5b06c76d9d70ad73548dd07418269c5c7977171" +dependencies = [ + "bitvec 0.17.4", + "coins-bip32", + "getrandom", + "hex", + "hmac", + "pbkdf2", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94090a6663f224feae66ab01e41a2555a8296ee07b5f20dab8888bdefc9f617" +dependencies = [ + "base58check", + "base64 0.12.3", + "bech32", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.7", + "generic-array 0.14.7", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "compile-fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed69047ed42e52c7e38d6421eeb8ceefb4f2a2b52eed59137f7bad7908f6800" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "unicode-xid 0.2.4", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-channel 0.4.4", + "crossbeam-deque 0.7.4", + "crossbeam-epoch 0.8.2", + "crossbeam-queue 0.2.3", + "crossbeam-utils 0.7.2", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel 0.5.12", + "crossbeam-deque 0.8.5", + "crossbeam-epoch 0.9.18", + "crossbeam-queue 0.3.11", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" +dependencies = [ + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch 0.9.18", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-boojum-validator-cli?branch=main#1661eef7b235fc10e92208fb738c9e261f58c653" +dependencies = [ + "anyhow", + "bincode", + "circuit_definitions 0.1.0", + "clap 4.5.4", + "codegen", + "colored", + "ethers", + "hex", + "once_cell", + "primitive-types", + "reqwest", + "serde", + "serde_json", + "sha3 0.9.1", + "tokio", + "zksync_types", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "cs_derive" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid 1.8.0", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7abbfc297053be59290e3152f8cbcd52c8642e0728b69ee187d991d4c1af08d" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bba3e9872d7c58ce7ef0fcf1844fcc3e23ef2a58377b50df35dd98e42a5726e" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", + "unicode-xid 0.2.4", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pem-rfc7468", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "elsa" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "envy" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965" +dependencies = [ + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac", + "pbkdf2", + "rand 0.8.5", + "scrypt", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", + "uuid 0.8.2", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f26f9d8d80da18ca72aca51804c65eb2153093af3bec74fd5ce32aa0c1f665" +dependencies = [ + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-middleware", + "ethers-providers", + "ethers-signers", + "ethers-solc", +] + +[[package]] +name = "ethers-addressbook" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4be54dd2260945d784e06ccdeb5ad573e8f1541838cee13a1ab885485eaa0b" +dependencies = [ + "ethers-core", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "ethers-contract" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c3c3e119a89f0a9a1e539e7faecea815f74ddcf7c90d0b00d1f524db2fdc9c" +dependencies = [ + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "hex", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4e5ad46aede34901f71afdb7bb555710ed9613d88d644245c657dc371aa228" +dependencies = [ + "Inflector", + "cfg-if 1.0.0", + "dunce", + "ethers-core", + "eyre", + "getrandom", + "hex", + "proc-macro2 1.0.82", + "quote 1.0.33", + "regex", + "reqwest", + "serde", + "serde_json", + "syn 1.0.109", + "toml", + "url", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f192e8e4cf2b038318aae01e94e7644e0659a76219e94bcd3203df744341d61f" +dependencies = [ + "ethers-contract-abigen", + "ethers-core", + "hex", + "proc-macro2 1.0.82", + "quote 1.0.33", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "ethers-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" +dependencies = [ + "arrayvec 0.7.4", + "bytes", + "cargo_metadata", + "chrono", + "convert_case 0.6.0", + "elliptic-curve 0.12.3", + "ethabi", + "generic-array 0.14.7", + "hex", + "k256 0.11.6", + "once_cell", + "open-fastrlp", + "proc-macro2 1.0.82", + "rand 0.8.5", + "rlp", + "rlp-derive", + "serde", + "serde_json", + "strum", + "syn 1.0.109", + "thiserror", + "tiny-keccak 2.0.2", + "unicode-xid 0.2.4", +] + +[[package]] +name = "ethers-etherscan" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9713f525348e5dde025d09b0a4217429f8074e8ff22c886263cc191e87d8216" +dependencies = [ + "ethers-core", + "getrandom", + "reqwest", + "semver", + "serde", + "serde-aux", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-middleware" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e71df7391b0a9a51208ffb5c7f2d068900e99d6b3128d3a4849d138f194778b7" +dependencies = [ + "async-trait", + "auto_impl 0.5.0", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-locks", + "futures-util", + "instant", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", +] + +[[package]] +name = "ethers-providers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" +dependencies = [ + "async-trait", + "auto_impl 1.2.0", + "base64 0.13.1", + "ethers-core", + "futures-channel", + "futures-core", + "futures-timer", + "futures-util", + "getrandom", + "hashers", + "hex", + "http", + "once_cell", + "parking_lot 0.11.2", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-timer", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethers-signers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f41ced186867f64773db2e55ffdd92959e094072a1d09a5e5e831d443204f98" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "elliptic-curve 0.12.3", + "eth-keystore", + "ethers-core", + "hex", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "ethers-solc" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbe9c0a6d296c57191e5f8a613a3b5e816812c28f4a28d6178a17c21db903d77" +dependencies = [ + "cfg-if 1.0.0", + "dunce", + "ethers-core", + "getrandom", + "glob", + "hex", + "home", + "md-5", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak 2.0.2", + "tokio", + "tracing", + "walkdir", + "yansi", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff_ce" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b538e4231443a5b9c507caee3356f016d832cf7393d2d90f03ea3180d4e3fbc" +dependencies = [ + "byteorder", + "ff_derive_ce", + "hex", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "ff_derive_ce" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96fbccd88dbb1fac4ee4a07c2fcc4ca719a74ffbd9d2b9d41d8c8eb073d8b20" +dependencies = [ + "num-bigint 0.4.5", + "num-integer", + "num-traits", + "proc-macro2 1.0.82", + "quote 1.0.33", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "firestorm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c5f6c2c942da57e2aaaa84b8a521489486f14e75e7fa91dab70aba913975f98" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "franklin-crypto" +version = "0.0.5" +source = "git+https://github.com/matter-labs/franklin-crypto?branch=snark_wrapper#2546c63b91b59bdb0ad342d26f03fb57477550b2" +dependencies = [ + "arr_macro", + "bellman_ce", + "bit-vec", + "blake2 0.9.2", + "blake2-rfc_bellman_edition", + "blake2s_simd", + "boojum", + "byteorder", + "derivative", + "digest 0.9.0", + "hex", + "indexmap 1.9.3", + "itertools 0.10.5", + "lazy_static", + "num-bigint 0.4.5", + "num-derive", + "num-integer", + "num-traits", + "rand 0.4.6", + "serde", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "splitmut", + "tiny-keccak 1.5.0", +] + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-locks" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" +dependencies = [ + "futures-channel", + "futures-task", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3 0.10.8", +] + +[[package]] +name = "k256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +dependencies = [ + "ascii-canvas", + "bit-set", + "diff", + "ena", + "is-terminal", + "itertools 0.10.5", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.6.29", + "string_cache", + "term", + "tiny-keccak 2.0.2", + "unicode-xid 0.2.4", +] + +[[package]] +name = "lalrpop-util" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +dependencies = [ + "regex", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "linkme" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3ae8aae8e1d516e0a3ceee1219eded7f73741607e4227bf11ef2c3e31580427" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad083d767be37e709a232ae2a244445ed032bb9c6bf7d9442dd416ba5a7b7264" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2 1.0.82", + "quote 1.0.33", + "regex-syntax 0.6.29", + "syn 2.0.33", +] + +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if 1.0.0", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +dependencies = [ + "num-bigint 0.4.5", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint 0.4.5", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.4", + "auto_impl 1.2.0", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-http" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7594ec0e11d8e33faf03530a4c49af7064ebba81c1480e01be67d90b356508b" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry_api", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5e5a5c4135864099f3faafbe939eb4d7f9b80ebf68a8448da961b32a7c1275" +dependencies = [ + "async-trait", + "futures-core", + "http", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry-semantic-conventions", + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "reqwest", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e3f814aa9f8c905d0ee4bde026afd3b2577a97c10e1699912e3e44f0c4cbeb" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9f9340ad135068800e7f1b24e9e09ed9e7143f5bf8518ded3d3ec69789269" +dependencies = [ + "opentelemetry", +] + +[[package]] +name = "opentelemetry_api" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +dependencies = [ + "async-trait", + "crossbeam-channel 0.5.12", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "ordered-float 3.9.2", + "percent-encoding", + "rand 0.8.5", + "regex", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_info" +version = "3.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "packed_simd" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f9f08af0c877571712e2e3e686ad79efad9657dbf0f7c3c8ba943ff6c38932d" +dependencies = [ + "cfg-if 1.0.0", + "num-traits", +] + +[[package]] +name = "pairing_ce" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db007b21259660d025918e653508f03050bf23fb96a88601f9936329faadc597" +dependencies = [ + "byteorder", + "cfg-if 1.0.0", + "ff_ce", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "pairing_ce" +version = "0.28.5" +source = "git+https://github.com/matter-labs/pairing.git#d24f2c5871089c4cd4f54c0ca266bb9fef6115eb" +dependencies = [ + "byteorder", + "cfg-if 1.0.0", + "ff_ce", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec 0.7.4", + "bitvec 1.0.1", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.5.1", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", + "hmac", + "password-hash", + "sha2 0.10.8", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "pest_meta" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2 1.0.82", + "syn 2.0.33", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +dependencies = [ + "dtoa", + "itoa", + "parking_lot 0.12.2", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +dependencies = [ + "bytes", + "prost-derive 0.12.4", +] + +[[package]] +name = "prost-build" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.12.1", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost 0.12.4", + "prost-types", + "regex", + "syn 2.0.33", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "prost-reflect" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057237efdb71cf4b3f9396302a3d6599a92fa94063ba537b66130980ea9909f3" +dependencies = [ + "base64 0.21.7", + "logos", + "miette", + "once_cell", + "prost 0.12.4", + "prost-types", + "serde", + "serde-value", +] + +[[package]] +name = "prost-types" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" +dependencies = [ + "prost 0.12.4", +] + +[[package]] +name = "protox" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bb76c5f6221de491fe2c8f39b106330bbd9762c6511119c07940e10eb9ff11" +dependencies = [ + "bytes", + "miette", + "prost 0.12.4", + "prost-reflect", + "prost-types", + "protox-parse", + "thiserror", +] + +[[package]] +name = "protox-parse" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4581f441c58863525a3e6bec7b8de98188cf75239a56c725a3e7288450a33f" +dependencies = [ + "logos", + "miette", + "prost-types", + "thiserror", +] + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2 1.0.82", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque 0.8.5", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "rescue_poseidon" +version = "0.4.1" +source = "git+https://github.com/matter-labs/rescue-poseidon?branch=poseidon2#126937ef0e7a281f1ff9f512ac41a746a691a342" +dependencies = [ + "addchain", + "arrayvec 0.7.4", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "derivative", + "franklin-crypto", + "lazy_static", + "log", + "num-bigint 0.3.3", + "num-integer", + "num-iter", + "num-traits", + "rand 0.4.6", + "serde", + "sha3 0.9.1", + "smallvec", + "typemap_rev", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +dependencies = [ + "cfg-if 1.0.0", + "derive_more 0.99.17", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2", + "salsa20", + "sha2 0.10.8", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.9", + "generic-array 0.14.7", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "sentry" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce4b57f1b521f674df7a1d200be8ff5d74e3712020ee25b553146657b5377d5" +dependencies = [ + "httpdate", + "native-tls", + "reqwest", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-debug-images", + "sentry-panic", + "sentry-tracing", + "tokio", + "ureq", +] + +[[package]] +name = "sentry-backtrace" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cc8d4e04a73de8f718dc703943666d03f25d3e9e4d0fb271ca0b8c76dfa00e" +dependencies = [ + "backtrace", + "once_cell", + "regex", + "sentry-core", +] + +[[package]] +name = "sentry-contexts" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6436c1bad22cdeb02179ea8ef116ffc217797c028927def303bc593d9320c0d1" +dependencies = [ + "hostname", + "libc", + "os_info", + "rustc_version", + "sentry-core", + "uname", +] + +[[package]] +name = "sentry-core" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901f761681f97db3db836ef9e094acdd8756c40215326c194201941947164ef1" +dependencies = [ + "once_cell", + "rand 0.8.5", + "sentry-types", + "serde", + "serde_json", +] + +[[package]] +name = "sentry-debug-images" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afdb263e73d22f39946f6022ed455b7561b22ff5553aca9be3c6a047fa39c328" +dependencies = [ + "findshlibs", + "once_cell", + "sentry-core", +] + +[[package]] +name = "sentry-panic" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fbf1c163f8b6a9d05912e1b272afa27c652e8b47ea60cb9a57ad5e481eea99" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82eabcab0a047040befd44599a1da73d3adb228ff53b5ed9795ae04535577704" +dependencies = [ + "sentry-backtrace", + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sentry-types" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da956cca56e0101998c8688bc65ce1a96f00673a0e58e663664023d4c7911e82" +dependencies = [ + "debugid", + "hex", + "rand 0.8.5", + "serde", + "serde_json", + "thiserror", + "time", + "url", + "uuid 1.8.0", +] + +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-aux" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float 2.10.1", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15e0ef66bf939a7c890a0bf6d5a733c70202225f9888a89ed5c62298b019129" +dependencies = [ + "indexmap 2.2.6", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=1731ced4a116d61ba9dc6ee6d0f38fb8102e357a#1731ced4a116d61ba9dc6ee6d0f38fb8102e357a" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=7a187e934c1f6c68e4b4e5cf37541b7a0d64d303#7a187e934c1f6c68e4b4e5cf37541b7a0d64d303" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "snark_wrapper" +version = "0.1.0" +source = "git+https://github.com/matter-labs/snark-wrapper.git?branch=main#76959cadabeec344b9fa1458728400d60340e496" +dependencies = [ + "derivative", + "rand 0.4.6", + "rescue_poseidon", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha-1 0.9.8", +] + +[[package]] +name = "solang-parser" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8ac4bfef383f368bd9bb045107a501cd9cd0b64ad1983e1b7e839d6a44ecad" +dependencies = [ + "itertools 0.10.5", + "lalrpop", + "lalrpop-util", + "phf", + "unicode-xid 0.2.4", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", +] + +[[package]] +name = "splitmut" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85070f382340e8b23a75808e83573ddf65f9ad9143df9573ca37c1ed2ee956a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.2", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap 2.34.0", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "svm-rs" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a04fc4f5cd35c700153b233f5575ccb3237e0f941fa5049d9e98254d10bf2fe" +dependencies = [ + "fs2", + "hex", + "home", + "once_cell", + "reqwest", + "semver", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "url", + "zip", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.2", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "rustls 0.20.9", + "tokio", + "tokio-rustls 0.23.4", + "tungstenite", + "webpki", + "webpki-roots 0.22.6", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75327c6b667828ddc28f5e3f169036cb793c3f588d83bf0f262a7f062ffed3c8" +dependencies = [ + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log 0.1.4", + "tracing-subscriber", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log 0.2.0", + "tracing-serde", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls 0.20.9", + "sha-1 0.10.1", + "thiserror", + "url", + "utf-8", + "webpki", +] + +[[package]] +name = "typemap_rev" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b08b0c1257381af16a5c3605254d529d3e7e109f3c62befc5d168968192998" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unroll" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad948c1cb799b1a70f836077721a92a35ac177d4daddf4c20a633786d4cf618" +dependencies = [ + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +dependencies = [ + "base64 0.22.1", + "log", + "native-tls", + "once_cell", + "url", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vise" +version = "0.1.0" +source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" +dependencies = [ + "compile-fmt", + "elsa", + "linkme", + "once_cell", + "prometheus-client", + "vise-macros", +] + +[[package]] +name = "vise-macros" +version = "0.1.0" +source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "vlog" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "chrono", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "sentry", + "serde_json", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote 1.0.33", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5388522c899d1e1c96a4c307e3797e0f697ba7c77dd8e0e625ecba9dd0342937" +dependencies = [ + "arrayvec 0.7.4", + "base64 0.21.7", + "bytes", + "derive_more 0.99.17", + "ethabi", + "ethereum-types", + "futures", + "futures-timer", + "headers", + "hex", + "idna 0.4.0", + "jsonrpc-core", + "log", + "once_cell", + "parking_lot 0.12.2", + "pin-project", + "reqwest", + "rlp", + "secp256k1", + "serde", + "serde_json", + "soketto", + "tiny-keccak 2.0.2", + "tokio", + "tokio-stream", + "tokio-util", + "url", + "web3-async-native-tls", +] + +[[package]] +name = "web3-async-native-tls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6d8d1636b2627fe63518d5a9b38a569405d9c9bc665c43c9c341de57227ebb" +dependencies = [ + "native-tls", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-targets" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils 0.8.19", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zk_evm" +version = "1.3.3" +source = "git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2#fbee20f5bac7d6ca3e22ae69b2077c510a07de4e" +dependencies = [ + "anyhow", + "lazy_static", + "num", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions 0.1.0", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm" +version = "1.4.0" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.4.0#dd76fc5badf2c05278a21b38015a7798fe2fe358" +dependencies = [ + "anyhow", + "lazy_static", + "num", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions 0.1.0", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.5.0#6119ce908ab714f2f99804794e725b97298a6b11" +dependencies = [ + "anyhow", + "lazy_static", + "num", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions 1.5.0", +] + +[[package]] +name = "zk_evm_abstractions" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git#32dd320953841aa78579d9da08abbc70bcaed175" +dependencies = [ + "anyhow", + "num_enum 0.6.1", + "serde", + "static_assertions", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm_abstractions" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git?branch=v1.5.0#e464b2cf2b146d883be80e7d690c752bf670ff05" +dependencies = [ + "anyhow", + "num_enum 0.6.1", + "serde", + "static_assertions", + "zkevm_opcode_defs 1.5.0", +] + +[[package]] +name = "zkevm_circuits" +version = "1.4.0" +source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.4.0#fb3e2574b5c890342518fc930c145443f039a105" +dependencies = [ + "arrayvec 0.7.4", + "bincode", + "boojum", + "cs_derive", + "derivative", + "hex", + "itertools 0.10.5", + "rand 0.4.6", + "rand 0.8.5", + "seq-macro", + "serde", + "serde_json", + "smallvec", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zkevm_circuits" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.5.0#861f81029bf3a916dae55afa5bd7f82b2eaca98b" +dependencies = [ + "arrayvec 0.7.4", + "boojum", + "cs_derive", + "derivative", + "hex", + "itertools 0.10.5", + "rand 0.4.6", + "rand 0.8.5", + "seq-macro", + "serde", + "smallvec", + "zkevm_opcode_defs 1.5.0", +] + +[[package]] +name = "zkevm_opcode_defs" +version = "1.3.2" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.3.2#dffacadeccdfdbff4bc124d44c595c4a6eae5013" +dependencies = [ + "bitflags 2.5.0", + "blake2 0.10.6 (git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e)", + "ethereum-types", + "k256 0.11.6", + "lazy_static", + "sha2 0.10.6", + "sha3 0.10.6", +] + +[[package]] +name = "zkevm_opcode_defs" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.5.0#109d9f734804a8b9dc0531c0b576e2a0f55a40de" +dependencies = [ + "bitflags 2.5.0", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types", + "k256 0.13.2", + "lazy_static", + "p256", + "serde", + "sha2 0.10.8", + "sha3 0.10.8", +] + +[[package]] +name = "zksync_basic_types" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "chrono", + "num_enum 0.7.2", + "serde", + "serde_json", + "strum", + "url", + "web3", +] + +[[package]] +name = "zksync_concurrency" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "anyhow", + "once_cell", + "pin-project", + "rand 0.8.5", + "sha3 0.10.8", + "thiserror", + "time", + "tokio", + "tracing", + "tracing-subscriber", + "vise", +] + +[[package]] +name = "zksync_config" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "rand 0.8.5", + "serde", + "url", + "zksync_basic_types", + "zksync_consensus_utils", + "zksync_crypto_primitives", +] + +[[package]] +name = "zksync_consensus_utils" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "rand 0.8.5", + "thiserror", + "zksync_concurrency", +] + +[[package]] +name = "zksync_contracts" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "envy", + "ethabi", + "hex", + "once_cell", + "serde", + "serde_json", + "zksync_utils", +] + +[[package]] +name = "zksync_crypto" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "once_cell", + "serde", + "sha2 0.10.8", + "thiserror", + "zksync_basic_types", +] + +[[package]] +name = "zksync_crypto_primitives" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "hex", + "rand 0.8.5", + "secp256k1", + "serde", + "serde_json", + "thiserror", + "web3", + "zksync_basic_types", + "zksync_utils", +] + +[[package]] +name = "zksync_mini_merkle_tree" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "once_cell", + "zksync_basic_types", + "zksync_crypto", +] + +[[package]] +name = "zksync_protobuf" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "anyhow", + "bit-vec", + "once_cell", + "prost 0.12.4", + "prost-reflect", + "quick-protobuf", + "rand 0.8.5", + "serde", + "serde_json", + "serde_yaml", + "zksync_concurrency", + "zksync_consensus_utils", + "zksync_protobuf_build", +] + +[[package]] +name = "zksync_protobuf_build" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "anyhow", + "heck 0.5.0", + "prettyplease", + "proc-macro2 1.0.82", + "prost-build", + "prost-reflect", + "protox", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "zksync_system_constants" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "once_cell", + "zksync_basic_types", + "zksync_utils", +] + +[[package]] +name = "zksync_types" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "derive_more 1.0.0-beta.6", + "hex", + "itertools 0.10.5", + "num", + "num_enum 0.7.2", + "once_cell", + "prost 0.12.4", + "rlp", + "secp256k1", + "serde", + "serde_json", + "strum", + "thiserror", + "zksync_basic_types", + "zksync_config", + "zksync_contracts", + "zksync_crypto_primitives", + "zksync_mini_merkle_tree", + "zksync_protobuf", + "zksync_protobuf_build", + "zksync_system_constants", + "zksync_utils", +] + +[[package]] +name = "zksync_utils" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "bigdecimal", + "futures", + "hex", + "itertools 0.10.5", + "num", + "reqwest", + "serde", + "thiserror", + "tokio", + "tracing", + "vlog", + "zk_evm 1.3.3", + "zksync_basic_types", +] [[package]] name = "zksync_verifier_contract_generator" version = "0.1.0" dependencies = [ + "circuit_definitions 1.5.0", + "crypto", "handlebars", + "hex", "lazy_static", "serde_derive", "serde_json", + "sha3 0.10.8", "structopt", ] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/tools/Cargo.toml b/tools/Cargo.toml index 204440623..b32b52bdb 100644 --- a/tools/Cargo.toml +++ b/tools/Cargo.toml @@ -4,10 +4,15 @@ version = "0.1.0" edition = "2021" [dependencies] +zksync_crypto = { git = "https://github.com/matter-labs/era-boojum-validator-cli", branch = "main", package = "crypto" } +circuit_definitions = {git = "https://github.com/matter-labs/era-zkevm_test_harness.git", branch="v1.5.0"} + serde_derive = "1.0" serde_json = "1.0" lazy_static = "1.4" structopt = "0.3.26" handlebars = "4.4.0" +sha3 = "0.10.8" +hex = "0.4.3" [workspace] diff --git a/tools/data/verifier_contract_template.txt b/tools/data/verifier_contract_template.txt index bef14e662..972123961 100644 --- a/tools/data/verifier_contract_template.txt +++ b/tools/data/verifier_contract_template.txt @@ -9,6 +9,7 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. /// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. +/// @dev Contract was generated from a verification key with a hash of 0x{{vk_hash}} /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: diff --git a/tools/rust-toolchain b/tools/rust-toolchain deleted file mode 100644 index 0834888f5..000000000 --- a/tools/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.72.0 diff --git a/tools/rust-toolchain.toml b/tools/rust-toolchain.toml new file mode 100644 index 000000000..1388c20ff --- /dev/null +++ b/tools/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-02-04" diff --git a/tools/src/main.rs b/tools/src/main.rs index 3ac8c3ff1..746373fe4 100644 --- a/tools/src/main.rs +++ b/tools/src/main.rs @@ -1,5 +1,9 @@ +use circuit_definitions::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey; +use circuit_definitions::snark_wrapper::franklin_crypto::bellman::pairing::bn256::Bn256; +use circuit_definitions::circuit_definitions::aux_layer::ZkSyncSnarkWrapperCircuit; use handlebars::Handlebars; use serde_json::json; +use zksync_crypto::calculate_verification_key_hash; use std::collections::HashMap; use std::error::Error; use std::fs; @@ -122,8 +126,16 @@ fn main() -> Result<(), Box> { let verifier_contract_template = fs::read_to_string("data/verifier_contract_template.txt")?; + let verification_key = fs::read_to_string(&opt.input_path) + .expect(&format!("Unable to read from {}", &opt.input_path)); + + let verification_key: VerificationKey = + serde_json::from_str(&verification_key).unwrap(); + + let vk_hash = hex::encode(calculate_verification_key_hash(verification_key).to_fixed_bytes()); + let verifier_contract_template = - insert_residue_elements_and_commitments(&verifier_contract_template, &vk)?; + insert_residue_elements_and_commitments(&verifier_contract_template, &vk, &vk_hash)?; let mut file = File::create(opt.output_path)?; @@ -134,6 +146,7 @@ fn main() -> Result<(), Box> { fn insert_residue_elements_and_commitments( template: &str, vk: &HashMap, + vk_hash: &str, ) -> Result> { let reg = Handlebars::new(); let residue_g2_elements = generate_residue_g2_elements(vk); @@ -145,7 +158,8 @@ fn insert_residue_elements_and_commitments( Ok(reg.render_template( &verifier_contract_template, &json!({"residue_g2_elements": residue_g2_elements, - "commitments": commitments}), + "commitments": commitments, + "vk_hash": vk_hash}), )?) } From 994897b14eb1d8e77c809da2db3379e7b58125b5 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 19:27:36 -0400 Subject: [PATCH 06/42] chore(contract): applied new solhint rules across l1, l2, and system contracts (#473) --- .solhint.json | 45 ++-- .solhintignore | 4 + l1-contracts-foundry/script/DeployErc20.s.sol | 16 +- l1-contracts-foundry/script/DeployL1.s.sol | 17 +- .../script/InitializeL2WethToken.s.sol | 3 +- .../script/RegisterHyperchain.s.sol | 17 +- l1-contracts-foundry/script/Utils.sol | 33 ++- .../script/ZkSyncScriptErrors.sol | 15 ++ .../contracts/bridge/L1ERC20Bridge.sol | 2 + .../contracts/bridge/L1SharedBridge.sol | 6 +- .../contracts/bridgehub/Bridgehub.sol | 4 +- l1-contracts/contracts/common/Messaging.sol | 1 + .../contracts/common/ReentrancyGuard.sol | 2 + .../common/libraries/L2ContractHelper.sol | 2 + .../contracts/dev-contracts/Multicall.sol | 3 +- .../dev-contracts/SingletonFactory.sol | 1 + .../contracts/governance/Governance.sol | 13 + .../IStateTransitionManager.sol | 1 + .../StateTransitionManager.sol | 5 +- .../state-transition/ValidatorTimelock.sol | 6 +- .../chain-deps/DiamondInit.sol | 2 + .../chain-deps/DiamondProxy.sol | 2 + .../chain-deps/ZkSyncHyperchainStorage.sol | 1 + .../chain-deps/facets/Admin.sol | 2 + .../chain-deps/facets/Executor.sol | 18 +- .../chain-deps/facets/Getters.sol | 2 + .../chain-deps/facets/Mailbox.sol | 11 +- .../facets/ZkSyncHyperchainBase.sol | 2 + .../chain-interfaces/IDiamondInit.sol | 1 + .../chain-interfaces/IExecutor.sol | 1 + .../state-transition/libraries/Diamond.sol | 3 + .../state-transition/libraries/Merkle.sol | 2 + .../libraries/PriorityQueue.sol | 2 + .../libraries/TransactionValidator.sol | 2 + .../contracts/upgrades/BaseZkSyncUpgrade.sol | 5 +- .../upgrades/BaseZkSyncUpgradeGenesis.sol | 30 ++- .../contracts/upgrades/UpgradeHyperchains.sol | 2 + .../contracts/upgrades/Upgrade_v1_4_1.sol | 12 +- .../upgrades/ZkSyncUpgradeErrors.sol | 8 + .../contracts/vendor/AddressAliasHelper.sol | 3 +- l1-contracts/foundry.toml | 8 + .../_StateTransitionManager_Shared.t.sol | 2 +- .../test/test_config/constant/hardhat.json | 32 +-- l2-contracts/contracts/L2ContractErrors.sol | 20 ++ .../contracts/SystemContractsCaller.sol | 9 +- l2-contracts/contracts/TestnetPaymaster.sol | 22 +- .../contracts/bridge/L2SharedBridge.sol | 56 ++-- .../contracts/bridge/L2StandardERC20.sol | 33 ++- .../contracts/bridge/L2WrappedBaseToken.sol | 29 +- .../contracts/vendor/AddressAliasHelper.sol | 2 +- package.json | 2 +- system-contracts/SystemContractsHashes.json | 82 +++--- .../contracts/AccountCodeStorage.sol | 19 +- .../contracts/BootloaderUtilities.sol | 15 +- .../contracts/ComplexUpgrader.sol | 9 +- system-contracts/contracts/Compressor.sol | 70 +++-- .../contracts/ContractDeployer.sol | 55 ++-- system-contracts/contracts/DefaultAccount.sol | 21 +- system-contracts/contracts/GasBoundCaller.sol | 13 +- .../contracts/ImmutableSimulator.sol | 5 +- .../contracts/KnownCodesStorage.sol | 13 +- system-contracts/contracts/L1Messenger.sol | 63 +++-- system-contracts/contracts/L2BaseToken.sol | 20 +- .../contracts/MsgValueSimulator.sol | 10 +- system-contracts/contracts/NonceHolder.sol | 28 +- .../contracts/PubdataChunkPublisher.sol | 9 +- system-contracts/contracts/SystemContext.sol | 5 +- .../contracts/SystemContractErrors.sol | 75 ++++++ .../contracts/interfaces/ISystemContract.sol | 27 +- .../contracts/libraries/EfficientCall.sol | 9 +- .../contracts/libraries/RLPEncoder.sol | 2 +- .../libraries/SystemContractHelper.sol | 10 +- .../contracts/libraries/TransactionHelper.sol | 21 +- .../contracts/libraries/Utils.sol | 31 ++- .../test/AccountCodeStorage.spec.ts | 15 +- .../test/BootloaderUtilities.spec.ts | 15 +- system-contracts/test/ComplexUpgrader.spec.ts | 5 +- system-contracts/test/Compressor.spec.ts | 46 ++-- .../test/ContractDeployer.spec.ts | 46 ++-- .../test/ImmutableSimulator.spec.ts | 5 +- .../test/KnownCodesStorage.spec.ts | 19 +- system-contracts/test/L1Messenger.spec.ts | 20 +- system-contracts/test/L2BaseToken.spec.ts | 10 +- system-contracts/test/NonceHolder.spec.ts | 42 +-- .../test/PubdataChunkPublisher.spec.ts | 7 +- system-contracts/test/SystemContext.spec.ts | 14 +- yarn.lock | 254 +++++++++++++++++- 87 files changed, 1188 insertions(+), 444 deletions(-) create mode 100644 l1-contracts-foundry/script/ZkSyncScriptErrors.sol create mode 100644 l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol create mode 100644 l2-contracts/contracts/L2ContractErrors.sol create mode 100644 system-contracts/contracts/SystemContractErrors.sol diff --git a/.solhint.json b/.solhint.json index 617a892bf..ef3522c45 100644 --- a/.solhint.json +++ b/.solhint.json @@ -1,31 +1,40 @@ { "extends": "solhint:recommended", "rules": { - "state-visibility": "off", - "func-visibility": ["warn", { "ignoreConstructors": true }], - "var-name-mixedcase": "off", - "avoid-call-value": "off", - "no-empty-blocks": "off", - "not-rely-on-time": "off", + "avoid-call-value": "error", "avoid-low-level-calls": "off", - "no-inline-assembly": "off", + "avoid-sha3": "error", + "check-send-result": "error", + "compiler-version": ["error", "^0.8.0"], "const-name-snakecase": "off", - "no-complex-fallback": "off", - "reason-string": "off", + "contract-name-camelcase": "off", + "gas-calldata-parameters": "error", + "gas-custom-errors": "error", + "gas-increment-by-one": "error", + "gas-length-in-loops": "error", + "gas-struct-packing": "error", + "explicit-types": "error", "func-name-mixedcase": "off", - "custom-errors": "off", - "no-unused-vars": "error", + "func-named-parameters": ["error", 4], + "func-visibility": ["error", { "ignoreConstructors": true }], + "imports-on-top": "error", "max-states-count": "off", + "modifier-name-mixedcase": "error", + "named-parameters-mapping": "off", + "no-complex-fallback": "off", + "no-console": "error", + "no-empty-blocks": "off", "no-global-import": "error", + "no-inline-assembly": "off", "no-unused-import": "error", - "explicit-types": "error", - "modifier-name-mixedcase": "error", - "imports-on-top": "error", + "no-unused-vars": "error", + "not-rely-on-time": "off", "quotes": "error", - "use-forbidden-name": "error", - "visibility-modifier-order": "error", + "reason-string": "error", "reentrancy": "error", - "func-named-parameters": ["error", 4], - "compiler-version": ["error", "^0.8.0"] + "state-visibility": "error", + "use-forbidden-name": "error", + "var-name-mixedcase": "off", + "visibility-modifier-order": "error" } } diff --git a/.solhintignore b/.solhintignore index ec8271f7e..d6471dfce 100644 --- a/.solhintignore +++ b/.solhintignore @@ -6,6 +6,8 @@ l1-contracts/cache l1-contracts/cache-forge l1-contracts/lib l1-contracts/node_modules +l1-contracts/contracts/dev-contracts +l1-contracts/test # l1-contracts-foundry l1-contracts-foundry/cache @@ -18,3 +20,5 @@ l2-contracts/node_modules # system-contracts system-contracts/contracts/openzeppelin system-contracts/contracts/Constants.sol +system-contracts/contracts/test-contracts +system-contracts/contracts-preprocessed diff --git a/l1-contracts-foundry/script/DeployErc20.s.sol b/l1-contracts-foundry/script/DeployErc20.s.sol index 4a2046ec7..49786b7ca 100644 --- a/l1-contracts-foundry/script/DeployErc20.s.sol +++ b/l1-contracts-foundry/script/DeployErc20.s.sol @@ -7,6 +7,7 @@ import {Script, console2 as console} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; import {Utils} from "./Utils.sol"; +import {MintFailed} from "./ZkSyncScriptErrors.sol"; contract DeployErc20Script is Script { using stdToml for string; @@ -27,7 +28,7 @@ contract DeployErc20Script is Script { uint256 mint; } - Config config; + Config internal config; function run() public { console.log("Deploying ERC20 Tokens"); @@ -52,7 +53,8 @@ contract DeployErc20Script is Script { config.create2FactorySalt = vm.parseTomlBytes32(toml, "$.create2_factory_salt"); string[] memory tokens = vm.parseTomlKeys(toml, "$.tokens"); - for (uint256 i = 0; i < tokens.length; i++) { + uint256 tokensLength = tokens.length; + for (uint256 i = 0; i < tokensLength; ++i) { TokenDescription memory token; string memory key = string.concat("$.tokens.", tokens[i]); token.name = toml.readString(string.concat(key, ".name")); @@ -66,7 +68,8 @@ contract DeployErc20Script is Script { } function deployTokens() internal { - for (uint256 i = 0; i < config.tokens.length; i++) { + uint256 tokensLength = config.tokens.length; + for (uint256 i = 0; i < tokensLength; ++i) { TokenDescription memory token = config.tokens[i]; console.log("Deploying token:", token.name); address tokenAddress = deployErc20({ @@ -103,7 +106,9 @@ contract DeployErc20Script is Script { (bool success, ) = tokenAddress.call( abi.encodeWithSignature("mint(address,uint256)", config.deployerAddress, mint) ); - require(success, "Mint failed"); + if (!success) { + revert MintFailed(); + } } return tokenAddress; @@ -114,7 +119,8 @@ contract DeployErc20Script is Script { vm.serializeBytes32("root", "create2_factory_salt", config.create2FactorySalt); string memory tokens = ""; - for (uint256 i = 0; i < config.tokens.length; i++) { + uint256 tokensLength = config.tokens.length; + for (uint256 i = 0; i < tokensLength; ++i) { TokenDescription memory token = config.tokens[i]; vm.serializeString(token.symbol, "name", token.name); vm.serializeString(token.symbol, "symbol", token.symbol); diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 3768787de..cf20e4f7a 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -31,13 +31,15 @@ import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-de import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {L1ERC20Bridge} from "contracts/bridge/L1ERC20Bridge.sol"; import {DiamondProxy} from "contracts/state-transition/chain-deps/DiamondProxy.sol"; +import {AddressHasNoCode} from "./ZkSyncScriptErrors.sol"; contract DeployL1Script is Script { using stdToml for string; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - address constant DETERMINISTIC_CREATE2_ADDRESS = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + address internal constant DETERMINISTIC_CREATE2_ADDRESS = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + // solhint-disable-next-line gas-struct-packing struct DeployedAddresses { BridgehubDeployedAddresses bridgehub; StateTransitionDeployedAddresses stateTransition; @@ -49,11 +51,13 @@ contract DeployL1Script is Script { address create2Factory; } + // solhint-disable-next-line gas-struct-packing struct BridgehubDeployedAddresses { address bridgehubImplementation; address bridgehubProxy; } + // solhint-disable-next-line gas-struct-packing struct StateTransitionDeployedAddresses { address stateTransitionProxy; address stateTransitionImplementation; @@ -68,6 +72,7 @@ contract DeployL1Script is Script { address diamondProxy; } + // solhint-disable-next-line gas-struct-packing struct BridgesDeployedAddresses { address erc20BridgeImplementation; address erc20BridgeProxy; @@ -75,6 +80,7 @@ contract DeployL1Script is Script { address sharedBridgeProxy; } + // solhint-disable-next-line gas-struct-packing struct Config { uint256 l1ChainId; uint256 eraChainId; @@ -84,6 +90,7 @@ contract DeployL1Script is Script { TokensConfig tokens; } + // solhint-disable-next-line gas-struct-packing struct ContractsConfig { bytes32 create2FactorySalt; address create2FactoryAddr; @@ -112,8 +119,8 @@ contract DeployL1Script is Script { address tokenWethAddress; } - Config config; - DeployedAddresses addresses; + Config internal config; + DeployedAddresses internal addresses; function run() public { console.log("Deploying L1 contracts"); @@ -208,7 +215,7 @@ contract DeployL1Script is Script { if (isConfigured) { if (config.contracts.create2FactoryAddr.code.length == 0) { - revert("Create2Factory configured address is empty"); + revert AddressHasNoCode(config.contracts.create2FactoryAddr); } contractAddress = config.contracts.create2FactoryAddr; console.log("Using configured Create2Factory address:", contractAddress); diff --git a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol index 96828fbe6..a147e3d00 100644 --- a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol +++ b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol @@ -14,6 +14,7 @@ import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; contract InitializeL2WethTokenScript is Script { using stdToml for string; + // solhint-disable-next-line gas-struct-packing struct Config { address deployerAddress; address create2FactoryAddr; @@ -31,7 +32,7 @@ contract InitializeL2WethTokenScript is Script { uint256 gasMultiplier; } - Config config; + Config internal config; function run() public { initializeConfig(); diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 9429a472c..c0d776813 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -15,12 +15,13 @@ import {VerifierParams, IVerifier} from "contracts/state-transition/chain-interf import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; import {InitializeDataNewChain as DiamondInitializeDataNewChain} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; +import {ZksyncContract, MissingAddress, AddressHasNoCode} from "./ZkSyncScriptErrors.sol"; contract RegisterHyperchainScript is Script { using stdToml for string; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - bytes32 constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + bytes32 internal constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); struct Config { ContractsConfig contracts; @@ -49,6 +50,7 @@ contract RegisterHyperchainScript is Script { uint128 baseTokenGasPriceMultiplierDenominator; } + // solhint-disable-next-line gas-struct-packing struct AddressesConfig { address baseToken; address bridgehub; @@ -64,7 +66,7 @@ contract RegisterHyperchainScript is Script { address newDiamondProxy; } - Config config; + Config internal config; function run() public { console.log("Deploying Hyperchain"); @@ -146,7 +148,7 @@ contract RegisterHyperchainScript is Script { function checkTokenAddress() internal { if (config.addresses.baseToken == address(0)) { - revert("Token address is not set"); + revert MissingAddress(ZksyncContract.BaseToken); } // Check if it's ethereum address @@ -155,7 +157,7 @@ contract RegisterHyperchainScript is Script { } if (config.addresses.baseToken.code.length == 0) { - revert("Token address is not a contract address"); + revert AddressHasNoCode(config.addresses.baseToken); } console.log("Using base token address:", config.addresses.baseToken); @@ -248,14 +250,15 @@ contract RegisterHyperchainScript is Script { // Get new diamond proxy address from emitted events Vm.Log[] memory logs = vm.getRecordedLogs(); address diamondProxyAddress; - for (uint256 i = 0; i < logs.length; i++) { + uint256 logsLength = logs.length; + for (uint256 i = 0; i < logsLength; ++i) { if (logs[i].topics[0] == STATE_TRANSITION_NEW_CHAIN_HASH) { diamondProxyAddress = address(uint160(uint256(logs[i].topics[2]))); break; } } if (diamondProxyAddress == address(0)) { - revert("Diamond proxy address not found"); + revert MissingAddress(ZksyncContract.DiamondProxy); } config.addresses.newDiamondProxy = diamondProxyAddress; } diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts-foundry/script/Utils.sol index b9a66426f..c694db463 100644 --- a/l1-contracts-foundry/script/Utils.sol +++ b/l1-contracts-foundry/script/Utils.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import {Vm} from "forge-std/Vm.sol"; +import {ZksyncContract, FailedToDeploy, BytecodeNotSet, FailedToDeployViaCreate2} from "./ZkSyncScriptErrors.sol"; library Utils { // Cheatcodes address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. @@ -30,12 +31,13 @@ library Utils { // Extract selectors from the result string[] memory parts = vm.split(stringResult, "\n"); - bytes4[] memory selectors = new bytes4[](parts.length); - for (uint256 i = 0; i < parts.length; i++) { + uint256 partsLength = parts.length; + bytes4[] memory selectors = new bytes4[](partsLength); + for (uint256 i = 0; i < partsLength; ++i) { bytes memory part = bytes(parts[i]); bytes memory extractedSelector = new bytes(10); // Selector length 10 is 0x + 4 bytes - for (uint256 j = 0; j < 10; j++) { + for (uint256 j = 0; j < 10; ++j) { extractedSelector[j] = part[j]; } bytes4 selector = bytes4(vm.parseBytes(string(extractedSelector))); @@ -44,16 +46,17 @@ library Utils { // Remove `getName()` selector if existing bool hasGetName = false; - for (uint256 i = 0; i < selectors.length; i++) { + uint256 selectorsLength = selectors.length; + for (uint256 i = 0; i < selectorsLength; ++i) { if (selectors[i] == bytes4(keccak256("getName()"))) { - selectors[i] = selectors[selectors.length - 1]; + selectors[i] = selectors[selectorsLength - 1]; hasGetName = true; break; } } if (hasGetName) { - bytes4[] memory newSelectors = new bytes4[](selectors.length - 1); - for (uint256 i = 0; i < selectors.length - 1; i++) { + bytes4[] memory newSelectors = new bytes4[](selectorsLength - 1); + for (uint256 i = 0; i < selectorsLength - 1; ++i) { newSelectors[i] = selectors[i]; } return newSelectors; @@ -76,10 +79,11 @@ library Utils { */ function bytesToUint256(bytes memory bys) internal pure returns (uint256 value) { // Add left padding to 32 bytes if needed - if (bys.length < 32) { + uint256 bytesLength = bys.length; + if (bytesLength < 32) { bytes memory padded = new bytes(32); - for (uint256 i = 0; i < bys.length; i++) { - padded[i + 32 - bys.length] = bys[i]; + for (uint256 i = 0; i < bytesLength; ++i) { + padded[i + 32 - bytesLength] = bys[i]; } bys = padded; } @@ -125,8 +129,9 @@ library Utils { child := create(0, add(bytecode, 0x20), mload(bytecode)) } vm.stopBroadcast(); - require(child != address(0), "Failed to deploy Create2Factory"); - require(child.code.length > 0, "Failed to deploy Create2Factory"); + if (child == address(0) || child.code.length == 0) { + revert FailedToDeploy(ZksyncContract.Create2Factory); + } return child; } @@ -135,7 +140,7 @@ library Utils { */ function deployViaCreate2(bytes memory _bytecode, bytes32 _salt, address _factory) internal returns (address) { if (_bytecode.length == 0) { - revert("Bytecode is not set"); + revert BytecodeNotSet(); } address contractAddress = vm.computeCreate2Address(_salt, keccak256(_bytecode), _factory); if (contractAddress.code.length != 0) { @@ -147,7 +152,7 @@ library Utils { contractAddress = Utils.bytesToAddress(data); if (!success || contractAddress == address(0) || contractAddress.code.length == 0) { - revert("Failed to deploy contract via create2"); + revert FailedToDeployViaCreate2(); } return contractAddress; diff --git a/l1-contracts-foundry/script/ZkSyncScriptErrors.sol b/l1-contracts-foundry/script/ZkSyncScriptErrors.sol new file mode 100644 index 000000000..76295d633 --- /dev/null +++ b/l1-contracts-foundry/script/ZkSyncScriptErrors.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +error FailedToDeploy(ZksyncContract); +error BytecodeNotSet(); +error FailedToDeployViaCreate2(); +error MissingAddress(ZksyncContract); +error AddressHasNoCode(address); +error MintFailed(); + +enum ZksyncContract { + Create2Factory, + DiamondProxy, + BaseToken +} diff --git a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol index da3098969..a19c1b31c 100644 --- a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index d2a9f4b0d..65033089e 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; @@ -37,10 +39,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade IBridgehub public immutable override BRIDGE_HUB; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 internal immutable ERA_CHAIN_ID; /// @dev The address of zkSync Era diamond proxy contract. - address immutable ERA_DIAMOND_PROXY; + address internal immutable ERA_DIAMOND_PROXY; /// @dev Stores the first batch number on the zkSync Era Diamond Proxy that was settled after Diamond proxy upgrade. /// This variable is used to differentiate between pre-upgrade and post-upgrade Eth withdrawals. Withdrawals from batches older diff --git a/l1-contracts/contracts/bridgehub/Bridgehub.sol b/l1-contracts/contracts/bridgehub/Bridgehub.sol index 539af6a0c..8a1498fec 100644 --- a/l1-contracts/contracts/bridgehub/Bridgehub.sol +++ b/l1-contracts/contracts/bridgehub/Bridgehub.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; @@ -169,7 +171,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus uint256 _chainId, uint256 _batchNumber, uint256 _index, - L2Log memory _log, + L2Log calldata _log, bytes32[] calldata _proof ) external view override returns (bool) { address hyperchain = getHyperchain(_chainId); diff --git a/l1-contracts/contracts/common/Messaging.sol b/l1-contracts/contracts/common/Messaging.sol index 3c934ae5f..496760438 100644 --- a/l1-contracts/contracts/common/Messaging.sol +++ b/l1-contracts/contracts/common/Messaging.sol @@ -122,6 +122,7 @@ struct L2CanonicalTransaction { /// @param factoryDeps The array of L2 bytecodes that the tx depends on. /// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then /// this address will receive the `l2Value`. +// solhint-disable-next-line gas-struct-packing struct BridgehubL2TransactionRequest { address sender; address contractL2; diff --git a/l1-contracts/contracts/common/ReentrancyGuard.sol b/l1-contracts/contracts/common/ReentrancyGuard.sol index a19020b77..894f94f5e 100644 --- a/l1-contracts/contracts/common/ReentrancyGuard.sol +++ b/l1-contracts/contracts/common/ReentrancyGuard.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + /** * @custom:security-contact security@matterlabs.dev * @dev Contract module that helps prevent reentrant calls to a function. diff --git a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol index ae1a64250..808068d59 100644 --- a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol +++ b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/l1-contracts/contracts/dev-contracts/Multicall.sol b/l1-contracts/contracts/dev-contracts/Multicall.sol index e2b1391dd..242c01e24 100644 --- a/l1-contracts/contracts/dev-contracts/Multicall.sol +++ b/l1-contracts/contracts/dev-contracts/Multicall.sol @@ -33,7 +33,8 @@ contract Multicall { function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) { blockNumber = block.number; returnData = new bytes[](calls.length); - for (uint256 i = 0; i < calls.length; ++i) { + uint256 callsLength = calls.length; + for (uint256 i = 0; i < callsLength; ++i) { (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); require(success, "multicall 1"); returnData[i] = ret; diff --git a/l1-contracts/contracts/dev-contracts/SingletonFactory.sol b/l1-contracts/contracts/dev-contracts/SingletonFactory.sol index b1bd999cf..3e8b9eec9 100644 --- a/l1-contracts/contracts/dev-contracts/SingletonFactory.sol +++ b/l1-contracts/contracts/dev-contracts/SingletonFactory.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /** diff --git a/l1-contracts/contracts/governance/Governance.sol b/l1-contracts/contracts/governance/Governance.sol index 42ac46e02..3f40721e9 100644 --- a/l1-contracts/contracts/governance/Governance.sol +++ b/l1-contracts/contracts/governance/Governance.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {IGovernance} from "./IGovernance.sol"; @@ -56,18 +58,21 @@ contract Governance is IGovernance, Ownable2Step { /// @notice Checks that the message sender is contract itself. modifier onlySelf() { + // solhint-disable-next-line reason-string require(msg.sender == address(this), "Only governance contract itself is allowed to call this function"); _; } /// @notice Checks that the message sender is an active security council. modifier onlySecurityCouncil() { + // solhint-disable-next-line reason-string require(msg.sender == securityCouncil, "Only security council is allowed to call this function"); _; } /// @notice Checks that the message sender is an active owner or an active security council. modifier onlyOwnerOrSecurityCouncil() { + // solhint-disable-next-line reason-string require( msg.sender == owner() || msg.sender == securityCouncil, "Only the owner and security council are allowed to call this function" @@ -170,12 +175,14 @@ contract Governance is IGovernance, Ownable2Step { // Check if the predecessor operation is completed. _checkPredecessorDone(_operation.predecessor); // Ensure that the operation is ready to proceed. + // solhint-disable-next-line reason-string require(isOperationReady(id), "Operation must be ready before execution"); // Execute operation. // slither-disable-next-line reentrancy-eth _execute(_operation.calls); // Reconfirming that the operation is still ready after execution. // This is needed to avoid unexpected reentrancy attacks of re-executing the same operation. + // solhint-disable-next-line reason-string require(isOperationReady(id), "Operation must be ready after execution"); // Set operation to be done timestamps[id] = EXECUTED_PROPOSAL_TIMESTAMP; @@ -191,12 +198,14 @@ contract Governance is IGovernance, Ownable2Step { // Check if the predecessor operation is completed. _checkPredecessorDone(_operation.predecessor); // Ensure that the operation is in a pending state before proceeding. + // solhint-disable-next-line reason-string require(isOperationPending(id), "Operation must be pending before execution"); // Execute operation. // slither-disable-next-line reentrancy-eth _execute(_operation.calls); // Reconfirming that the operation is still pending before execution. // This is needed to avoid unexpected reentrancy attacks of re-executing the same operation. + // solhint-disable-next-line reason-string require(isOperationPending(id), "Operation must be pending after execution"); // Set operation to be done timestamps[id] = EXECUTED_PROPOSAL_TIMESTAMP; @@ -217,8 +226,10 @@ contract Governance is IGovernance, Ownable2Step { /// @param _id The operation hash (see `hashOperation` function) /// @param _delay The delay time (in seconds) after which the proposed upgrade can be executed by the owner. function _schedule(bytes32 _id, uint256 _delay) internal { + // solhint-disable reason-string require(!isOperation(_id), "Operation with this proposal id already exists"); require(_delay >= minDelay, "Proposed delay is less than minimum delay"); + // solhint-enable reason-string timestamps[_id] = block.timestamp + _delay; } @@ -226,6 +237,7 @@ contract Governance is IGovernance, Ownable2Step { /// @dev Execute an operation's calls. /// @param _calls The array of calls to be executed. function _execute(Call[] calldata _calls) internal { + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _calls.length; ++i) { // slither-disable-next-line arbitrary-send-eth (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data); @@ -242,6 +254,7 @@ contract Governance is IGovernance, Ownable2Step { /// @param _predecessorId The hash of the operation that should be completed. /// @dev Doesn't check the operation to be complete if the input is zero. function _checkPredecessorDone(bytes32 _predecessorId) internal view { + // solhint-disable-next-line reason-string require(_predecessorId == bytes32(0) || isOperationDone(_predecessorId), "Predecessor operation not completed"); } diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index d201c8333..d275075d6 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -16,6 +16,7 @@ import {FeeParams} from "./chain-deps/ZkSyncHyperchainStorage.sol"; /// @param genesisBatchCommitment The zk-proof commitment for the genesis batch /// @param diamondCut The diamond cut for the first upgrade transaction on the newly deployed chain /// @param protocolVersion The initial protocol version on the newly deployed chain +// solhint-disable-next-line gas-struct-packing struct StateTransitionManagerInitializeData { address owner; address validatorTimelock; diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index 7271b253d..a152da054 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import {Diamond} from "./libraries/Diamond.sol"; @@ -88,7 +90,8 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own function getAllHyperchains() public view override returns (address[] memory chainAddresses) { uint256[] memory keys = hyperchainMap.keys(); chainAddresses = new address[](keys.length); - for (uint256 i = 0; i < keys.length; i++) { + uint256 keysLength = keys.length; + for (uint256 i = 0; i < keysLength; ++i) { chainAddresses[i] = hyperchainMap.get(i); } } diff --git a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol index d793783d6..396276306 100644 --- a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol +++ b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {LibMap} from "./libraries/LibMap.sol"; import {IExecutor} from "./chain-interfaces/IExecutor.sol"; @@ -52,7 +54,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { uint32 public executionDelay; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 internal immutable ERA_CHAIN_ID; constructor(address _initialOwner, uint32 _executionDelay, uint256 _eraChainId) { _transferOwnership(_initialOwner); @@ -130,6 +132,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { // This contract is only a temporary solution, that hopefully will be disabled until 2106 year, so... // It is safe to cast. uint32 timestamp = uint32(block.timestamp); + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; ++i) { committedBatchTimestamp[_chainId].set(_newBatchesData[i].batchNumber, timestamp); } @@ -193,6 +196,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { function _executeBatchesInner(uint256 _chainId, StoredBatchInfo[] calldata _newBatchesData) internal { uint256 delay = executionDelay; // uint32 unchecked { + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; ++i) { uint256 commitBatchTimestamp = committedBatchTimestamp[_chainId].get(_newBatchesData[i].batchNumber); diff --git a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol index 424223396..145056590 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Diamond} from "../libraries/Diamond.sol"; import {ZkSyncHyperchainBase} from "./facets/ZkSyncHyperchainBase.sol"; import {L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_GAS_PER_TRANSACTION} from "../../common/Config.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol b/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol index 5cf26ac82..db29da126 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Diamond} from "../libraries/Diamond.sol"; /// @title Diamond Proxy Contract (EIP-2535) diff --git a/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol b/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol index e76d86f24..a06921fdb 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol @@ -63,6 +63,7 @@ struct FeeParams { /// but NOT to modify already existing variables or change their order. /// NOTE: variables prefixed with '__DEPRECATED_' are deprecated and shouldn't be used. /// Their presence is maintained for compatibility and to prevent storage collision. +// solhint-disable-next-line gas-struct-packing struct ZkSyncHyperchainStorage { /// @dev Storage of variables needed for deprecated diamond cut facet uint256[7] __DEPRECATED_diamondCutStorage; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol index 7eb6e7904..fd1f4929a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors, reason-string + import {IAdmin} from "../../chain-interfaces/IAdmin.sol"; import {Diamond} from "../../libraries/Diamond.sol"; import {MAX_GAS_PER_TRANSACTION} from "../../../common/Config.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 506379eb4..169426871 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors, reason-string + import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER, COMMIT_TIMESTAMP_APPROXIMATION_DELTA, EMPTY_STRING_KECCAK, L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, PACKED_L2_BLOCK_TIMESTAMP_MASK, PUBLIC_INPUT_SHIFT, POINT_EVALUATION_PRECOMPILE_ADDR} from "../../../common/Config.sol"; import {IExecutor, L2_LOG_ADDRESS_OFFSET, L2_LOG_KEY_OFFSET, L2_LOG_VALUE_OFFSET, SystemLogKey, LogProcessingOutput, PubdataSource, BLS_MODULUS, PUBDATA_COMMITMENT_SIZE, PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET, PUBDATA_COMMITMENT_COMMITMENT_OFFSET, MAX_NUMBER_OF_BLOBS, TOTAL_BLOBS_IN_COMMITMENT, BLOB_SIZE_BYTES} from "../../chain-interfaces/IExecutor.sol"; @@ -146,7 +148,8 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { uint256 processedLogs; // linear traversal of the logs - for (uint256 i = 0; i < emittedL2Logs.length; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { + uint256 logsLength = emittedL2Logs.length; + for (uint256 i = 0; i < logsLength; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { // Extract the values to be compared to/used such as the log sender, key, and value // slither-disable-next-line unused-return (address logSender, ) = UnsafeBytes.readAddress(emittedL2Logs, i + L2_LOG_ADDRESS_OFFSET); @@ -212,7 +215,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { /// @inheritdoc IExecutor function commitBatches( - StoredBatchInfo memory _lastCommittedBatchData, + StoredBatchInfo calldata _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) external nonReentrant onlyValidator { _commitBatches(_lastCommittedBatchData, _newBatchesData); @@ -221,7 +224,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { /// @inheritdoc IExecutor function commitBatchesSharedBridge( uint256, // _chainId - StoredBatchInfo memory _lastCommittedBatchData, + StoredBatchInfo calldata _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) external nonReentrant onlyValidator { _commitBatches(_lastCommittedBatchData, _newBatchesData); @@ -269,6 +272,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) internal { + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { _lastCommittedBatchData = _commitOneBatch(_lastCommittedBatchData, _newBatchesData[i], bytes32(0)); @@ -301,6 +305,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // Save the batch number where the upgrade transaction was executed. s.l2SystemContractsUpgradeBatchNumber = _newBatchesData[0].batchNumber; + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { // The upgrade transaction must only be included in the first batch. bytes32 expectedUpgradeTxHash = i == 0 ? _systemContractUpgradeTxHash : bytes32(0); @@ -566,7 +571,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { blobAuxOutputWords = new bytes32[](2 * TOTAL_BLOBS_IN_COMMITMENT); - for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { blobAuxOutputWords[i * 2] = _blobHashes[i]; blobAuxOutputWords[i * 2 + 1] = _blobCommitments[i]; } @@ -622,6 +627,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { require(_pubdataCommitments.length % PUBDATA_COMMITMENT_SIZE == 0, "bs"); blobCommitments = new bytes32[](MAX_NUMBER_OF_BLOBS); + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _pubdataCommitments.length; i += PUBDATA_COMMITMENT_SIZE) { bytes32 blobVersionedHash = _getBlobVersionedHash(versionedHashIndex); @@ -643,7 +649,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { blobCommitments[versionedHashIndex] = keccak256( abi.encodePacked(blobVersionedHash, _pubdataCommitments[i:i + PUBDATA_COMMITMENT_COMMITMENT_OFFSET]) ); - versionedHashIndex += 1; + ++versionedHashIndex; } // This check is required because we want to ensure that there aren't any extra blobs trying to be published. @@ -653,7 +659,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // We verify that for each set of blobHash/blobCommitment are either both empty // or there are values for both. - for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { require( (_blobHashes[i] == bytes32(0) && blobCommitments[i] == bytes32(0)) || (_blobHashes[i] != bytes32(0) && blobCommitments[i] != bytes32(0)), diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol index 1769dceca..3c72805eb 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; import {VerifierParams} from "../../../state-transition/chain-interfaces/IVerifier.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol index 752913b3f..a65a47b55 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {IMailbox} from "../../chain-interfaces/IMailbox.sol"; @@ -34,7 +36,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { string public constant override getName = "MailboxFacet"; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 public immutable ERA_CHAIN_ID; constructor(uint256 _eraChainId) { ERA_CHAIN_ID = _eraChainId; @@ -60,7 +62,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { function proveL2MessageInclusion( uint256 _batchNumber, uint256 _index, - L2Message memory _message, + L2Message calldata _message, bytes32[] calldata _proof ) public view returns (bool) { return _proveL2LogInclusion(_batchNumber, _index, _L2MessageToLog(_message), _proof); @@ -70,7 +72,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { function proveL2LogInclusion( uint256 _batchNumber, uint256 _index, - L2Log memory _log, + L2Log calldata _log, bytes32[] calldata _proof ) external view returns (bool) { return _proveL2LogInclusion(_batchNumber, _index, _log, _proof); @@ -134,7 +136,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { } /// @dev Convert arbitrary-length message to the raw l2 log - function _L2MessageToLog(L2Message memory _message) internal pure returns (L2Log memory) { + function _L2MessageToLog(L2Message calldata _message) internal pure returns (L2Log memory) { return L2Log({ l2ShardId: 0, @@ -279,6 +281,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { request.refundRecipient = AddressAliasHelper.actualRefundRecipient(request.refundRecipient, request.sender); // Change the sender address if it is a smart contract to prevent address collision between L1 and L2. // Please note, currently zkSync address derivation is different from Ethereum one, but it may be changed in the future. + // solhint-disable avoid-tx-origin // slither-disable-next-line tx-origin if (request.sender != tx.origin) { request.sender = AddressAliasHelper.applyL1ToL2Alias(request.sender); diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol index 59662d409..3c855e87a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {ZkSyncHyperchainStorage} from "../ZkSyncHyperchainStorage.sol"; import {ReentrancyGuard} from "../../../common/ReentrancyGuard.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol index eaa61c3e5..a8209b546 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol @@ -21,6 +21,7 @@ import {FeeParams} from "../chain-deps/ZkSyncHyperchainStorage.sol"; /// @param priorityTxMaxGasLimit maximum number of the L2 gas that a user can request for L1 -> L2 transactions /// @param feeParams Fee parameters to be used for L1->L2 transactions /// @param blobVersionedHashRetriever Address of contract used to pull the blob versioned hash for a transaction. +// solhint-disable-next-line gas-struct-packing struct InitializeData { uint256 chainId; address bridgehub; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol index 43a7485c7..149b97027 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol @@ -88,6 +88,7 @@ interface IExecutor is IZkSyncHyperchainBase { /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant /// @param commitment Verified input for the zkSync circuit + // solhint-disable-next-line gas-struct-packing struct StoredBatchInfo { uint64 batchNumber; bytes32 batchHash; diff --git a/l1-contracts/contracts/state-transition/libraries/Diamond.sol b/l1-contracts/contracts/state-transition/libraries/Diamond.sol index 4e44375da..8699f750e 100644 --- a/l1-contracts/contracts/state-transition/libraries/Diamond.sol +++ b/l1-contracts/contracts/state-transition/libraries/Diamond.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; @@ -59,6 +61,7 @@ library Diamond { /// @param action The action that is made on the facet /// @param isFreezable Denotes whether the facet & all their selectors can be frozen /// @param selectors An array of unique selectors that belongs to the facet address + // solhint-disable-next-line gas-struct-packing struct FacetCut { address facet; Action action; diff --git a/l1-contracts/contracts/state-transition/libraries/Merkle.sol b/l1-contracts/contracts/state-transition/libraries/Merkle.sol index ec31073aa..8680f9ac6 100644 --- a/l1-contracts/contracts/state-transition/libraries/Merkle.sol +++ b/l1-contracts/contracts/state-transition/libraries/Merkle.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; /// @author Matter Labs diff --git a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol index cb43068df..186ecda09 100644 --- a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol +++ b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + /// @notice The structure that contains meta information of the L2 transaction that was requested from L1 /// @dev The weird size of fields was selected specifically to minimize the structure storage size /// @param canonicalTxHash Hashed L2 transaction data that is needed to process it diff --git a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol index 71ef18a86..86bdb4294 100644 --- a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol +++ b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {L2CanonicalTransaction} from "../../common/Messaging.sol"; diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol index 07185b095..597563b03 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {ZkSyncHyperchainBase} from "../state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol"; import {VerifierParams} from "../state-transition/chain-interfaces/IVerifier.sol"; import {IVerifier} from "../state-transition/chain-interfaces/IVerifier.sol"; @@ -221,8 +223,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { function _verifyFactoryDeps(bytes[] calldata _factoryDeps, uint256[] calldata _expectedHashes) private pure { require(_factoryDeps.length == _expectedHashes.length, "Wrong number of factory deps"); require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "Factory deps can be at most 32"); + uint256 length = _factoryDeps.length; - for (uint256 i = 0; i < _factoryDeps.length; ++i) { + for (uint256 i = 0; i < length; ++i) { require( L2ContractHelper.hashL2Bytecode(_factoryDeps[i]) == bytes32(_expectedHashes[i]), "Wrong factory dep hash" diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol index 4dccf4565..656ddda13 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {MAX_ALLOWED_PROTOCOL_VERSION_DELTA} from "../common/Config.sol"; import {BaseZkSyncUpgrade} from "./BaseZkSyncUpgrade.sol"; +import {ProtocolVersionShouldBeGreater, ProtocolVersionDeltaTooLarge, PreviousUpgradeNotFinalized, PreviousUpgradeBatchNotCleared} from "./ZkSyncUpgradeErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -13,22 +14,25 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { /// @param _newProtocolVersion The new protocol version function _setNewProtocolVersion(uint256 _newProtocolVersion) internal override { uint256 previousProtocolVersion = s.protocolVersion; - require( + if ( // IMPORTANT Genesis Upgrade difference: Note this is the only thing change > to >= - _newProtocolVersion >= previousProtocolVersion, - "New protocol version is not greater than the current one" - ); - require( - _newProtocolVersion - previousProtocolVersion <= MAX_ALLOWED_PROTOCOL_VERSION_DELTA, - "Too big protocol version difference" - ); + _newProtocolVersion < previousProtocolVersion + ) { + revert ProtocolVersionShouldBeGreater(previousProtocolVersion, _newProtocolVersion); + } + uint256 protocolDiff = _newProtocolVersion - previousProtocolVersion; + if (protocolDiff > MAX_ALLOWED_PROTOCOL_VERSION_DELTA) { + revert ProtocolVersionDeltaTooLarge(protocolDiff, MAX_ALLOWED_PROTOCOL_VERSION_DELTA); + } // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. - require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); - require( - s.l2SystemContractsUpgradeBatchNumber == 0, - "The batch number of the previous upgrade has not been cleaned" - ); + if (s.l2SystemContractsUpgradeTxHash != bytes32(0)) { + revert PreviousUpgradeNotFinalized(); + } + + if (s.l2SystemContractsUpgradeBatchNumber != 0) { + revert PreviousUpgradeBatchNotCleared(); + } s.protocolVersion = _newProtocolVersion; emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion); diff --git a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol index ded2df649..32d6e4380 100644 --- a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol +++ b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Diamond} from "../state-transition/libraries/Diamond.sol"; import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; import {ETH_TOKEN_ADDRESS} from "../common/Config.sol"; diff --git a/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol b/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol index baca21ab6..7db229f95 100644 --- a/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol +++ b/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Diamond} from "../state-transition/libraries/Diamond.sol"; import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; import {PubdataPricingMode, FeeParams} from "../state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; @@ -9,11 +11,11 @@ import {PubdataPricingMode, FeeParams} from "../state-transition/chain-deps/ZkSy /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev contract Upgrade_v1_4_1 is BaseZkSyncUpgrade { - uint32 constant PRIORITY_TX_BATCH_OVERHEAD_L1_GAS = 1_000_000; - uint32 constant PRIORITY_TX_PUBDATA_PER_BATCH = 120_000; - uint32 constant PRIORITY_TX_MAX_GAS_PER_BATCH = 80_000_000; - uint32 constant PRIORITY_TX_MAX_PUBDATA = 99_000; - uint64 constant PRIORITY_TX_MINIMAL_GAS_PRICE = 250_000_000; + uint32 private constant PRIORITY_TX_BATCH_OVERHEAD_L1_GAS = 1_000_000; + uint32 private constant PRIORITY_TX_PUBDATA_PER_BATCH = 120_000; + uint32 private constant PRIORITY_TX_MAX_GAS_PER_BATCH = 80_000_000; + uint32 private constant PRIORITY_TX_MAX_PUBDATA = 99_000; + uint64 private constant PRIORITY_TX_MINIMAL_GAS_PRICE = 250_000_000; /// This event is an exact copy of the "IAdmin.NewFeeParams" event. Since they have the same name and parameters, /// these will be tracked by indexers in the same manner. diff --git a/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol new file mode 100644 index 000000000..d2e78011b --- /dev/null +++ b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +error ProtocolVersionShouldBeGreater(uint256 _oldProtocolVersion, uint256 _newProtocolVersion); +error ProtocolVersionDeltaTooLarge(uint256 _proposedDelta, uint256 _maxDelta); +error PreviousUpgradeNotFinalized(); +error PreviousUpgradeBatchNotCleared(); diff --git a/l1-contracts/contracts/vendor/AddressAliasHelper.sol b/l1-contracts/contracts/vendor/AddressAliasHelper.sol index 19f3b2d79..fe705cfc3 100644 --- a/l1-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l1-contracts/contracts/vendor/AddressAliasHelper.sol @@ -19,7 +19,7 @@ pragma solidity 0.8.24; library AddressAliasHelper { - uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); + uint160 private constant offset = uint160(0x1111000000000000000000000000000000001111); /// @notice Utility function converts the address that submitted a tx /// to the inbox on L1 to the msg.sender viewed on L2 @@ -51,6 +51,7 @@ library AddressAliasHelper { ) internal view returns (address _recipient) { if (_refundRecipient == address(0)) { // If the `_refundRecipient` is not provided, we use the `_prevMsgSender` as the recipient. + // solhint-disable avoid-tx-origin // slither-disable-next-line tx-origin _recipient = _prevMsgSender == tx.origin ? _prevMsgSender diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index dad521718..97b165ced 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -6,5 +6,13 @@ cache_path = 'cache-forge' test = 'test/foundry' solc_version = "0.8.24" evm_version = "cancun" +ignored_error_codes = [ + "missing-receive-ether", + "code-size", +] +ignored_warnings_from = [ + "test", + "contracts/dev-contracts" +] # See more config options https://github.com/foundry-rs/foundry/tree/master/crates/config diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol index cb7251185..7f7b7dfad 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol @@ -118,7 +118,7 @@ contract StateTransitionManagerTest is Test { vm.startPrank(governor); } - function getDiamondCutData(address _diamondInit) internal returns (Diamond.DiamondCutData memory) { + function getDiamondCutData(address _diamondInit) internal view returns (Diamond.DiamondCutData memory) { InitializeDataNewChain memory initializeData = Utils.makeInitializeDataForNewChain(testnetVerifier); bytes memory initCalldata = abi.encode(initializeData); diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index b9bd70c61..0b550819d 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -3,96 +3,96 @@ "name": "DAI", "symbol": "DAI", "decimals": 18, - "address": "0xfCdA09988fC2433BFE27BBe9e95E0C007ee272Fd" + "address": "0x3202935CA01eADd2F0B4e7aA23EFA52315121172" }, { "name": "wBTC", "symbol": "wBTC", "decimals": 8, - "address": "0x3b78cDD294f0b34755c8a9bA8f124Cb6c217b60a" + "address": "0xe73a1c05498e492f182f9B3E3cd65b2F9f52eE94" }, { "name": "BAT", "symbol": "BAT", "decimals": 18, - "address": "0xd4a9D970EF600289dC96b67505027D17604FBfe1" + "address": "0x7aAE2ee8317b384aDE246664933A147411b60045" }, { "name": "GNT", "symbol": "GNT", "decimals": 18, - "address": "0x4fE0EE70D78132fBb5C68C1d5e0020f3c05542f2" + "address": "0x02a344d1e31e92e39c2681937645F1d668C37d4e" }, { "name": "MLTT", "symbol": "MLTT", "decimals": 18, - "address": "0x3202935CA01eADd2F0B4e7aA23EFA52315121172" + "address": "0x28033f8EdB2F43747E55401C4a3E3b4b2cF5146C" }, { "name": "DAIK", "symbol": "DAIK", "decimals": 18, - "address": "0xe73a1c05498e492f182f9B3E3cd65b2F9f52eE94" + "address": "0x147dCc3a8E99794C2Ec79EaF1a142324D6778255" }, { "name": "wBTCK", "symbol": "wBTCK", "decimals": 8, - "address": "0x7aAE2ee8317b384aDE246664933A147411b60045" + "address": "0x74cA8715E29196Bfbcd7444B09203d22dDaF7d1a" }, { "name": "BATK", "symbol": "BATS", "decimals": 18, - "address": "0x02a344d1e31e92e39c2681937645F1d668C37d4e" + "address": "0x2eAf3eac597d23db3A8427329482aE47935141d9" }, { "name": "GNTK", "symbol": "GNTS", "decimals": 18, - "address": "0x28033f8EdB2F43747E55401C4a3E3b4b2cF5146C" + "address": "0x2B1b32d23f2be391280bFbD2B51daB8Ad2a69B9e" }, { "name": "MLTTK", "symbol": "MLTTS", "decimals": 18, - "address": "0x147dCc3a8E99794C2Ec79EaF1a142324D6778255" + "address": "0xc2Ca10940Ad80Cd98512B767457bd44713232B5a" }, { "name": "DAIL", "symbol": "DAIL", "decimals": 18, - "address": "0x74cA8715E29196Bfbcd7444B09203d22dDaF7d1a" + "address": "0xd6b4CDa9F0Ef6d9F6b35Ab5424df0dD95E6a6D1b" }, { "name": "wBTCL", "symbol": "wBTCP", "decimals": 8, - "address": "0x2eAf3eac597d23db3A8427329482aE47935141d9" + "address": "0x15CD4a1C10AE2D3727Dad680a1966947931588C9" }, { "name": "BATL", "symbol": "BATW", "decimals": 18, - "address": "0x2B1b32d23f2be391280bFbD2B51daB8Ad2a69B9e" + "address": "0x45f430CFD5Bf38eCE39f1B9A2930B3fD494619e8" }, { "name": "GNTL", "symbol": "GNTW", "decimals": 18, - "address": "0xc2Ca10940Ad80Cd98512B767457bd44713232B5a" + "address": "0x801Ab08819573537C0B256d139473eF13482B3Dd" }, { "name": "MLTTL", "symbol": "MLTTW", "decimals": 18, - "address": "0xd6b4CDa9F0Ef6d9F6b35Ab5424df0dD95E6a6D1b" + "address": "0xf55F3af54B9a507Bd0260e5844C1648921214745" }, { "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, - "address": "0x15CD4a1C10AE2D3727Dad680a1966947931588C9" + "address": "0xed01DF970925Cc0BB427f9E8014449C8a529D303" } ] diff --git a/l2-contracts/contracts/L2ContractErrors.sol b/l2-contracts/contracts/L2ContractErrors.sol new file mode 100644 index 000000000..98b5048b3 --- /dev/null +++ b/l2-contracts/contracts/L2ContractErrors.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +error InvalidCaller(address); +error InvalidInput(); +error InsufficientAllowance(uint256 providedAllowance, uint256 requiredAmount); +error FailedToTransferTokens(address tokenContract, address to, uint256 amount); +error UnsupportedPaymasterFlow(); +error EmptyAddress(); +error EmptyBytes32(); +error AddressMismatch(address expected, address supplied); +error AmountMustBeGreaterThanZero(); +error DeployFailed(); +error Unauthorized(); +error NonSequentialVersion(); +error Unimplemented(); +error UnimplementedMessage(string); +error WithdrawFailed(); + +string constant BRIDGE_MINT_NOT_IMPLEMENTED = "bridgeMint is not implemented! Use deposit/depositTo methods instead."; diff --git a/l2-contracts/contracts/SystemContractsCaller.sol b/l2-contracts/contracts/SystemContractsCaller.sol index 36153eb6d..97753cbac 100644 --- a/l2-contracts/contracts/SystemContractsCaller.sol +++ b/l2-contracts/contracts/SystemContractsCaller.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT +// solhint-disable one-contract-per-file + pragma solidity 0.8.20; import {MSG_VALUE_SYSTEM_CONTRACT} from "./L2ContractHelper.sol"; @@ -23,9 +25,14 @@ enum CalldataForwardingMode { UseAuxHeap } +/// @notice Error thrown a cast from uint256 to u32 is not possible. +error U32CastOverflow(); + library Utils { function safeCastToU32(uint256 _x) internal pure returns (uint32) { - require(_x <= type(uint32).max, "Overflow"); + if (_x > type(uint32).max) { + revert U32CastOverflow(); + } return uint32(_x); } diff --git a/l2-contracts/contracts/TestnetPaymaster.sol b/l2-contracts/contracts/TestnetPaymaster.sol index 41ce678c1..6a85ff84c 100644 --- a/l2-contracts/contracts/TestnetPaymaster.sol +++ b/l2-contracts/contracts/TestnetPaymaster.sol @@ -7,6 +7,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IPaymaster, ExecutionResult, PAYMASTER_VALIDATION_SUCCESS_MAGIC} from "./interfaces/IPaymaster.sol"; import {IPaymasterFlow} from "./interfaces/IPaymasterFlow.sol"; import {Transaction, BOOTLOADER_ADDRESS} from "./L2ContractHelper.sol"; +import {InvalidCaller, InvalidInput, InsufficientAllowance, FailedToTransferTokens, UnsupportedPaymasterFlow} from "./L2ContractErrors.sol"; // This is a dummy paymaster. It expects the paymasterInput to contain its "signature" as well as the needed exchange rate. // It supports only approval-based paymaster flow. @@ -19,8 +20,13 @@ contract TestnetPaymaster is IPaymaster { // By default we consider the transaction as accepted. magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; - require(msg.sender == BOOTLOADER_ADDRESS, "Only bootloader can call this contract"); - require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long"); + if (msg.sender != BOOTLOADER_ADDRESS) { + revert InvalidCaller(msg.sender); + } + + if (_transaction.paymasterInput.length < 4) { + revert InvalidInput(); + } bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]); if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { @@ -33,7 +39,9 @@ contract TestnetPaymaster is IPaymaster { address thisAddress = address(this); uint256 providedAllowance = IERC20(token).allowance(userAddress, thisAddress); - require(providedAllowance >= amount, "The user did not provide enough allowance"); + if (providedAllowance < amount) { + revert InsufficientAllowance(providedAllowance, amount); + } // The testnet paymaster exchanges X wei of the token to the X wei of ETH. uint256 requiredETH = _transaction.gasLimit * _transaction.maxFeePerGas; @@ -51,7 +59,7 @@ contract TestnetPaymaster is IPaymaster { // If the revert reason is empty or represented by just a function selector, // we replace the error with a more user-friendly message if (revertReason.length <= 4) { - revert("Failed to transferFrom from users' account"); + revert FailedToTransferTokens(token, thisAddress, amount); } else { assembly { revert(add(0x20, revertReason), mload(revertReason)) @@ -61,9 +69,11 @@ contract TestnetPaymaster is IPaymaster { // The bootloader never returns any data, so it can safely be ignored here. (bool success, ) = payable(BOOTLOADER_ADDRESS).call{value: requiredETH}(""); - require(success, "Failed to transfer funds to the bootloader"); + if (!success) { + revert FailedToTransferTokens(address(0), BOOTLOADER_ADDRESS, requiredETH); + } } else { - revert("Unsupported paymaster flow"); + revert UnsupportedPaymasterFlow(); } } diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index 82c5bc615..e8102022b 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -15,6 +15,8 @@ import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; import {L2ContractHelper, DEPLOYER_SYSTEM_CONTRACT, IContractDeployer} from "../L2ContractHelper.sol"; import {SystemContractsCaller} from "../SystemContractsCaller.sol"; +import {EmptyAddress, EmptyBytes32, InvalidCaller, AddressMismatch, AmountMustBeGreaterThanZero, DeployFailed} from "../L2ContractErrors.sol"; + /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev /// @notice The "default" bridge implementation for the ERC20 tokens. Note, that it does not @@ -35,10 +37,10 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { address private l1LegacyBridge; + uint256 internal immutable ERA_CHAIN_ID; + /// @dev Contract is expected to be used as proxy implementation. /// @dev Disable the initialization to prevent Parity hack. - uint256 immutable ERA_CHAIN_ID; - constructor(uint256 _eraChainId) { ERA_CHAIN_ID = _eraChainId; _disableInitializers(); @@ -54,9 +56,17 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { bytes32 _l2TokenProxyBytecodeHash, address _aliasedOwner ) external reinitializer(2) { - require(_l1Bridge != address(0), "bf"); - require(_l2TokenProxyBytecodeHash != bytes32(0), "df"); - require(_aliasedOwner != address(0), "sf"); + if (_l1Bridge == address(0)) { + revert EmptyAddress(); + } + + if (_l2TokenProxyBytecodeHash == bytes32(0)) { + revert EmptyBytes32(); + } + + if (_aliasedOwner == address(0)) { + revert EmptyAddress(); + } l1Bridge = _l1Bridge; @@ -66,7 +76,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; l2TokenBeacon.transferOwnership(_aliasedOwner); } else { - require(_l1LegacyBridge != address(0), "bf2"); + if (_l1LegacyBridge == address(0)) { + revert EmptyAddress(); + } l1LegacyBridge = _l1LegacyBridge; // l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy } @@ -86,20 +98,26 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { bytes calldata _data ) external override { // Only the L1 bridge counterpart can initiate and finalize the deposit. - require( - AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge || - AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1LegacyBridge, - "mq" - ); + if ( + AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1Bridge && + AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1LegacyBridge + ) { + revert InvalidCaller(msg.sender); + } address expectedL2Token = l2TokenAddress(_l1Token); address currentL1Token = l1TokenAddress[expectedL2Token]; if (currentL1Token == address(0)) { address deployedToken = _deployL2Token(_l1Token, _data); - require(deployedToken == expectedL2Token, "mt"); + if (deployedToken != expectedL2Token) { + revert AddressMismatch(expectedL2Token, deployedToken); + } + l1TokenAddress[expectedL2Token] = _l1Token; } else { - require(currentL1Token == _l1Token, "gg"); // Double check that the expected value equal to real one + if (currentL1Token != _l1Token) { + revert AddressMismatch(_l1Token, currentL1Token); + } } IL2StandardToken(expectedL2Token).bridgeMint(_l2Receiver, _amount); @@ -122,12 +140,16 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { /// @param _l2Token The L2 token address which is withdrawn /// @param _amount The total amount of tokens to be withdrawn function withdraw(address _l1Receiver, address _l2Token, uint256 _amount) external override { - require(_amount > 0, "Amount cannot be zero"); + if (_amount == 0) { + revert AmountMustBeGreaterThanZero(); + } IL2StandardToken(_l2Token).bridgeBurn(msg.sender, _amount); address l1Token = l1TokenAddress[_l2Token]; - require(l1Token != address(0), "yh"); + if (l1Token == address(0)) { + revert EmptyAddress(); + } bytes memory message = _getL1WithdrawMessage(_l1Receiver, l1Token, _amount); L2ContractHelper.sendMessageToL1(message); @@ -174,7 +196,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { ); // The deployment should be successful and return the address of the proxy - require(success, "mk"); + if (!success) { + revert DeployFailed(); + } proxy = BeaconProxy(abi.decode(returndata, (address))); } } diff --git a/l2-contracts/contracts/bridge/L2StandardERC20.sol b/l2-contracts/contracts/bridge/L2StandardERC20.sol index d72608368..2104629f4 100644 --- a/l2-contracts/contracts/bridge/L2StandardERC20.sol +++ b/l2-contracts/contracts/bridge/L2StandardERC20.sol @@ -7,6 +7,7 @@ import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/Upgradeabl import {ERC1967Upgrade} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; import {IL2StandardToken} from "./interfaces/IL2StandardToken.sol"; +import {EmptyAddress, Unauthorized, NonSequentialVersion, Unimplemented} from "../L2ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -47,8 +48,10 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg /// @param _l1Address Address of the L1 token that can be deposited to mint this L2 token /// @param _data The additional data that the L1 bridge provide for initialization. /// In this case, it is packed `name`/`symbol`/`decimals` of the L1 token. - function bridgeInitialize(address _l1Address, bytes memory _data) external initializer { - require(_l1Address != address(0), "in6"); // Should be non-zero address + function bridgeInitialize(address _l1Address, bytes calldata _data) external initializer { + if (_l1Address == address(0)) { + revert EmptyAddress(); + } l1Address = _l1Address; l2Bridge = msg.sender; @@ -110,14 +113,16 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg /// to ensure that the governor can not accidentally disable future reinitialization of the token. function reinitializeToken( ERC20Getters calldata _availableGetters, - string memory _newName, - string memory _newSymbol, + string calldata _newName, + string calldata _newSymbol, uint8 _version ) external onlyNextVersion(_version) reinitializer(_version) { // It is expected that this token is deployed as a beacon proxy, so we'll // allow the governor of the beacon to reinitialize the token. address beaconAddress = _getBeacon(); - require(msg.sender == UpgradeableBeacon(beaconAddress).owner(), "tt"); + if (msg.sender != UpgradeableBeacon(beaconAddress).owner()) { + revert Unauthorized(); + } __ERC20_init_unchained(_newName, _newSymbol); __ERC20Permit_init(_newName); @@ -127,14 +132,18 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg } modifier onlyBridge() { - require(msg.sender == l2Bridge, "xnt"); // Only L2 bridge can call this method + if (msg.sender != l2Bridge) { + revert Unauthorized(); + } _; } modifier onlyNextVersion(uint8 _version) { // The version should be incremented by 1. Otherwise, the governor risks disabling // future reinitialization of the token by providing too large a version. - require(_version == _getInitializedVersion() + 1, "v"); + if (_version != _getInitializedVersion() + 1) { + revert NonSequentialVersion(); + } _; } @@ -158,29 +167,29 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg function name() public view override returns (string memory) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreName) revert(); + if (availableGetters.ignoreName) revert Unimplemented(); return super.name(); } function symbol() public view override returns (string memory) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreSymbol) revert(); + if (availableGetters.ignoreSymbol) revert Unimplemented(); return super.symbol(); } function decimals() public view override returns (uint8) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreDecimals) revert(); + if (availableGetters.ignoreDecimals) revert Unimplemented(); return decimals_; } /// @dev External function to decode a string from bytes. - function decodeString(bytes memory _input) external pure returns (string memory result) { + function decodeString(bytes calldata _input) external pure returns (string memory result) { (result) = abi.decode(_input, (string)); } /// @dev External function to decode a uint8 from bytes. - function decodeUint8(bytes memory _input) external pure returns (uint8 result) { + function decodeUint8(bytes calldata _input) external pure returns (uint8 result) { (result) = abi.decode(_input, (uint8)); } } diff --git a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol index 8cf4d7b5c..8fc3b05b9 100644 --- a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol +++ b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol @@ -7,6 +7,8 @@ import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ import {IL2WrappedBaseToken} from "./interfaces/IL2WrappedBaseToken.sol"; import {IL2StandardToken} from "./interfaces/IL2StandardToken.sol"; +import {EmptyAddress, Unauthorized, UnimplementedMessage, BRIDGE_MINT_NOT_IMPLEMENTED, WithdrawFailed} from "../L2ContractErrors.sol"; + /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev /// @notice The canonical implementation of the WETH token. @@ -42,13 +44,18 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S /// @param _l1Address Address of the L1 token that can be deposited to mint this L2 WETH. /// Note: The decimals are hardcoded to 18, the same as on Ether. function initializeV2( - string memory name_, - string memory symbol_, + string calldata name_, + string calldata symbol_, address _l2Bridge, address _l1Address ) external reinitializer(2) { - require(_l2Bridge != address(0), "L2 bridge address cannot be zero"); - require(_l1Address != address(0), "L1 WETH token address cannot be zero"); + if (_l2Bridge == address(0)) { + revert EmptyAddress(); + } + + if (_l1Address == address(0)) { + revert EmptyAddress(); + } l2Bridge = _l2Bridge; l1Address = _l1Address; @@ -62,7 +69,9 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S } modifier onlyBridge() { - require(msg.sender == l2Bridge, "permission denied"); // Only L2 bridge can call this method + if (msg.sender != l2Bridge) { + revert Unauthorized(); + } _; } @@ -71,7 +80,7 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S /// Note: Use `deposit`/`depositTo` methods instead. // solhint-disable-next-line no-unused-vars function bridgeMint(address _to, uint256 _amount) external override onlyBridge { - revert("bridgeMint is not implemented! Use deposit/depositTo methods instead."); + revert UnimplementedMessage(BRIDGE_MINT_NOT_IMPLEMENTED); } /// @dev Burn tokens from a given account and send the same amount of Ether to the bridge. @@ -82,7 +91,9 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S _burn(_from, _amount); // sends Ether to the bridge (bool success, ) = msg.sender.call{value: _amount}(""); - require(success, "Failed withdrawal"); + if (!success) { + revert WithdrawFailed(); + } emit BridgeBurn(_from, _amount); } @@ -107,7 +118,9 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S function withdrawTo(address _to, uint256 _amount) public override { _burn(msg.sender, _amount); (bool success, ) = _to.call{value: _amount}(""); - require(success, "Failed withdrawal"); + if (!success) { + revert WithdrawFailed(); + } } /// @dev Fallback function to allow receiving Ether. diff --git a/l2-contracts/contracts/vendor/AddressAliasHelper.sol b/l2-contracts/contracts/vendor/AddressAliasHelper.sol index da0282ed8..33b5e95e8 100644 --- a/l2-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l2-contracts/contracts/vendor/AddressAliasHelper.sol @@ -19,7 +19,7 @@ pragma solidity 0.8.20; library AddressAliasHelper { - uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); + uint160 internal constant offset = uint160(0x1111000000000000000000000000000000001111); /// @notice Utility function converts the address that submitted a tx /// to the inbox on L1 to the msg.sender viewed on L2 diff --git a/package.json b/package.json index 9bb6bdd1e..edb9817b9 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "markdownlint-cli": "^0.33.0", "prettier-plugin-solidity": "^1.1.3", "prettier": "^3.0.3", - "solhint": "^3.6.2" + "solhint": "4.5.4" }, "scripts": { "lint:check": "yarn lint:md && yarn lint:sol && yarn lint:ts && yarn prettier:check", diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 79fba0a88..e56f2dcc0 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,50 +3,50 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x01000075076d9e9ca73d51f8ef0af1bb2e7f74fd8377876ab6bc470a2900a4bf", - "sourceCodeHash": "0xfbf66e830201c4b7fda14f0ddf28a53beb7fbb48a8406392bcfd0ef7ea9265c8" + "bytecodeHash": "0x0100005db7d0621192834d201f8bcd14c6ac987b95f422ca8bb28d500748f1fa", + "sourceCodeHash": "0x69d2533e5481ff13e65f4442e650f4b90c46a48ac643cac9798bbbf421194353" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007d1e60e441b0b776e8f6b1c8a9e0fdd787a944a9d851cd093a3b65b3daa", - "sourceCodeHash": "0x9ff5a2da00acfa145ee4575381ad386587d96b6a0309d05015974f4726881132" + "bytecodeHash": "0x010007c7e006453f3693c1f1c7500b74c594e7a627076be9d2dcb35c1c268dc3", + "sourceCodeHash": "0x26060f33c7c63bd1f8a1a2f3b368b97ef8dd939bc53e95090f2c556248b99dce" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x0100005576cef4b90577db7ca2e5cc02340a0b56ee9473b34756502963551a97", - "sourceCodeHash": "0x0aa5d7ed159e783acde47856b13801b7f2268ba39b2fa50807fe3d705c506e96" + "bytecodeHash": "0x0100004db8b96797e7d854f2c67c2f13d3920dcf82602f77a6ce0e2353304b37", + "sourceCodeHash": "0xdde7c49a94cc3cd34c3e7ced1b5ba45e4740df68d26243871edbe393e7298f7a" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x0100017924bee877f2ab925cfb1c161ef3c19a8a3034da5d4fd76d0c377a3749", - "sourceCodeHash": "0xd43ac120a50398e0d6bdcfcf807154bfeece0c231509a0eb2e00bcad744e60cd" + "bytecodeHash": "0x0100014387fd8393671b5edd2cc5bb58f72d357c033a44c6274fe92abf19f96d", + "sourceCodeHash": "0x63f5f3a541ac5b59736f9117b15f293346d1842fbfe75219f7961e73185315c5" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010005217819daf0124b7ccb96aca43053d0d13c0c8ad8ae7568d811eecbc3bf", - "sourceCodeHash": "0x635301b824f927b4d17b3d9974cf6abbf979dda49e610805637db7c677d5f522" + "bytecodeHash": "0x010004e5219e70c32d67ed1df0c46983a83a382e482abb5c4310ad554f55f738", + "sourceCodeHash": "0x28208c532ed8851077a9bb0a87636215840ce964397ab0767692f956a0fd11b3" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x0100004b3ac74b1706466d4b2f2b401addad6f17fabb7c8b979cea2fe700cbaf", + "bytecodeHash": "0x01000049cd4b556f8ebc05b0bd35d9996e0b65412343bcc8eb6ce14d958dd21f", "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x01000563e438856e95e453dd4380fbcbb2d8657320ebe7b067f88d7e7898d6bb", - "sourceCodeHash": "0xa42423712ddaa8f357d26e46825fda80a9a870d0ac7ff52c98884355f1173ec7" + "bytecodeHash": "0x0100055dbcf921fb36006fa42209bda58bc468eb33257b1782e854ed29273e64", + "sourceCodeHash": "0xeb5ac8fc83e1c8619db058a9b6973958bd6ed1b6f4938f8f4541d702f12e085d" }, { "contractName": "EmptyContract", @@ -59,64 +59,64 @@ "contractName": "GasBoundCaller", "bytecodePath": "artifacts-zk/contracts-preprocessed/GasBoundCaller.sol/GasBoundCaller.json", "sourceCodePath": "contracts-preprocessed/GasBoundCaller.sol", - "bytecodeHash": "0x010000b51b2bae505be6deb2294505457c6e8df65d6b8d08f32d0d85f8610c60", - "sourceCodeHash": "0xd6877ecfd598bcf8abe26ec344949ae8f992d9a8ab1ac8d529a21da521f77923" + "bytecodeHash": "0x010000abbab74213f27d4d7f132761f7315ad84dd2239195f336aa910c9c92fc", + "sourceCodeHash": "0x7774719fe82d1664af19f3f30e9ca2223784374367d32399638671722e9da850" }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003dc7171a0acf2c4290f0ed222e9d2496b02a47202862e2b2dc70436c4a", - "sourceCodeHash": "0x30df621c72cb35b8820b902b91057f72d0214a0e4a6b7ad4c0847e674e8b9df8" + "bytecodeHash": "0x0100003b91f0ceda986543b6b45811b72cb492cdcb80c42d8600185e33f72251", + "sourceCodeHash": "0x4212e99cbc1722887cfb5b4cb967f278ac8642834786f0e3c6f3b324a9316815" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100007d6f907a56f64d3c054ae5e4a8f73499e1d9fdfea09684fc9de9542941", - "sourceCodeHash": "0x51d388adc58f67ef975a94a7978caa60ed8a0df9d3bd9ac723dfcfc540286c70" + "bytecodeHash": "0x0100006f8342acd40c21d8e535e8ceb65d370ad76a116f3a893fa67452bb616f", + "sourceCodeHash": "0x8da495a9fc5aa0d7d20a165a4fc8bc77012bec29c472015ea5ecc0a2bd706137" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002b9ed3fe658cc5fbc4c2d8b4b5325f47a417f9df02e7dba4360f290141c", - "sourceCodeHash": "0x35c189f3babf5c7a9ce2590bed9eb62b59766e358b7733fdb1bc33f4c232f765" + "bytecodeHash": "0x0100029361cc1606b2e55c12bef0a9ccbb36f70f6a12b41593b34053ea93f433", + "sourceCodeHash": "0x3e4c749b52c9fd8e6040b836dac10df29305ee0fc4fc9418326d3197e1630c38" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x010001035dc295d66d39f6f5ae560801400c6ac1141fd1556acabff84c79c22c", - "sourceCodeHash": "0x76ac95c12820d9a02cd1f177eab59092d99463816f2616e1e0f44637bf791a43" + "bytecodeHash": "0x010001055346ab8d4eb1b48ef7e768a95930d4ef6300c57ca173f4a76d1a9258", + "sourceCodeHash": "0x4cdafafd4cfdf410b31641e14487ea657be3af25e5ec1754fcd7ad67ec23d8be" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x01000069227f9b9d7666a4fc7ac51a280f33fd92021f2e8f06a2d5a458930563", - "sourceCodeHash": "0x3f9e0af527875bebcdc20ca4ecb6822305877fd6038e4c4c58854d000b9ac115" + "bytecodeHash": "0x0100005d606dc17844411ee44a09b08e574347fd92fb4df7d1739fe02ebae2cc", + "sourceCodeHash": "0x4834adf62dbaefa1a1c15d36b5ad1bf2826e7d888a17be495f7ed4e4ea381aa8" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000e5e7614688d2be15699477b56c66e3596a16b60c206f3c3e8a4763e6b4", - "sourceCodeHash": "0x91847512344ac5026e9fd396189c23ad9e253f22cb6e2fe65805c20c915797d4" + "bytecodeHash": "0x010000dbe03a15e6478090c69b0565c273a9cb034c8af48b70d8e71baf5ecf94", + "sourceCodeHash": "0xaa2ed3a26af30032c00a612ac327e0cdf5288b7c932ae903462355f863f950cb" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x01000049d12af64a260c7dbfa32b778e60fe6793b73d50388cfdb0d38df4a97c", - "sourceCodeHash": "0xbc62d673c2cf9ba2d2148e5e2f99ea577cd357c6fd3ad7d248f670c750050faa" + "bytecodeHash": "0x01000047abbd0db8bc506c1cb48e3aab878da3e5ea1bbacf1d4b5f46391f2493", + "sourceCodeHash": "0x0568a9a12bdac94c9e055ca303824a6bf4dc4aa503cfe9a2586c7d3dda8d45da" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001b38acd12ee43d880840d48bd0474c519a8076cf28c8930489117e9bc73", - "sourceCodeHash": "0xb90284d78f48a958d082c4c877fc91ec292d05f0e388c6c78e6cce6d3b069a63" + "bytecodeHash": "0x010001a55d8778874657090f2db3a8aeabd491a5f3352f04c89eadabdd92e6ba", + "sourceCodeHash": "0xf23d12ad2f17ad3b26e909fabfdcfaf4e1d158923e7cb8eeb9b5965a0b464406" }, { "contractName": "EventWriter", @@ -185,35 +185,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb38a53b3466209bf803fc2cacd06f9dc4ff9b123a38f6ba41928f735b", - "sourceCodeHash": "0xd5b248e75ad4a0a433c47de88b5a6eb30c3b7b540e0a716e953c07903233c2d1" + "bytecodeHash": "0x010003cbda052f30cd056d0c758c7cc5be2c31f77461591d4be73dc3291b6ca5", + "sourceCodeHash": "0xa13475403f910dff1ea0cf7ebf80633d9dcc37b4f8dd9f0c678a935793580932" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x010009519002105dd21a44bde50b697ffbc607baf3196d2eac80ad06f99e0f4c", - "sourceCodeHash": "0xbecdcccce351008db583c0447c7e1c7e8c69b5806abee65f22119e699e908e9d" + "bytecodeHash": "0x010009519c960b6baa12091cd1f8538d00fa0d7505c81943ba6e379a5f1c9c9e", + "sourceCodeHash": "0xbcdce81799656df718b5dfff4ba6ce8aac82087a78c0c33edb0675e55bb8364c" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d7d5b5c05e49761c406b847fe3ad0db839525b3e4370e9a5b86f2062af", - "sourceCodeHash": "0x533349c05727f117c00727ddcc25814055571afe74827a1d7130b037e131362b" + "bytecodeHash": "0x010008d7f0ddbde3a633aa89aff433666ba28dcf3adb35deb26a207ea1824454", + "sourceCodeHash": "0xe08f6eaca1995981baf257dd86e5dec8b62c1b5ac53a1173142cebca510b7859" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000957163c0f203bb8a7d3eda31cd9024e0572d212cdefc3046d740cd35afc", - "sourceCodeHash": "0xcf9c1d03c4d5c087b5c80b2ced7eff33067121a9ae78e1b0ff4b3eba4b5fbe1d" + "bytecodeHash": "0x01000957fe599ea1dfc3fc958c63b11f46a726d9462078b77c3f28c4db21446c", + "sourceCodeHash": "0x97e33d4d96f9ee25e171add92ec7d725de58904dfc68466e4aae1807e9997dc2" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e7d48764fc25121571a4139372fb3dbfd326416ed4bf5c5857cb7affc4", - "sourceCodeHash": "0x5acea8e48b7e840467552341bcf15670856fa5d671614b398e6bd7141052671d" + "bytecodeHash": "0x010008e756cd4ef7a22e5bf21b357fda5c90223b7947f38cd3749826a6faff68", + "sourceCodeHash": "0x62556a75277d8c72961a1fb9e1d0e1f1cef41c0e8f8d26a6e85cda336a734834" } ] diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 399ea54f5..5df2fdd8b 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.20; import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol"; import {Utils} from "./libraries/Utils.sol"; import {DEPLOYER_SYSTEM_CONTRACT, NONCE_HOLDER_SYSTEM_CONTRACT, CURRENT_MAX_PRECOMPILE_ADDRESS} from "./Constants.sol"; +import {Unauthorized, InvalidCodeHash, CodeHashReason} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -20,10 +21,12 @@ import {DEPLOYER_SYSTEM_CONTRACT, NONCE_HOLDER_SYSTEM_CONTRACT, CURRENT_MAX_PREC * system contracts to enforce the invariants mentioned above. */ contract AccountCodeStorage is IAccountCodeStorage { - bytes32 constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + bytes32 internal constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; modifier onlyDeployer() { - require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract"); + if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { + revert Unauthorized(msg.sender); + } _; } @@ -34,7 +37,9 @@ contract AccountCodeStorage is IAccountCodeStorage { /// but checks whether the bytecode hash corresponds to the constructing smart contract. function storeAccountConstructingCodeHash(address _address, bytes32 _hash) external override onlyDeployer { // Check that code hash corresponds to the deploying smart contract - require(Utils.isContractConstructing(_hash), "Code hash is not for a contract on constructor"); + if (!Utils.isContractConstructing(_hash)) { + revert InvalidCodeHash(CodeHashReason.NotContractOnConstructor); + } _storeCodeHash(_address, _hash); } @@ -45,7 +50,9 @@ contract AccountCodeStorage is IAccountCodeStorage { /// but checks whether the bytecode hash corresponds to the constructed smart contract. function storeAccountConstructedCodeHash(address _address, bytes32 _hash) external override onlyDeployer { // Check that code hash corresponds to the deploying smart contract - require(Utils.isContractConstructed(_hash), "Code hash is not for a constructed contract"); + if (!Utils.isContractConstructed(_hash)) { + revert InvalidCodeHash(CodeHashReason.NotConstructedContract); + } _storeCodeHash(_address, _hash); } @@ -54,7 +61,9 @@ contract AccountCodeStorage is IAccountCodeStorage { function markAccountCodeHashAsConstructed(address _address) external override onlyDeployer { bytes32 codeHash = getRawCodeHash(_address); - require(Utils.isContractConstructing(codeHash), "Code hash is not for a contract on constructor"); + if (!Utils.isContractConstructing(codeHash)) { + revert InvalidCodeHash(CodeHashReason.NotContractOnConstructor); + } // Get the bytecode hash with "isConstructor" flag equal to false bytes32 constructedBytecodeHash = Utils.constructedBytecodeHash(codeHash); diff --git a/system-contracts/contracts/BootloaderUtilities.sol b/system-contracts/contracts/BootloaderUtilities.sol index 5551764dd..0aafee7be 100644 --- a/system-contracts/contracts/BootloaderUtilities.sol +++ b/system-contracts/contracts/BootloaderUtilities.sol @@ -6,6 +6,7 @@ import {IBootloaderUtilities} from "./interfaces/IBootloaderUtilities.sol"; import {Transaction, TransactionHelper, EIP_712_TX_TYPE, LEGACY_TX_TYPE, EIP_2930_TX_TYPE, EIP_1559_TX_TYPE} from "./libraries/TransactionHelper.sol"; import {RLPEncoder} from "./libraries/RLPEncoder.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; +import {UnsupportedTxType, InvalidSig, SigField} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -34,7 +35,7 @@ contract BootloaderUtilities is IBootloaderUtilities { } else if (_transaction.txType == EIP_2930_TX_TYPE) { txHash = encodeEIP2930TransactionHash(_transaction); } else { - revert("Unsupported tx type"); + revert UnsupportedTxType(_transaction.txType); } } @@ -89,7 +90,9 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory vEncoded; { uint256 vInt = uint256(uint8(_transaction.signature[64])); - require(vInt == 27 || vInt == 28, "Invalid v value"); + if (vInt != 27 && vInt != 28) { + revert InvalidSig(SigField.V, vInt); + } // If the `chainId` is specified in the transaction, then the `v` value is encoded as // `35 + y + 2 * chainId == vInt + 8 + 2 * chainId`, where y - parity bit (see EIP-155). @@ -190,7 +193,9 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory vEncoded; { uint256 vInt = uint256(uint8(_transaction.signature[64])); - require(vInt == 27 || vInt == 28, "Invalid v value"); + if (vInt != 27 && vInt != 28) { + revert InvalidSig(SigField.V, vInt); + } vEncoded = RLPEncoder.encodeUint256(vInt - 27); } @@ -287,7 +292,9 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory vEncoded; { uint256 vInt = uint256(uint8(_transaction.signature[64])); - require(vInt == 27 || vInt == 28, "Invalid v value"); + if (vInt != 27 && vInt != 28) { + revert InvalidSig(SigField.V, vInt); + } vEncoded = RLPEncoder.encodeUint256(vInt - 27); } diff --git a/system-contracts/contracts/ComplexUpgrader.sol b/system-contracts/contracts/ComplexUpgrader.sol index 2f4d886cd..009e8994d 100644 --- a/system-contracts/contracts/ComplexUpgrader.sol +++ b/system-contracts/contracts/ComplexUpgrader.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol"; import {FORCE_DEPLOYER} from "./Constants.sol"; +import {Unauthorized, AddressHasNoCode} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -19,9 +20,13 @@ contract ComplexUpgrader is IComplexUpgrader { /// @param _delegateTo the address of the contract to which the calls will be delegated /// @param _calldata the calldata to be delegate called in the `_delegateTo` contract function upgrade(address _delegateTo, bytes calldata _calldata) external payable { - require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER"); + if (msg.sender != FORCE_DEPLOYER) { + revert Unauthorized(msg.sender); + } - require(_delegateTo.code.length > 0, "Delegatee is an EOA"); + if (_delegateTo.code.length == 0) { + revert AddressHasNoCode(_delegateTo); + } (bool success, bytes memory returnData) = _delegateTo.delegatecall(_calldata); assembly { if iszero(success) { diff --git a/system-contracts/contracts/Compressor.sol b/system-contracts/contracts/Compressor.sol index f52c18ed4..73582f639 100644 --- a/system-contracts/contracts/Compressor.sol +++ b/system-contracts/contracts/Compressor.sol @@ -8,6 +8,7 @@ import {Utils} from "./libraries/Utils.sol"; import {UnsafeBytesCalldata} from "./libraries/UnsafeBytesCalldata.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {L1_MESSENGER_CONTRACT, STATE_DIFF_ENTRY_SIZE, KNOWN_CODE_STORAGE_CONTRACT} from "./Constants.sol"; +import {MalformedBytecode, BytecodeError, IndexOutOfBounds, IndexSizeError, ValuesNotEqual, UnsupportedOperation} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -48,24 +49,27 @@ contract Compressor is ICompressor, ISystemContract { unchecked { (bytes calldata dictionary, bytes calldata encodedData) = _decodeRawBytecode(_rawCompressedData); - require( - encodedData.length * 4 == _bytecode.length, - "Encoded data length should be 4 times shorter than the original bytecode" - ); + if (encodedData.length * 4 != _bytecode.length) { + revert MalformedBytecode(BytecodeError.Length); + } - require( - dictionary.length / 8 <= encodedData.length / 2, - "Dictionary should have at most the same number of entries as the encoded data" - ); + if (dictionary.length / 8 > encodedData.length / 2) { + revert MalformedBytecode(BytecodeError.DictionaryLength); + } + // solhint-disable-next-line gas-length-in-loops for (uint256 encodedDataPointer = 0; encodedDataPointer < encodedData.length; encodedDataPointer += 2) { uint256 indexOfEncodedChunk = uint256(encodedData.readUint16(encodedDataPointer)) * 8; - require(indexOfEncodedChunk < dictionary.length, "Encoded chunk index is out of bounds"); + if (indexOfEncodedChunk > dictionary.length - 1) { + revert IndexOutOfBounds(); + } uint64 encodedChunk = dictionary.readUint64(indexOfEncodedChunk); uint64 realChunk = _bytecode.readUint64(encodedDataPointer * 4); - require(encodedChunk == realChunk, "Encoded chunk does not match the original bytecode"); + if (encodedChunk != realChunk) { + revert ValuesNotEqual(realChunk, encodedChunk); + } } } @@ -116,7 +120,9 @@ contract Compressor is ICompressor, ISystemContract { // We do not enforce the operator to use the optimal, i.e. the minimally possible _enumerationIndexSize. // We do enforce however, that the _enumerationIndexSize is not larger than 8 bytes long, which is the // maximal ever possible size for enumeration index. - require(_enumerationIndexSize <= MAX_ENUMERATION_INDEX_SIZE, "enumeration index size is too large"); + if (_enumerationIndexSize > MAX_ENUMERATION_INDEX_SIZE) { + revert IndexSizeError(); + } uint256 numberOfInitialWrites = uint256(_compressedStateDiffs.readUint16(0)); @@ -132,16 +138,18 @@ contract Compressor is ICompressor, ISystemContract { continue; } - numInitialWritesProcessed++; + ++numInitialWritesProcessed; bytes32 derivedKey = stateDiff.readBytes32(52); uint256 initValue = stateDiff.readUint256(92); uint256 finalValue = stateDiff.readUint256(124); - require(derivedKey == _compressedStateDiffs.readBytes32(stateDiffPtr), "iw: initial key mismatch"); + if (derivedKey != _compressedStateDiffs.readBytes32(stateDiffPtr)) { + revert ValuesNotEqual(uint256(derivedKey), _compressedStateDiffs.readUint256(stateDiffPtr)); + } stateDiffPtr += 32; uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr])); - stateDiffPtr++; + ++stateDiffPtr; uint8 operation = metadata & OPERATION_BITMASK; uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; _verifyValueCompression( @@ -153,7 +161,9 @@ contract Compressor is ICompressor, ISystemContract { stateDiffPtr += len; } - require(numInitialWritesProcessed == numberOfInitialWrites, "Incorrect number of initial storage diffs"); + if (numInitialWritesProcessed != numberOfInitialWrites) { + revert ValuesNotEqual(numberOfInitialWrites, numInitialWritesProcessed); + } // Process repeated writes for (uint256 i = 0; i < _numberOfStateDiffs * STATE_DIFF_ENTRY_SIZE; i += STATE_DIFF_ENTRY_SIZE) { @@ -168,11 +178,13 @@ contract Compressor is ICompressor, ISystemContract { uint256 compressedEnumIndex = _sliceToUint256( _compressedStateDiffs[stateDiffPtr:stateDiffPtr + _enumerationIndexSize] ); - require(enumIndex == compressedEnumIndex, "rw: enum key mismatch"); + if (enumIndex != compressedEnumIndex) { + revert ValuesNotEqual(enumIndex, compressedEnumIndex); + } stateDiffPtr += _enumerationIndexSize; uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr])); - stateDiffPtr += 1; + ++stateDiffPtr; uint8 operation = metadata & OPERATION_BITMASK; uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; _verifyValueCompression( @@ -184,7 +196,9 @@ contract Compressor is ICompressor, ISystemContract { stateDiffPtr += len; } - require(stateDiffPtr == _compressedStateDiffs.length, "Extra data in _compressedStateDiffs"); + if (stateDiffPtr != _compressedStateDiffs.length) { + revert ValuesNotEqual(stateDiffPtr, _compressedStateDiffs.length); + } stateDiffHash = EfficientCall.keccak(_stateDiffs); } @@ -227,19 +241,19 @@ contract Compressor is ICompressor, ISystemContract { unchecked { if (_operation == 0 || _operation == 3) { - require(convertedValue == _finalValue, "transform or no compression: compressed and final mismatch"); + if (convertedValue != _finalValue) { + revert ValuesNotEqual(_finalValue, convertedValue); + } } else if (_operation == 1) { - require( - _initialValue + convertedValue == _finalValue, - "add: initial plus converted not equal to final" - ); + if (_initialValue + convertedValue != _finalValue) { + revert ValuesNotEqual(_finalValue, _initialValue + convertedValue); + } } else if (_operation == 2) { - require( - _initialValue - convertedValue == _finalValue, - "sub: initial minus converted not equal to final" - ); + if (_initialValue - convertedValue != _finalValue) { + revert ValuesNotEqual(_finalValue, _initialValue - convertedValue); + } } else { - revert("unsupported operation"); + revert UnsupportedOperation(); } } } diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index 01009da19..30d5e3930 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -10,6 +10,7 @@ import {Utils} from "./libraries/Utils.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {Unauthorized, InvalidNonceOrderingChange, ValuesNotEqual, EmptyBytes32, NotAllowedToDeployInKernelSpace, HashIsNonZero, NonEmptyAccount, UnknownCodeHash, NonEmptyMsgValue} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -26,7 +27,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { mapping(address => AccountInfo) internal accountInfo; modifier onlySelf() { - require(msg.sender == address(this), "Callable only by self"); + if (msg.sender != address(this)) { + revert Unauthorized(msg.sender); + } _; } @@ -74,11 +77,12 @@ contract ContractDeployer is IContractDeployer, ISystemContract { function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external onlySystemCall { AccountInfo memory currentInfo = accountInfo[msg.sender]; - require( - _nonceOrdering == AccountNonceOrdering.Arbitrary && - currentInfo.nonceOrdering == AccountNonceOrdering.Sequential, - "It is only possible to change from sequential to arbitrary ordering" - ); + if ( + _nonceOrdering != AccountNonceOrdering.Arbitrary && + currentInfo.nonceOrdering != AccountNonceOrdering.Sequential + ) { + revert InvalidNonceOrderingChange(); + } currentInfo.nonceOrdering = _nonceOrdering; _storeAccountInfo(msg.sender, currentInfo); @@ -237,10 +241,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { /// @dev We do not require `onlySystemCall` here, since the method is accessible only /// by `FORCE_DEPLOYER`. function forceDeployOnAddresses(ForceDeployment[] calldata _deployments) external payable { - require( - msg.sender == FORCE_DEPLOYER || msg.sender == address(COMPLEX_UPGRADER_CONTRACT), - "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT" - ); + if (msg.sender != FORCE_DEPLOYER && msg.sender != address(COMPLEX_UPGRADER_CONTRACT)) { + revert Unauthorized(msg.sender); + } uint256 deploymentsLength = _deployments.length; // We need to ensure that the `value` provided by the call is enough to provide `value` @@ -249,7 +252,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { for (uint256 i = 0; i < deploymentsLength; ++i) { sumOfValues += _deployments[i].value; } - require(msg.value == sumOfValues, "`value` provided is not equal to the combined `value`s of deployments"); + if (msg.value != sumOfValues) { + revert ValuesNotEqual(sumOfValues, msg.value); + } for (uint256 i = 0; i < deploymentsLength; ++i) { this.forceDeployOnAddress{value: _deployments[i].value}(_deployments[i], msg.sender); @@ -262,16 +267,22 @@ contract ContractDeployer is IContractDeployer, ISystemContract { AccountAbstractionVersion _aaVersion, bytes calldata _input ) internal { - require(_bytecodeHash != bytes32(0x0), "BytecodeHash cannot be zero"); - require(uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS, "Can not deploy contracts in kernel space"); + if (_bytecodeHash == bytes32(0x0)) { + revert EmptyBytes32(); + } + if (uint160(_newAddress) <= MAX_SYSTEM_CONTRACT_ADDRESS) { + revert NotAllowedToDeployInKernelSpace(); + } // We do not allow deploying twice on the same address. - require( - ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0, - "Code hash is non-zero" - ); + bytes32 codeHash = ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))); + if (codeHash != 0x0) { + revert HashIsNonZero(codeHash); + } // Do not allow deploying contracts to default accounts that have already executed transactions. - require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied"); + if (NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) != 0x00) { + revert NonEmptyAccount(); + } _performDeployOnAddress(_bytecodeHash, _newAddress, _aaVersion, _input); } @@ -308,7 +319,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { /// @notice Check that bytecode hash is marked as known on the `KnownCodeStorage` system contracts function _ensureBytecodeIsKnown(bytes32 _bytecodeHash) internal view { uint256 knownCodeMarker = KNOWN_CODE_STORAGE_CONTRACT.getMarker(_bytecodeHash); - require(knownCodeMarker > 0, "The code hash is not known"); + if (knownCodeMarker == 0) { + revert UnknownCodeHash(_bytecodeHash); + } } /// @notice Ensures that the _newAddress and assigns a new contract hash to it @@ -362,7 +375,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { ImmutableData[] memory immutables = abi.decode(returnData, (ImmutableData[])); IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT.setImmutables(_newAddress, immutables); } else { - require(value == 0, "The value must be zero if we do not call the constructor"); + if (value != 0) { + revert NonEmptyMsgValue(); + } // If we do not call the constructor, we need to set the constructed code hash. ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.storeAccountConstructedCodeHash(_newAddress, _bytecodeHash); } diff --git a/system-contracts/contracts/DefaultAccount.sol b/system-contracts/contracts/DefaultAccount.sol index 4c7356dd8..ff62e9a57 100644 --- a/system-contracts/contracts/DefaultAccount.sol +++ b/system-contracts/contracts/DefaultAccount.sol @@ -9,6 +9,7 @@ import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {BOOTLOADER_FORMAL_ADDRESS, NONCE_HOLDER_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, INonceHolder} from "./Constants.sol"; import {Utils} from "./libraries/Utils.sol"; +import {InsufficientFunds, InvalidSig, SigField, FailedToPayOperator} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -99,7 +100,9 @@ contract DefaultAccount is IAccount { // should be checked explicitly to prevent user paying for fee for a // transaction that wouldn't be included on Ethereum. uint256 totalRequiredBalance = _transaction.totalRequiredBalance(); - require(totalRequiredBalance <= address(this).balance, "Not enough balance for fee + value"); + if (totalRequiredBalance > address(this).balance) { + revert InsufficientFunds(totalRequiredBalance, address(this).balance); + } if (_isValidSignature(txHash, _transaction.signature)) { magic = ACCOUNT_VALIDATION_SUCCESS_MAGIC; @@ -165,7 +168,9 @@ contract DefaultAccount is IAccount { /// @param _signature The signature of the transaction. /// @return EIP1271_SUCCESS_RETURN_VALUE if the signature is correct. It reverts otherwise. function _isValidSignature(bytes32 _hash, bytes memory _signature) internal view returns (bool) { - require(_signature.length == 65, "Signature length is incorrect"); + if (_signature.length != 65) { + revert InvalidSig(SigField.Length, _signature.length); + } uint8 v; bytes32 r; bytes32 s; @@ -178,7 +183,9 @@ contract DefaultAccount is IAccount { s := mload(add(_signature, 0x40)) v := and(mload(add(_signature, 0x41)), 0xff) } - require(v == 27 || v == 28, "v is neither 27 nor 28"); + if (v != 27 && v != 28) { + revert InvalidSig(SigField.V, v); + } // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines @@ -189,7 +196,9 @@ contract DefaultAccount is IAccount { // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. - require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "Invalid s"); + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + revert InvalidSig(SigField.S, uint256(s)); + } address recoveredAddress = ecrecover(_hash, v, r, s); @@ -207,7 +216,9 @@ contract DefaultAccount is IAccount { Transaction calldata _transaction ) external payable ignoreNonBootloader ignoreInDelegateCall { bool success = _transaction.payToTheBootloader(); - require(success, "Failed to pay the fee to the operator"); + if (!success) { + revert FailedToPayOperator(); + } } /// @notice Method, where the user should prepare for the transaction to be diff --git a/system-contracts/contracts/GasBoundCaller.sol b/system-contracts/contracts/GasBoundCaller.sol index 67a43883e..47b12b6ff 100644 --- a/system-contracts/contracts/GasBoundCaller.sol +++ b/system-contracts/contracts/GasBoundCaller.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; +import {InsufficientGas} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -15,10 +16,10 @@ import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; contract GasBoundCaller { /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` gas are used for the O(1) operations at the start /// of execution of the contract, such as abi decoding the parameters, jumping to the correct function, etc. - uint256 constant CALL_ENTRY_OVERHEAD = 800; + uint256 internal constant CALL_ENTRY_OVERHEAD = 800; /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, /// as such relaying the return. - uint256 constant CALL_RETURN_OVERHEAD = 200; + uint256 internal constant CALL_RETURN_OVERHEAD = 200; /// @notice The function that implements limiting of the total gas expenditure of the call. /// @dev On Era, the gas for pubdata is charged at the end of the execution of the entire transaction, meaning @@ -43,7 +44,9 @@ contract GasBoundCaller { // This require is more of a safety protection for the users that call this function with incorrect parameters. // // Ultimately, the entire `gas` sent to this call can be spent on compute regardless of the `_maxTotalGas` parameter. - require(_maxTotalGas >= gasleft(), "Gas limit is too low"); + if (_maxTotalGas < gasleft()) { + revert InsufficientGas(); + } // This is the amount of gas that can be spent *exclusively* on pubdata in addition to the `gas` provided to this function. uint256 pubdataAllowance = _maxTotalGas > expectedForCompute ? _maxTotalGas - expectedForCompute : 0; @@ -79,7 +82,9 @@ contract GasBoundCaller { if (pubdataGas != 0) { // Here we double check that the additional cost is not higher than the maximum allowed. // Note, that the `gasleft()` can be spent on pubdata too. - require(pubdataAllowance + gasleft() >= pubdataGas + CALL_RETURN_OVERHEAD, "Not enough gas for pubdata"); + if (pubdataAllowance + gasleft() < pubdataGas + CALL_RETURN_OVERHEAD) { + revert InsufficientGas(); + } } assembly { diff --git a/system-contracts/contracts/ImmutableSimulator.sol b/system-contracts/contracts/ImmutableSimulator.sol index 2d077316a..701ee5d90 100644 --- a/system-contracts/contracts/ImmutableSimulator.sol +++ b/system-contracts/contracts/ImmutableSimulator.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {IImmutableSimulator, ImmutableData} from "./interfaces/IImmutableSimulator.sol"; import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; +import {Unauthorized} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -32,7 +33,9 @@ contract ImmutableSimulator is IImmutableSimulator { /// @param _dest The address which to store the immutables for. /// @param _immutables The list of the immutables. function setImmutables(address _dest, ImmutableData[] calldata _immutables) external override { - require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract"); + if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { + revert Unauthorized(msg.sender); + } unchecked { uint256 immutablesLength = _immutables.length; for (uint256 i = 0; i < immutablesLength; ++i) { diff --git a/system-contracts/contracts/KnownCodesStorage.sol b/system-contracts/contracts/KnownCodesStorage.sol index 3db07fe31..efddf5d9c 100644 --- a/system-contracts/contracts/KnownCodesStorage.sol +++ b/system-contracts/contracts/KnownCodesStorage.sol @@ -6,6 +6,7 @@ import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {Utils} from "./libraries/Utils.sol"; import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; +import {Unauthorized, MalformedBytecode, BytecodeError} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -17,7 +18,9 @@ import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; */ contract KnownCodesStorage is IKnownCodesStorage, ISystemContract { modifier onlyCompressor() { - require(msg.sender == address(COMPRESSOR_CONTRACT), "Callable only by the compressor"); + if (msg.sender != address(COMPRESSOR_CONTRACT)) { + revert Unauthorized(msg.sender); + } _; } @@ -73,8 +76,12 @@ contract KnownCodesStorage is IKnownCodesStorage, ISystemContract { /// That's why we need to validate it function _validateBytecode(bytes32 _bytecodeHash) internal pure { uint8 version = uint8(_bytecodeHash[0]); - require(version == 1 && _bytecodeHash[1] == bytes1(0), "Incorrectly formatted bytecodeHash"); + if (version != 1 || _bytecodeHash[1] != bytes1(0)) { + revert MalformedBytecode(BytecodeError.Version); + } - require(Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 1, "Code length in words must be odd"); + if (Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 0) { + revert MalformedBytecode(BytecodeError.NumberOfWords); + } } } diff --git a/system-contracts/contracts/L1Messenger.sol b/system-contracts/contracts/L1Messenger.sol index 2b584d110..26d49672a 100644 --- a/system-contracts/contracts/L1Messenger.sol +++ b/system-contracts/contracts/L1Messenger.sol @@ -8,6 +8,7 @@ import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {Utils} from "./libraries/Utils.sol"; import {SystemLogKey, SYSTEM_CONTEXT_CONTRACT, KNOWN_CODE_STORAGE_CONTRACT, COMPRESSOR_CONTRACT, STATE_DIFF_ENTRY_SIZE, L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, PUBDATA_CHUNK_PUBLISHER, COMPUTATIONAL_PRICE_FOR_PUBDATA} from "./Constants.sol"; +import {ReconstructionMismatch, PubdataField} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -107,7 +108,7 @@ contract L1Messenger is IL1Messenger, ISystemContract { chainedLogsHash = keccak256(abi.encode(chainedLogsHash, hashedLog)); logIdInMerkleTree = numberOfLogsToProcess; - numberOfLogsToProcess++; + ++numberOfLogsToProcess; emit L2ToL1LogSent(_l2ToL1Log); } @@ -198,7 +199,13 @@ contract L1Messenger is IL1Messenger, ISystemContract { /// Check logs uint32 numberOfL2ToL1Logs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); - require(numberOfL2ToL1Logs <= L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, "Too many L2->L1 logs"); + if (numberOfL2ToL1Logs > L2_TO_L1_LOGS_MERKLE_TREE_LEAVES) { + revert ReconstructionMismatch( + PubdataField.NumberOfLogs, + bytes32(L2_TO_L1_LOGS_MERKLE_TREE_LEAVES), + bytes32(uint256(numberOfL2ToL1Logs)) + ); + } calldataPtr += 4; bytes32[] memory l2ToL1LogsTreeArray = new bytes32[](L2_TO_L1_LOGS_MERKLE_TREE_LEAVES); @@ -211,10 +218,9 @@ contract L1Messenger is IL1Messenger, ISystemContract { l2ToL1LogsTreeArray[i] = hashedLog; reconstructedChainedLogsHash = keccak256(abi.encode(reconstructedChainedLogsHash, hashedLog)); } - require( - reconstructedChainedLogsHash == chainedLogsHash, - "reconstructedChainedLogsHash is not equal to chainedLogsHash" - ); + if (reconstructedChainedLogsHash != chainedLogsHash) { + revert ReconstructionMismatch(PubdataField.LogsHash, chainedLogsHash, reconstructedChainedLogsHash); + } for (uint256 i = numberOfL2ToL1Logs; i < L2_TO_L1_LOGS_MERKLE_TREE_LEAVES; ++i) { l2ToL1LogsTreeArray[i] = L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH; } @@ -242,10 +248,9 @@ contract L1Messenger is IL1Messenger, ISystemContract { calldataPtr += currentMessageLength; reconstructedChainedMessagesHash = keccak256(abi.encode(reconstructedChainedMessagesHash, hashedMessage)); } - require( - reconstructedChainedMessagesHash == chainedMessagesHash, - "reconstructedChainedMessagesHash is not equal to chainedMessagesHash" - ); + if (reconstructedChainedMessagesHash != chainedMessagesHash) { + revert ReconstructionMismatch(PubdataField.MsgHash, chainedMessagesHash, reconstructedChainedMessagesHash); + } /// Check bytecodes uint32 numberOfBytecodes = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); @@ -266,28 +271,36 @@ contract L1Messenger is IL1Messenger, ISystemContract { ); calldataPtr += currentBytecodeLength; } - require( - reconstructedChainedL1BytecodesRevealDataHash == chainedL1BytecodesRevealDataHash, - "reconstructedChainedL1BytecodesRevealDataHash is not equal to chainedL1BytecodesRevealDataHash" - ); + if (reconstructedChainedL1BytecodesRevealDataHash != chainedL1BytecodesRevealDataHash) { + revert ReconstructionMismatch( + PubdataField.Bytecode, + chainedL1BytecodesRevealDataHash, + reconstructedChainedL1BytecodesRevealDataHash + ); + } /// Check State Diffs /// encoding is as follows: /// header (1 byte version, 3 bytes total len of compressed, 1 byte enumeration index size) /// body (`compressedStateDiffSize` bytes, 4 bytes number of state diffs, `numberOfStateDiffs` * `STATE_DIFF_ENTRY_SIZE` bytes for the uncompressed state diffs) /// encoded state diffs: [20bytes address][32bytes key][32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value] - require( - uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) == - STATE_DIFF_COMPRESSION_VERSION_NUMBER, - "state diff compression version mismatch" - ); - calldataPtr++; + if ( + uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) != + STATE_DIFF_COMPRESSION_VERSION_NUMBER + ) { + revert ReconstructionMismatch( + PubdataField.StateDiffCompressionVersion, + bytes32(STATE_DIFF_COMPRESSION_VERSION_NUMBER), + bytes32(uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr])))) + ); + } + ++calldataPtr; uint24 compressedStateDiffSize = uint24(bytes3(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 3])); calldataPtr += 3; uint8 enumerationIndexSize = uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr])); - calldataPtr++; + ++calldataPtr; bytes calldata compressedStateDiffs = _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + compressedStateDiffSize]; @@ -310,7 +323,13 @@ contract L1Messenger is IL1Messenger, ISystemContract { ); /// Check for calldata strict format - require(calldataPtr == _totalL2ToL1PubdataAndStateDiffs.length, "Extra data in the totalL2ToL1Pubdata array"); + if (calldataPtr != _totalL2ToL1PubdataAndStateDiffs.length) { + revert ReconstructionMismatch( + PubdataField.ExtraData, + bytes32(calldataPtr), + bytes32(_totalL2ToL1PubdataAndStateDiffs.length) + ); + } PUBDATA_CHUNK_PUBLISHER.chunkAndPublishPubdata(totalL2ToL1Pubdata); diff --git a/system-contracts/contracts/L2BaseToken.sol b/system-contracts/contracts/L2BaseToken.sol index 8101c638b..c5b934013 100644 --- a/system-contracts/contracts/L2BaseToken.sol +++ b/system-contracts/contracts/L2BaseToken.sol @@ -6,6 +6,7 @@ import {IBaseToken} from "./interfaces/IBaseToken.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {MSG_VALUE_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS, L1_MESSENGER_CONTRACT} from "./Constants.sol"; import {IMailbox} from "./interfaces/IMailbox.sol"; +import {Unauthorized, InsufficientFunds} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -30,15 +31,18 @@ contract L2BaseToken is IBaseToken, ISystemContract { /// @dev This function also emits "Transfer" event, which might be removed /// later on. function transferFromTo(address _from, address _to, uint256 _amount) external override { - require( - msg.sender == MSG_VALUE_SYSTEM_CONTRACT || - msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) || - msg.sender == BOOTLOADER_FORMAL_ADDRESS, - "Only system contracts with special access can call this method" - ); + if ( + msg.sender != MSG_VALUE_SYSTEM_CONTRACT && + msg.sender != address(DEPLOYER_SYSTEM_CONTRACT) && + msg.sender != BOOTLOADER_FORMAL_ADDRESS + ) { + revert Unauthorized(msg.sender); + } uint256 fromBalance = balance[_from]; - require(fromBalance >= _amount, "Transfer amount exceeds balance"); + if (fromBalance < _amount) { + revert InsufficientFunds(_amount, fromBalance); + } unchecked { balance[_from] = fromBalance - _amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by @@ -82,7 +86,7 @@ contract L2BaseToken is IBaseToken, ISystemContract { /// @notice Initiate the withdrawal of the base token, with the sent message. The funds will be available to claim on L1 `finalizeEthWithdrawal` method. /// @param _l1Receiver The address on L1 to receive the funds. /// @param _additionalData Additional data to be sent to L1 with the withdrawal. - function withdrawWithMessage(address _l1Receiver, bytes memory _additionalData) external payable override { + function withdrawWithMessage(address _l1Receiver, bytes calldata _additionalData) external payable override { uint256 amount = _burnMsgValue(); // Send the L2 log, a user could use it as proof of the withdrawal diff --git a/system-contracts/contracts/MsgValueSimulator.sol b/system-contracts/contracts/MsgValueSimulator.sol index c1dcde694..61a221653 100644 --- a/system-contracts/contracts/MsgValueSimulator.sol +++ b/system-contracts/contracts/MsgValueSimulator.sol @@ -7,6 +7,7 @@ import {EfficientCall} from "./libraries/EfficientCall.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, REAL_BASE_TOKEN_SYSTEM_CONTRACT} from "./Constants.sol"; +import {InvalidCall} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -33,17 +34,18 @@ contract MsgValueSimulator is ISystemContract { } /// @notice The maximal number of gas out of the stipend that should be passed to the callee. - uint256 constant GAS_TO_PASS = 2300; + uint256 internal constant GAS_TO_PASS = 2300; /// @notice The amount of gas that is passed to the MsgValueSimulator as a stipend. /// This number servers to pay for the ETH transfer as well as to provide gas for the `GAS_TO_PASS` gas. /// It is equal to the following constant: https://github.com/matter-labs/era-zkevm_opcode_defs/blob/7bf8016f5bb13a73289f321ad6ea8f614540ece9/src/system_params.rs#L96. - uint256 constant MSG_VALUE_SIMULATOR_STIPEND_GAS = 27000; + uint256 internal constant MSG_VALUE_SIMULATOR_STIPEND_GAS = 27000; /// @notice The fallback function that is the main entry point for the MsgValueSimulator. /// @dev The contract accepts value, the callee and whether the call should be a system one via its ABI params. /// @param _data The calldata to be passed to the callee. /// @return The return data from the callee. + // solhint-disable-next-line payable-fallback fallback(bytes calldata _data) external onlySystemCall returns (bytes memory) { // Firstly we calculate how much gas has been actually provided by the user to the inner call. // For that, we need to get the total gas available in this context and subtract the stipend from it. @@ -57,7 +59,9 @@ contract MsgValueSimulator is ISystemContract { (uint256 value, bool isSystemCall, address to) = _getAbiParams(); // Prevent mimic call to the MsgValueSimulator to prevent an unexpected change of callee. - require(to != address(this), "MsgValueSimulator calls itself"); + if (to == address(this)) { + revert InvalidCall(); + } if (value != 0) { (bool success, ) = address(REAL_BASE_TOKEN_SYSTEM_CONTRACT).call( diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol index 12abda8bd..b769d2d37 100644 --- a/system-contracts/contracts/NonceHolder.sol +++ b/system-contracts/contracts/NonceHolder.sol @@ -6,6 +6,7 @@ import {INonceHolder} from "./interfaces/INonceHolder.sol"; import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; +import {NonceIncreaseError, ZeroNonceError, NonceJumpError, ValuesNotEqual, NonceAlreadyUsed, NonceNotUsed, Unauthorized} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -63,7 +64,9 @@ contract NonceHolder is INonceHolder, ISystemContract { /// @param _value The number by which to increase the minimal nonce for msg.sender. /// @return oldMinNonce The value of the minimal nonce for msg.sender before the increase. function increaseMinNonce(uint256 _value) public onlySystemCall returns (uint256 oldMinNonce) { - require(_value <= MAXIMAL_MIN_NONCE_INCREMENT, "The value for incrementing the nonce is too high"); + if (_value > MAXIMAL_MIN_NONCE_INCREMENT) { + revert NonceIncreaseError(MAXIMAL_MIN_NONCE_INCREMENT, _value); + } uint256 addressAsKey = uint256(uint160(msg.sender)); uint256 oldRawNonce = rawNonces[addressAsKey]; @@ -82,11 +85,15 @@ contract NonceHolder is INonceHolder, ISystemContract { function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall { IContractDeployer.AccountInfo memory accountInfo = DEPLOYER_SYSTEM_CONTRACT.getAccountInfo(msg.sender); - require(_value != 0, "Nonce value cannot be set to 0"); + if (_value == 0) { + revert ZeroNonceError(); + } // If an account has sequential nonce ordering, we enforce that the previous // nonce has already been used. if (accountInfo.nonceOrdering == IContractDeployer.AccountNonceOrdering.Sequential && _key != 0) { - require(isNonceUsed(msg.sender, _key - 1), "Previous nonce has not been used"); + if (!isNonceUsed(msg.sender, _key - 1)) { + revert NonceJumpError(); + } } uint256 addressAsKey = uint256(uint160(msg.sender)); @@ -112,7 +119,9 @@ contract NonceHolder is INonceHolder, ISystemContract { uint256 oldRawNonce = rawNonces[addressAsKey]; (, uint256 oldMinNonce) = _splitRawNonce(oldRawNonce); - require(oldMinNonce == _expectedNonce, "Incorrect nonce"); + if (oldMinNonce != _expectedNonce) { + revert ValuesNotEqual(_expectedNonce, oldMinNonce); + } unchecked { rawNonces[addressAsKey] = oldRawNonce + 1; @@ -133,10 +142,9 @@ contract NonceHolder is INonceHolder, ISystemContract { /// @param _address The address of the account which to return the deploy nonce for. /// @return prevDeploymentNonce The deployment nonce at the time this function is called. function incrementDeploymentNonce(address _address) external returns (uint256 prevDeploymentNonce) { - require( - msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), - "Only the contract deployer can increment the deployment nonce" - ); + if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { + revert Unauthorized(msg.sender); + } uint256 addressAsKey = uint256(uint160(_address)); uint256 oldRawNonce = rawNonces[addressAsKey]; @@ -167,9 +175,9 @@ contract NonceHolder is INonceHolder, ISystemContract { bool isUsed = isNonceUsed(_address, _key); if (isUsed && !_shouldBeUsed) { - revert("Reusing the same nonce twice"); + revert NonceAlreadyUsed(_address, _key); } else if (!isUsed && _shouldBeUsed) { - revert("The nonce was not set as used"); + revert NonceNotUsed(_address, _key); } } diff --git a/system-contracts/contracts/PubdataChunkPublisher.sol b/system-contracts/contracts/PubdataChunkPublisher.sol index 53c265e9b..a096e6900 100644 --- a/system-contracts/contracts/PubdataChunkPublisher.sol +++ b/system-contracts/contracts/PubdataChunkPublisher.sol @@ -5,6 +5,7 @@ import {IPubdataChunkPublisher} from "./interfaces/IPubdataChunkPublisher.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {L1_MESSENGER_CONTRACT, BLOB_SIZE_BYTES, MAX_NUMBER_OF_BLOBS, SystemLogKey} from "./Constants.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {TooMuchPubdata} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -17,7 +18,9 @@ contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { /// @dev Note: This is an early implementation, in the future we plan to support up to 16 blobs per l1 batch. /// @dev We always publish 6 system logs even if our pubdata fits into a single blob. This makes processing logs on L1 easier. function chunkAndPublishPubdata(bytes calldata _pubdata) external onlyCallFrom(address(L1_MESSENGER_CONTRACT)) { - require(_pubdata.length <= BLOB_SIZE_BYTES * MAX_NUMBER_OF_BLOBS, "pubdata should fit in 6 blobs"); + if (_pubdata.length > BLOB_SIZE_BYTES * MAX_NUMBER_OF_BLOBS) { + revert TooMuchPubdata(BLOB_SIZE_BYTES * MAX_NUMBER_OF_BLOBS, _pubdata.length); + } bytes32[] memory blobHashes = new bytes32[](MAX_NUMBER_OF_BLOBS); @@ -31,7 +34,7 @@ contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { calldatacopy(ptr, _pubdata.offset, _pubdata.length) } - for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { uint256 start = BLOB_SIZE_BYTES * i; // We break if the pubdata isn't enough to cover all 6 blobs. On L1 it is expected that the hash @@ -50,7 +53,7 @@ contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { blobHashes[i] = blobHash; } - for (uint8 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint8 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { SystemContractHelper.toL1( true, bytes32(uint256(SystemLogKey(i + uint256(SystemLogKey.BLOB_ONE_HASH_KEY)))), diff --git a/system-contracts/contracts/SystemContext.sol b/system-contracts/contracts/SystemContext.sol index 51b9633d9..a37cf0c19 100644 --- a/system-contracts/contracts/SystemContext.sol +++ b/system-contracts/contracts/SystemContext.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT +// solhint-disable reason-string, gas-custom-errors + pragma solidity 0.8.20; import {ISystemContext} from "./interfaces/ISystemContext.sol"; @@ -289,6 +291,7 @@ contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContr virtualBlockUpgradeInfo.virtualBlockStartBatch = currentBatchNumber; require(_maxVirtualBlocksToCreate > 0, "Can't initialize the first virtual block"); + // solhint-disable-next-line gas-increment-by-one _maxVirtualBlocksToCreate -= 1; } else if (_maxVirtualBlocksToCreate == 0) { // The virtual blocks have been already initialized, but the operator didn't ask to create @@ -484,7 +487,7 @@ contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContr } function incrementTxNumberInBatch() external onlyCallFromBootloader { - txNumberInBlock += 1; + ++txNumberInBlock; } function resetTxNumberInBatch() external onlyCallFromBootloader { diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol new file mode 100644 index 000000000..5ab4ece43 --- /dev/null +++ b/system-contracts/contracts/SystemContractErrors.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +error Unauthorized(address); +error InvalidCodeHash(CodeHashReason); +error UnsupportedTxType(uint256); +error AddressHasNoCode(address); +error EncodingLengthMismatch(); +error IndexOutOfBounds(); +error ValuesNotEqual(uint256 expected, uint256 actual); +error HashMismatch(bytes32 expected, uint256 actual); +error IndexSizeError(); +error UnsupportedOperation(); +error InvalidNonceOrderingChange(); +error EmptyBytes32(); +error NotAllowedToDeployInKernelSpace(); +error HashIsNonZero(bytes32); +error NonEmptyAccount(); +error UnknownCodeHash(bytes32); +error NonEmptyMsgValue(); +error InsufficientFunds(uint256 required, uint256 actual); +error InvalidSig(SigField, uint256); +error FailedToPayOperator(); +error InsufficientGas(); +error MalformedBytecode(BytecodeError); +error ReconstructionMismatch(PubdataField, bytes32 expected, bytes32 actual); +error InvalidCall(); +error NonceIncreaseError(uint256 max, uint256 proposed); +error ZeroNonceError(); +error NonceJumpError(); +error NonceAlreadyUsed(address account, uint256 nonce); +error NonceNotUsed(address account, uint256 nonce); +error TooMuchPubdata(uint256 limit, uint256 supplied); +error UpgradeMustBeFirstTxn(); +error L2BlockMustBeGreaterThanZero(); +error FirstL2BlockInitializationError(); +error NonIncreasingTimestamp(); +error EmptyVirtualBlocks(); +error SystemCallFlagRequired(); +error CallerMustBeSystemContract(); +error CallerMustBeBootloader(); +error CallerMustBeForceDeployer(); +error InvalidData(); +error FailedToChargeGas(); +error Overflow(); +error InvalidInput(); +error UnsupportedPaymasterFlow(); + +enum CodeHashReason { + NotContractOnConstructor, + NotConstructedContract +} + +enum SigField { + Length, + V, + S +} + +enum PubdataField { + NumberOfLogs, + LogsHash, + MsgHash, + Bytecode, + StateDiffCompressionVersion, + ExtraData +} + +enum BytecodeError { + Version, + NumberOfWords, + Length, + WordsMustBeOdd, + DictionaryLength +} diff --git a/system-contracts/contracts/interfaces/ISystemContract.sol b/system-contracts/contracts/interfaces/ISystemContract.sol index 01ff9d95f..1f383a823 100644 --- a/system-contracts/contracts/interfaces/ISystemContract.sol +++ b/system-contracts/contracts/interfaces/ISystemContract.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {SystemContractHelper} from "../libraries/SystemContractHelper.sol"; import {BOOTLOADER_FORMAL_ADDRESS, FORCE_DEPLOYER} from "../Constants.sol"; +import {SystemCallFlagRequired, Unauthorized, CallerMustBeSystemContract, CallerMustBeBootloader, CallerMustBeForceDeployer} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -18,41 +19,45 @@ abstract contract ISystemContract { /// @notice Modifier that makes sure that the method /// can only be called via a system call. modifier onlySystemCall() { - require( - SystemContractHelper.isSystemCall() || SystemContractHelper.isSystemContract(msg.sender), - "This method require system call flag" - ); + if (!SystemContractHelper.isSystemCall() && !SystemContractHelper.isSystemContract(msg.sender)) { + revert SystemCallFlagRequired(); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from a system contract. modifier onlyCallFromSystemContract() { - require( - SystemContractHelper.isSystemContract(msg.sender), - "This method require the caller to be system contract" - ); + if (!SystemContractHelper.isSystemContract(msg.sender)) { + revert CallerMustBeSystemContract(); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from a special given address. modifier onlyCallFrom(address caller) { - require(msg.sender == caller, "Inappropriate caller"); + if (msg.sender != caller) { + revert Unauthorized(msg.sender); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from the bootloader. modifier onlyCallFromBootloader() { - require(msg.sender == BOOTLOADER_FORMAL_ADDRESS, "Callable only by the bootloader"); + if (msg.sender != BOOTLOADER_FORMAL_ADDRESS) { + revert CallerMustBeBootloader(); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from the L1 force deployer. modifier onlyCallFromForceDeployer() { - require(msg.sender == FORCE_DEPLOYER); + if (msg.sender != FORCE_DEPLOYER) { + revert CallerMustBeForceDeployer(); + } _; } } diff --git a/system-contracts/contracts/libraries/EfficientCall.sol b/system-contracts/contracts/libraries/EfficientCall.sol index 8f9939f08..70f33ae5d 100644 --- a/system-contracts/contracts/libraries/EfficientCall.sol +++ b/system-contracts/contracts/libraries/EfficientCall.sol @@ -6,6 +6,7 @@ import {SystemContractHelper, ADDRESS_MASK} from "./SystemContractHelper.sol"; import {SystemContractsCaller, CalldataForwardingMode, RAW_FAR_CALL_BY_REF_CALL_ADDRESS, SYSTEM_CALL_BY_REF_CALL_ADDRESS, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, MIMIC_CALL_BY_REF_CALL_ADDRESS} from "./SystemContractsCaller.sol"; import {Utils} from "./Utils.sol"; import {SHA256_SYSTEM_CONTRACT, KECCAK256_SYSTEM_CONTRACT, MSG_VALUE_SYSTEM_CONTRACT} from "../Constants.sol"; +import {InvalidData} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -36,7 +37,9 @@ library EfficientCall { /// @return The `keccak256` hash. function keccak(bytes calldata _data) internal view returns (bytes32) { bytes memory returnData = staticCall(gasleft(), KECCAK256_SYSTEM_CONTRACT, _data); - require(returnData.length == 32, "keccak256 returned invalid data"); + if (returnData.length != 32) { + revert InvalidData(); + } return bytes32(returnData); } @@ -45,7 +48,9 @@ library EfficientCall { /// @return The `sha256` hash. function sha(bytes calldata _data) internal view returns (bytes32) { bytes memory returnData = staticCall(gasleft(), SHA256_SYSTEM_CONTRACT, _data); - require(returnData.length == 32, "sha returned invalid data"); + if (returnData.length != 32) { + revert InvalidData(); + } return bytes32(returnData); } diff --git a/system-contracts/contracts/libraries/RLPEncoder.sol b/system-contracts/contracts/libraries/RLPEncoder.sol index 8e32ea9ba..7bfbd2a69 100644 --- a/system-contracts/contracts/libraries/RLPEncoder.sol +++ b/system-contracts/contracts/libraries/RLPEncoder.sol @@ -100,7 +100,7 @@ library RLPEncoder { hbs += 2; } if (_number > type(uint8).max) { - hbs += 1; + ++hbs; } } } diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol index 7ae75b520..14d29f100 100644 --- a/system-contracts/contracts/libraries/SystemContractHelper.sol +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.20; import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; import {CALLFLAGS_CALL_ADDRESS, CODE_ADDRESS_CALL_ADDRESS, EVENT_WRITE_ADDRESS, EVENT_INITIALIZE_ADDRESS, GET_EXTRA_ABI_DATA_ADDRESS, LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, META_CODE_SHARD_ID_OFFSET, META_CALLER_SHARD_ID_OFFSET, META_SHARD_ID_OFFSET, META_AUX_HEAP_SIZE_OFFSET, META_HEAP_SIZE_OFFSET, META_PUBDATA_PUBLISHED_OFFSET, META_CALL_ADDRESS, PTR_CALLDATA_CALL_ADDRESS, PTR_ADD_INTO_ACTIVE_CALL_ADDRESS, PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, PRECOMPILE_CALL_ADDRESS, SET_CONTEXT_VALUE_CALL_ADDRESS, TO_L1_CALL_ADDRESS} from "./SystemContractsCaller.sol"; +import {IndexOutOfBounds, FailedToChargeGas} from "../SystemContractErrors.sol"; uint256 constant UINT32_MASK = type(uint32).max; uint256 constant UINT64_MASK = type(uint64).max; @@ -318,7 +319,10 @@ library SystemContractHelper { /// @dev It is equal to the value of the (N+2)-th register /// at the start of the call. function getExtraAbiData(uint256 index) internal view returns (uint256 extraAbiData) { - require(index < 10, "There are only 10 accessible registers"); + // Note that there are only 10 accessible registers (indices 0-9 inclusively) + if (index > 9) { + revert IndexOutOfBounds(); + } address callAddr = GET_EXTRA_ABI_DATA_ADDRESS; assembly { @@ -350,6 +354,8 @@ library SystemContractHelper { _gasToPay, _pubdataToSpend ); - require(precompileCallSuccess, "Failed to charge gas"); + if (!precompileCallSuccess) { + revert FailedToChargeGas(); + } } } diff --git a/system-contracts/contracts/libraries/TransactionHelper.sol b/system-contracts/contracts/libraries/TransactionHelper.sol index 9a2921010..fbdc57919 100644 --- a/system-contracts/contracts/libraries/TransactionHelper.sol +++ b/system-contracts/contracts/libraries/TransactionHelper.sol @@ -9,6 +9,7 @@ import {IPaymasterFlow} from "../interfaces/IPaymasterFlow.sol"; import {BASE_TOKEN_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS} from "../Constants.sol"; import {RLPEncoder} from "./RLPEncoder.sol"; import {EfficientCall} from "./EfficientCall.sol"; +import {UnsupportedTxType, InvalidInput, UnsupportedPaymasterFlow} from "../SystemContractErrors.sol"; /// @dev The type id of zkSync's EIP-712-signed transaction. uint8 constant EIP_712_TX_TYPE = 0x71; @@ -78,9 +79,10 @@ library TransactionHelper { using SafeERC20 for IERC20; /// @notice The EIP-712 typehash for the contract's domain - bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId)"); + bytes32 internal constant EIP712_DOMAIN_TYPEHASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId)"); - bytes32 constant EIP712_TRANSACTION_TYPE_HASH = + bytes32 internal constant EIP712_TRANSACTION_TYPE_HASH = keccak256( "Transaction(uint256 txType,uint256 from,uint256 to,uint256 gasLimit,uint256 gasPerPubdataByteLimit,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 paymaster,uint256 nonce,uint256 value,bytes data,bytes32[] factoryDeps,bytes paymasterInput)" ); @@ -108,7 +110,7 @@ library TransactionHelper { } else { // Currently no other transaction types are supported. // Any new transaction types will be processed in a similar manner. - revert("Encoding unsupported tx"); + revert UnsupportedTxType(_transaction.txType); } } @@ -365,14 +367,15 @@ library TransactionHelper { /// for tokens, etc. For more information on the expected behavior, check out /// the "Paymaster flows" section in the documentation. function processPaymasterInput(Transaction calldata _transaction) internal { - require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long"); + if (_transaction.paymasterInput.length < 4) { + revert InvalidInput(); + } bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]); if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { - require( - _transaction.paymasterInput.length >= 68, - "The approvalBased paymaster input must be at least 68 bytes long" - ); + if (_transaction.paymasterInput.length < 68) { + revert InvalidInput(); + } // While the actual data consists of address, uint256 and bytes data, // the data is needed only for the paymaster, so we ignore it here for the sake of optimization @@ -390,7 +393,7 @@ library TransactionHelper { } else if (paymasterInputSelector == IPaymasterFlow.general.selector) { // Do nothing. general(bytes) paymaster flow means that the paymaster must interpret these bytes on his own. } else { - revert("Unsupported paymaster flow"); + revert UnsupportedPaymasterFlow(); } } diff --git a/system-contracts/contracts/libraries/Utils.sol b/system-contracts/contracts/libraries/Utils.sol index 5fa7eec6f..4f535e2c1 100644 --- a/system-contracts/contracts/libraries/Utils.sol +++ b/system-contracts/contracts/libraries/Utils.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.20; import {EfficientCall} from "./EfficientCall.sol"; +import {MalformedBytecode, BytecodeError, Overflow} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -10,27 +11,33 @@ import {EfficientCall} from "./EfficientCall.sol"; */ library Utils { /// @dev Bit mask of bytecode hash "isConstructor" marker - bytes32 constant IS_CONSTRUCTOR_BYTECODE_HASH_BIT_MASK = + bytes32 internal constant IS_CONSTRUCTOR_BYTECODE_HASH_BIT_MASK = 0x00ff000000000000000000000000000000000000000000000000000000000000; /// @dev Bit mask to set the "isConstructor" marker in the bytecode hash - bytes32 constant SET_IS_CONSTRUCTOR_MARKER_BIT_MASK = + bytes32 internal constant SET_IS_CONSTRUCTOR_MARKER_BIT_MASK = 0x0001000000000000000000000000000000000000000000000000000000000000; function safeCastToU128(uint256 _x) internal pure returns (uint128) { - require(_x <= type(uint128).max, "Overflow"); + if (_x > type(uint128).max) { + revert Overflow(); + } return uint128(_x); } function safeCastToU32(uint256 _x) internal pure returns (uint32) { - require(_x <= type(uint32).max, "Overflow"); + if (_x > type(uint32).max) { + revert Overflow(); + } return uint32(_x); } function safeCastToU24(uint256 _x) internal pure returns (uint24) { - require(_x <= type(uint24).max, "Overflow"); + if (_x > type(uint24).max) { + revert Overflow(); + } return uint24(_x); } @@ -81,11 +88,19 @@ library Utils { /// - Bytecode words length is not odd function hashL2Bytecode(bytes calldata _bytecode) internal view returns (bytes32 hashedBytecode) { // Note that the length of the bytecode must be provided in 32-byte words. - require(_bytecode.length % 32 == 0, "po"); + if (_bytecode.length % 32 != 0) { + revert MalformedBytecode(BytecodeError.Length); + } uint256 lengthInWords = _bytecode.length / 32; - require(lengthInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words - require(lengthInWords % 2 == 1, "pr"); // bytecode length in words must be odd + // bytecode length must be less than 2^16 words + if (lengthInWords >= 2 ** 16) { + revert MalformedBytecode(BytecodeError.NumberOfWords); + } + // bytecode length in words must be odd + if (lengthInWords % 2 == 0) { + revert MalformedBytecode(BytecodeError.WordsMustBeOdd); + } hashedBytecode = EfficientCall.sha(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; diff --git a/system-contracts/test/AccountCodeStorage.spec.ts b/system-contracts/test/AccountCodeStorage.spec.ts index 994cfacc8..dca782e01 100644 --- a/system-contracts/test/AccountCodeStorage.spec.ts +++ b/system-contracts/test/AccountCodeStorage.spec.ts @@ -44,7 +44,7 @@ describe("AccountCodeStorage tests", function () { it("non-deployer failed to call", async () => { await expect( accountCodeStorage.storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) - ).to.be.revertedWith("Callable only by the deployer system contract"); + ).to.be.revertedWithCustomError(accountCodeStorage, "Unauthorized"); }); it("failed to set with constructed bytecode", async () => { @@ -52,7 +52,7 @@ describe("AccountCodeStorage tests", function () { accountCodeStorage .connect(deployerAccount) .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH) - ).to.be.revertedWith("Code hash is not for a contract on constructor"); + ).to.be.revertedWithCustomError(accountCodeStorage, "InvalidCodeHash"); }); it("successfully stored", async () => { @@ -72,7 +72,7 @@ describe("AccountCodeStorage tests", function () { it("non-deployer failed to call", async () => { await expect( accountCodeStorage.storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) - ).to.be.revertedWith("Callable only by the deployer system contract"); + ).to.be.revertedWithCustomError(accountCodeStorage, "Unauthorized"); }); it("failed to set with constructing bytecode", async () => { @@ -80,7 +80,7 @@ describe("AccountCodeStorage tests", function () { accountCodeStorage .connect(deployerAccount) .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) - ).to.be.revertedWith("Code hash is not for a constructed contract"); + ).to.be.revertedWithCustomError(accountCodeStorage, "InvalidCodeHash"); }); it("successfully stored", async () => { @@ -96,8 +96,9 @@ describe("AccountCodeStorage tests", function () { describe("markAccountCodeHashAsConstructed", function () { it("non-deployer failed to call", async () => { - await expect(accountCodeStorage.markAccountCodeHashAsConstructed(RANDOM_ADDRESS)).to.be.revertedWith( - "Callable only by the deployer system contract" + await expect(accountCodeStorage.markAccountCodeHashAsConstructed(RANDOM_ADDRESS)).to.be.revertedWithCustomError( + accountCodeStorage, + "Unauthorized" ); }); @@ -108,7 +109,7 @@ describe("AccountCodeStorage tests", function () { await expect( accountCodeStorage.connect(deployerAccount).markAccountCodeHashAsConstructed(RANDOM_ADDRESS) - ).to.be.revertedWith("Code hash is not for a contract on constructor"); + ).to.be.revertedWithCustomError(accountCodeStorage, "InvalidCodeHash"); await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); }); diff --git a/system-contracts/test/BootloaderUtilities.spec.ts b/system-contracts/test/BootloaderUtilities.spec.ts index 2c4176a17..e47446e33 100644 --- a/system-contracts/test/BootloaderUtilities.spec.ts +++ b/system-contracts/test/BootloaderUtilities.spec.ts @@ -84,7 +84,10 @@ describe("BootloaderUtilities tests", function () { signature[64] = 29; txData.signature = signature; - await expect(bootloaderUtilities.getTransactionHashes(txData)).to.be.revertedWith("Invalid v value"); + await expect(bootloaderUtilities.getTransactionHashes(txData)).to.be.revertedWithCustomError( + bootloaderUtilities, + "InvalidSig" + ); }); }); @@ -130,7 +133,10 @@ describe("BootloaderUtilities tests", function () { signature[64] = 0; EIP1559TxData.signature = signature; - await expect(bootloaderUtilities.getTransactionHashes(EIP1559TxData)).to.be.revertedWith("Invalid v value"); + await expect(bootloaderUtilities.getTransactionHashes(EIP1559TxData)).to.be.revertedWithCustomError( + bootloaderUtilities, + "InvalidSig" + ); }); }); @@ -176,7 +182,10 @@ describe("BootloaderUtilities tests", function () { signature[64] = 100; EIP2930TxData.signature = signature; - await expect(bootloaderUtilities.getTransactionHashes(EIP2930TxData)).to.be.revertedWith("Invalid v value"); + await expect(bootloaderUtilities.getTransactionHashes(EIP2930TxData)).to.be.revertedWithCustomError( + bootloaderUtilities, + "InvalidSig" + ); }); }); }); diff --git a/system-contracts/test/ComplexUpgrader.spec.ts b/system-contracts/test/ComplexUpgrader.spec.ts index 63b4a61eb..e9104e010 100644 --- a/system-contracts/test/ComplexUpgrader.spec.ts +++ b/system-contracts/test/ComplexUpgrader.spec.ts @@ -18,8 +18,9 @@ describe("ComplexUpgrader tests", function () { describe("upgrade", function () { it("non force deployer failed to call", async () => { - await expect(complexUpgrader.upgrade(dummyUpgrade.address, "0xdeadbeef")).to.be.revertedWith( - "Can only be called by FORCE_DEPLOYER" + await expect(complexUpgrader.upgrade(dummyUpgrade.address, "0xdeadbeef")).to.be.revertedWithCustomError( + complexUpgrader, + "Unauthorized" ); }); diff --git a/system-contracts/test/Compressor.spec.ts b/system-contracts/test/Compressor.spec.ts index 094eddd99..363be1d13 100644 --- a/system-contracts/test/Compressor.spec.ts +++ b/system-contracts/test/Compressor.spec.ts @@ -46,8 +46,9 @@ describe("Compressor tests", function () { describe("publishCompressedBytecode", function () { it("should revert when it's a non-bootloader call", async () => { - await expect(compressor.publishCompressedBytecode("0x", "0x0000")).to.be.revertedWith( - "Callable only by the bootloader" + await expect(compressor.publishCompressedBytecode("0x", "0x0000")).to.be.revertedWithCustomError( + compressor, + "CallerMustBeBootloader" ); }); @@ -57,7 +58,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0002" + "deadbeefdeadbeef" + "0000" + "0000" + "0000" + "0000"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when there is no encoded data", async () => { @@ -66,7 +67,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0002" + "deadbeefdeadbeef" + "deadbeefdeadbeef"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the encoded data length is invalid", async () => { @@ -80,7 +81,7 @@ describe("Compressor tests", function () { // The length of the encodedData should be 32 / 4 = 8 bytes await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the dictionary has too many entries", async () => { @@ -101,7 +102,7 @@ describe("Compressor tests", function () { // The dictionary should have at most encode data length entries await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Dictionary should have at most the same number of entries as the encoded data"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the encoded data has chunks where index is out of bounds", async () => { @@ -112,7 +113,7 @@ describe("Compressor tests", function () { // The dictionary has only 1 entry, so at the last entry of the encoded data the chunk index is out of bounds await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded chunk index is out of bounds"); + ).to.be.revertedWithCustomError(compressor, "IndexOutOfBounds"); }); it("should revert when the encoded data has chunks that does not match the original bytecode", async () => { @@ -122,7 +123,7 @@ describe("Compressor tests", function () { "0x0002" + "deadbeefdeadbeef" + "1111111111111111" + "0001" + "0000" + "0000" + "0001"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded chunk does not match the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("should revert when the bytecode length in bytes is invalid", async () => { @@ -131,7 +132,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0001" + "deadbeefdeadbeef" + "0000" + "0000" + "0000"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("po"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the bytecode length in words is odd", async () => { @@ -140,7 +141,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0001" + "deadbeefdeadbeef" + "0000".repeat(4 * 2); await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("pr"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); // Test case with too big bytecode is unrealistic because API cannot accept so much data. @@ -183,8 +184,9 @@ describe("Compressor tests", function () { describe("verifyCompressedStateDiffs", function () { it("non l1 messenger failed to call", async () => { - await expect(compressor.verifyCompressedStateDiffs(0, 8, "0x", "0x0000")).to.be.revertedWith( - "Inappropriate caller" + await expect(compressor.verifyCompressedStateDiffs(0, 8, "0x", "0x0000")).to.be.revertedWithCustomError( + compressor, + "Unauthorized" ); }); @@ -202,7 +204,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(9, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 9, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("enumeration index size is too large"); + ).to.be.revertedWithCustomError(compressor, "IndexSizeError"); }); it("initial write key mismatch", async () => { @@ -219,7 +221,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(4, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 4, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("iw: initial key mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("repeated write key mismatch", async () => { @@ -236,7 +238,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(8, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 8, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("rw: enum key mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("no compression value mismatch", async () => { @@ -259,7 +261,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(3, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 3, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("transform or no compression: compressed and final mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("transform value mismatch", async () => { @@ -282,7 +284,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("transform or no compression: compressed and final mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("add value mismatch", async () => { @@ -299,7 +301,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("add: initial plus converted not equal to final"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("sub value mismatch", async () => { @@ -316,7 +318,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("sub: initial minus converted not equal to final"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("invalid operation", async () => { @@ -335,7 +337,7 @@ describe("Compressor tests", function () { compressedStateDiffs = compressedStateDiffsCharArray.join(""); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("unsupported operation"); + ).to.be.revertedWithCustomError(compressor, "UnsupportedOperation"); }); it("Incorrect number of initial storage diffs", async () => { @@ -363,7 +365,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("Incorrect number of initial storage diffs"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("Extra data in compressed state diffs", async () => { @@ -391,7 +393,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("Extra data in _compressedStateDiffs"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("successfully verified", async () => { diff --git a/system-contracts/test/ContractDeployer.spec.ts b/system-contracts/test/ContractDeployer.spec.ts index 6f8984eae..bcae882c0 100644 --- a/system-contracts/test/ContractDeployer.spec.ts +++ b/system-contracts/test/ContractDeployer.spec.ts @@ -68,8 +68,9 @@ describe("ContractDeployer tests", function () { describe("updateAccountVersion", function () { it("non system call failed", async () => { - await expect(contractDeployer.updateAccountVersion(AA_VERSION_NONE)).to.be.revertedWith( - "This method require system call flag" + await expect(contractDeployer.updateAccountVersion(AA_VERSION_NONE)).to.be.revertedWithCustomError( + contractDeployer, + "SystemCallFlagRequired" ); }); @@ -96,8 +97,9 @@ describe("ContractDeployer tests", function () { describe("updateNonceOrdering", function () { it("non system call failed", async () => { - await expect(contractDeployer.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWith( - "This method require system call flag" + await expect(contractDeployer.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWithCustomError( + contractDeployer, + "SystemCallFlagRequired" ); }); @@ -115,9 +117,9 @@ describe("ContractDeployer tests", function () { expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).nonceOrdering).to.be.eq( NONCE_ORDERING_ARBITRARY ); - await expect(contractDeployerSystemCall.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWith( - "It is only possible to change from sequential to arbitrary ordering" - ); + await expect( + contractDeployerSystemCall.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL) + ).to.be.revertedWithCustomError(contractDeployer, "InvalidNonceOrderingChange"); }); }); @@ -233,7 +235,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("zero bytecode hash failed", async () => { @@ -244,7 +246,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("BytecodeHash cannot be zero"); + ).to.be.revertedWithCustomError(contractDeployer, "EmptyBytes32"); }); it("not known bytecode hash failed", async () => { @@ -261,7 +263,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("The code hash is not known"); + ).to.be.revertedWithCustomError(contractDeployer, "UnknownCodeHash"); }); // TODO: other mock events can be checked as well @@ -344,7 +346,7 @@ describe("ContractDeployer tests", function () { "0xdeadbeef", AA_VERSION_NONE ) - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("zero bytecode hash failed", async () => { @@ -355,7 +357,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("BytecodeHash cannot be zero"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "EmptyBytes32"); }); it("not known bytecode hash failed", async () => { @@ -386,7 +388,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("The code hash is not known"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "UnknownCodeHash"); }); it("successfully deployed", async () => { @@ -419,7 +421,7 @@ describe("ContractDeployer tests", function () { "0xdeadbeef", AA_VERSION_NONE ) - ).to.be.revertedWith("Code hash is non-zero"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "HashIsNonZero"); await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { failure: false, returnData: ethers.constants.HashZero, @@ -477,7 +479,7 @@ describe("ContractDeployer tests", function () { it("non system call failed", async () => { await expect( contractDeployer.create(ethers.constants.HashZero, utils.hashBytecode(deployableArtifact.bytecode), "0x") - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("successfully deployed", async () => { @@ -534,7 +536,7 @@ describe("ContractDeployer tests", function () { it("non system call failed", async () => { await expect( contractDeployer.create2(ethers.constants.HashZero, utils.hashBytecode(deployableArtifact.bytecode), "0xabcd") - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("successfully deployed", async () => { @@ -564,8 +566,9 @@ describe("ContractDeployer tests", function () { value: 0, input: "0x", }; - await expect(contractDeployer.forceDeployOnAddress(deploymentData, wallet.address)).to.be.revertedWith( - "Callable only by self" + await expect(contractDeployer.forceDeployOnAddress(deploymentData, wallet.address)).to.be.revertedWithCustomError( + contractDeployer, + "Unauthorized" ); }); @@ -585,7 +588,7 @@ describe("ContractDeployer tests", function () { }; await expect( contractDeployer.connect(deployerAccount).forceDeployOnAddress(deploymentData, wallet.address) - ).to.be.revertedWith("The code hash is not known"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "UnknownCodeHash"); }); it("successfully deployed", async () => { @@ -628,8 +631,9 @@ describe("ContractDeployer tests", function () { input: "0xab", }, ]; - await expect(contractDeployer.forceDeployOnAddresses(deploymentData)).to.be.revertedWith( - "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT" + await expect(contractDeployer.forceDeployOnAddresses(deploymentData)).to.be.revertedWithCustomError( + contractDeployer, + "Unauthorized" ); }); diff --git a/system-contracts/test/ImmutableSimulator.spec.ts b/system-contracts/test/ImmutableSimulator.spec.ts index 530fa370c..0adce4c2e 100644 --- a/system-contracts/test/ImmutableSimulator.spec.ts +++ b/system-contracts/test/ImmutableSimulator.spec.ts @@ -31,8 +31,9 @@ describe("ImmutableSimulator tests", function () { describe("setImmutables", function () { it("non-deployer failed to call", async () => { - await expect(immutableSimulator.setImmutables(RANDOM_ADDRESS, IMMUTABLES_DATA)).to.be.revertedWith( - "Callable only by the deployer system contract" + await expect(immutableSimulator.setImmutables(RANDOM_ADDRESS, IMMUTABLES_DATA)).to.be.revertedWithCustomError( + immutableSimulator, + "Unauthorized" ); }); diff --git a/system-contracts/test/KnownCodesStorage.spec.ts b/system-contracts/test/KnownCodesStorage.spec.ts index 9558f85dc..36a034cb7 100644 --- a/system-contracts/test/KnownCodesStorage.spec.ts +++ b/system-contracts/test/KnownCodesStorage.spec.ts @@ -50,21 +50,22 @@ describe("KnownCodesStorage tests", function () { describe("markBytecodeAsPublished", function () { it("non-compressor failed to call", async () => { - await expect(knownCodesStorage.markBytecodeAsPublished(BYTECODE_HASH_1)).to.be.revertedWith( - "Callable only by the compressor" + await expect(knownCodesStorage.markBytecodeAsPublished(BYTECODE_HASH_1)).to.be.revertedWithCustomError( + knownCodesStorage, + "Unauthorized" ); }); it("incorrectly formatted bytecode hash failed to call", async () => { await expect( knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(INCORRECTLY_FORMATTED_HASH) - ).to.be.revertedWith("Incorrectly formatted bytecodeHash"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("invalid length bytecode hash failed to call", async () => { await expect( knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(INVALID_LENGTH_HASH) - ).to.be.revertedWith("Code length in words must be odd"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("successfully marked", async () => { @@ -85,9 +86,9 @@ describe("KnownCodesStorage tests", function () { describe("markFactoryDeps", function () { it("non-bootloader failed to call", async () => { - await expect(knownCodesStorage.markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3])).to.be.revertedWith( - "Callable only by the bootloader" - ); + await expect( + knownCodesStorage.markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3]) + ).to.be.revertedWithCustomError(knownCodesStorage, "CallerMustBeBootloader"); }); it("incorrectly formatted bytecode hash failed to call", async () => { @@ -95,13 +96,13 @@ describe("KnownCodesStorage tests", function () { knownCodesStorage .connect(bootloaderAccount) .markFactoryDeps(true, [BYTECODE_HASH_2, INCORRECTLY_FORMATTED_HASH]) - ).to.be.revertedWith("Incorrectly formatted bytecodeHash"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("invalid length bytecode hash failed to call", async () => { await expect( knownCodesStorage.connect(bootloaderAccount).markFactoryDeps(false, [INVALID_LENGTH_HASH, BYTECODE_HASH_3]) - ).to.be.revertedWith("Code length in words must be odd"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("successfully marked", async () => { diff --git a/system-contracts/test/L1Messenger.spec.ts b/system-contracts/test/L1Messenger.spec.ts index 74f16fc10..6910bc9f5 100644 --- a/system-contracts/test/L1Messenger.spec.ts +++ b/system-contracts/test/L1Messenger.spec.ts @@ -99,7 +99,7 @@ describe("L1Messenger tests", () => { l1Messenger .connect(bootloaderAccount) .publishPubdataAndClearState(emulator.buildTotalL2ToL1PubdataAndStateDiffs({ numberOfLogs: 0x4002 })) - ).to.be.rejectedWith("Too many L2->L1 logs"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert logshashes mismatch", async () => { @@ -121,7 +121,7 @@ describe("L1Messenger tests", () => { l1Messenger .connect(bootloaderAccount) .publishPubdataAndClearState(emulator.buildTotalL2ToL1PubdataAndStateDiffs(overrideData)) - ).to.be.rejectedWith("reconstructedChainedLogsHash is not equal to chainedLogsHash"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert chainedMessageHash mismatch", async () => { @@ -133,7 +133,7 @@ describe("L1Messenger tests", () => { l1Messenger .connect(bootloaderAccount) .publishPubdataAndClearState(emulator.buildTotalL2ToL1PubdataAndStateDiffs(overrideData)) - ).to.be.rejectedWith("reconstructedChainedMessagesHash is not equal to chainedMessagesHash"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert state diff compression version mismatch", async () => { @@ -151,7 +151,7 @@ describe("L1Messenger tests", () => { version: ethers.utils.hexZeroPad(ethers.utils.hexlify(66), 1), }) ) - ).to.be.rejectedWith("state diff compression version mismatch"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert extra data", async () => { @@ -162,14 +162,15 @@ describe("L1Messenger tests", () => { .publishPubdataAndClearState( ethers.utils.concat([emulator.buildTotalL2ToL1PubdataAndStateDiffs(), Buffer.alloc(1, 64)]) ) - ).to.be.rejectedWith("Extra data in the totalL2ToL1Pubdata array"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); }); describe("sendL2ToL1Log", async () => { it("should revert when not called by the system contract", async () => { - await expect(l1Messenger.sendL2ToL1Log(true, logData.key, logData.value)).to.be.rejectedWith( - "This method require the caller to be system contract" + await expect(l1Messenger.sendL2ToL1Log(true, logData.key, logData.value)).to.be.revertedWithCustomError( + l1Messenger, + "CallerMustBeSystemContract" ); }); @@ -244,7 +245,10 @@ describe("L1Messenger tests", () => { describe("requestBytecodeL1Publication", async () => { it("should revert when not called by known code storage contract", async () => { const byteCodeHash = ethers.utils.hexlify(randomBytes(32)); - await expect(l1Messenger.requestBytecodeL1Publication(byteCodeHash)).to.be.rejectedWith("Inappropriate caller"); + await expect(l1Messenger.requestBytecodeL1Publication(byteCodeHash)).to.be.revertedWithCustomError( + l1Messenger, + "Unauthorized" + ); }); it("should emit event, called by known code system contract", async () => { diff --git a/system-contracts/test/L2BaseToken.spec.ts b/system-contracts/test/L2BaseToken.spec.ts index 3ef04d590..c1b03fb7e 100644 --- a/system-contracts/test/L2BaseToken.spec.ts +++ b/system-contracts/test/L2BaseToken.spec.ts @@ -53,9 +53,9 @@ describe("L2BaseToken tests", () => { it("not called by bootloader", async () => { const amountToMint: BigNumber = ethers.utils.parseEther("10.0"); - await expect(L2BaseToken.connect(wallets[0]).mint(wallets[0].address, amountToMint)).to.be.rejectedWith( - "Callable only by the bootloader" - ); + await expect( + L2BaseToken.connect(wallets[0]).mint(wallets[0].address, amountToMint) + ).to.be.revertedWithCustomError(L2BaseToken, "CallerMustBeBootloader"); }); }); @@ -90,7 +90,7 @@ describe("L2BaseToken tests", () => { await expect( L2BaseToken.connect(bootloaderAccount).transferFromTo(wallets[0].address, wallets[1].address, amountToTransfer) - ).to.be.rejectedWith("Transfer amount exceeds balance"); + ).to.be.revertedWithCustomError(L2BaseToken, "InsufficientFunds"); }); it("no transfer - require special access", async () => { @@ -107,7 +107,7 @@ describe("L2BaseToken tests", () => { wallets[1].address, amountToTransfer ) - ).to.be.rejectedWith("Only system contracts with special access can call this method"); + ).to.be.revertedWithCustomError(L2BaseToken, "Unauthorized"); }); }); diff --git a/system-contracts/test/NonceHolder.spec.ts b/system-contracts/test/NonceHolder.spec.ts index 91e9e3ba4..4c2ea8738 100644 --- a/system-contracts/test/NonceHolder.spec.ts +++ b/system-contracts/test/NonceHolder.spec.ts @@ -78,7 +78,7 @@ describe("NonceHolder tests", () => { await expect( nonceHolder.connect(systemAccount).increaseMinNonce(BigNumber.from(2).pow(32).add(1)) - ).to.be.rejectedWith("The value for incrementing the nonce is too high"); + ).to.be.revertedWithCustomError(nonceHolder, "NonceIncreaseError"); const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); @@ -88,21 +88,26 @@ describe("NonceHolder tests", () => { }); it("should revert This method require system call flag", async () => { - await expect(nonceHolder.increaseMinNonce(123)).to.be.rejectedWith("This method require system call flag"); + await expect(nonceHolder.increaseMinNonce(123)).to.be.revertedWithCustomError( + nonceHolder, + "SystemCallFlagRequired" + ); }); }); describe("incrementMinNonceIfEquals", async () => { it("should revert This method require system call flag", async () => { const expectedNonce = await nonceHolder.getMinNonce(systemAccount.address); - await expect(nonceHolder.incrementMinNonceIfEquals(expectedNonce)).to.be.rejectedWith( - "This method require system call flag" + await expect(nonceHolder.incrementMinNonceIfEquals(expectedNonce)).to.be.revertedWithCustomError( + nonceHolder, + "SystemCallFlagRequired" ); }); it("should revert Incorrect nonce", async () => { - await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.rejectedWith( - "Incorrect nonce" + await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.revertedWithCustomError( + nonceHolder, + "ValuesNotEqual" ); }); @@ -116,8 +121,9 @@ describe("NonceHolder tests", () => { describe("incrementDeploymentNonce", async () => { it("should revert Only the contract deployer can increment the deployment nonce", async () => { - await expect(nonceHolder.incrementDeploymentNonce(deployerAccount.address)).to.be.rejectedWith( - "Only the contract deployer can increment the deployment nonce" + await expect(nonceHolder.incrementDeploymentNonce(deployerAccount.address)).to.be.revertedWithCustomError( + nonceHolder, + "Unauthorized" ); }); @@ -141,8 +147,9 @@ describe("NonceHolder tests", () => { failure: false, returnData: encodedAccountInfo, }); - await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(124, 0)).to.be.rejectedWith( - "Nonce value cannot be set to 0" + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(124, 0)).to.be.revertedWithCustomError( + nonceHolder, + "ZeroNonceError" ); }); @@ -153,8 +160,9 @@ describe("NonceHolder tests", () => { failure: false, returnData: encodedAccountInfo, }); - await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(443, 111)).to.be.rejectedWith( - "Previous nonce has not been used" + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(443, 111)).to.be.revertedWithCustomError( + nonceHolder, + "NonceJumpError" ); }); @@ -235,8 +243,9 @@ describe("NonceHolder tests", () => { describe("validateNonceUsage", () => { it("used nonce & should not be used", async () => { - await expect(nonceHolder.validateNonceUsage(systemAccount.address, 1, false)).to.be.rejectedWith( - "Reusing the same nonce twice" + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 1, false)).to.be.revertedWithCustomError( + nonceHolder, + "NonceAlreadyUsed" ); }); @@ -245,8 +254,9 @@ describe("NonceHolder tests", () => { }); it("not used nonce & should be used", async () => { - await expect(nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, true)).to.be.rejectedWith( - "The nonce was not set as used" + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, true)).to.be.revertedWithCustomError( + nonceHolder, + "NonceNotUsed" ); }); diff --git a/system-contracts/test/PubdataChunkPublisher.spec.ts b/system-contracts/test/PubdataChunkPublisher.spec.ts index 49dd5b05f..f007f2018 100644 --- a/system-contracts/test/PubdataChunkPublisher.spec.ts +++ b/system-contracts/test/PubdataChunkPublisher.spec.ts @@ -37,14 +37,17 @@ describe("PubdataChunkPublisher tests", () => { describe("chunkAndPublishPubdata", () => { it("non-L1Messenger failed to call", async () => { - await expect(pubdataChunkPublisher.chunkAndPublishPubdata("0x1337")).to.be.revertedWith("Inappropriate caller"); + await expect(pubdataChunkPublisher.chunkAndPublishPubdata("0x1337")).to.be.revertedWithCustomError( + pubdataChunkPublisher, + "Unauthorized" + ); }); it("Too Much Pubdata", async () => { const pubdata = genRandHex(blobSizeInBytes * maxNumberBlobs + 1); await expect( pubdataChunkPublisher.connect(l1MessengerAccount).chunkAndPublishPubdata(pubdata) - ).to.be.revertedWith("pubdata should fit in 6 blobs"); + ).to.be.revertedWithCustomError(pubdataChunkPublisher, "TooMuchPubdata"); }); it("Publish 1 Blob", async () => { diff --git a/system-contracts/test/SystemContext.spec.ts b/system-contracts/test/SystemContext.spec.ts index dd23acaf2..2117c59da 100644 --- a/system-contracts/test/SystemContext.spec.ts +++ b/system-contracts/test/SystemContext.spec.ts @@ -28,7 +28,10 @@ describe("SystemContext tests", () => { describe("setTxOrigin", async () => { it("should revert not called by bootlader", async () => { const txOriginExpected = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; - await expect(systemContext.setTxOrigin(txOriginExpected)).to.be.rejectedWith("Callable only by the bootloader"); + await expect(systemContext.setTxOrigin(txOriginExpected)).to.be.revertedWithCustomError( + systemContext, + "CallerMustBeBootloader" + ); }); it("should set tx.origin", async () => { @@ -44,7 +47,10 @@ describe("SystemContext tests", () => { describe("setGasPrice", async () => { it("should revert not called by bootlader", async () => { const newGasPrice = 4294967295; - await expect(systemContext.setGasPrice(newGasPrice)).to.be.rejectedWith("Callable only by the bootloader"); + await expect(systemContext.setGasPrice(newGasPrice)).to.be.revertedWithCustomError( + systemContext, + "CallerMustBeBootloader" + ); }); it("should set tx.gasprice", async () => { @@ -92,7 +98,7 @@ describe("SystemContext tests", () => { const batchHash = await systemContext.getBatchHash(batchData.batchNumber); await expect( systemContext.setNewBatch(batchHash, batchData.batchTimestamp.add(1), batchData.batchNumber.add(1), 1) - ).to.be.rejectedWith("Callable only by the bootloader"); + ).to.be.revertedWithCustomError(systemContext, "CallerMustBeBootloader"); }); it("should revert timestamp should be incremental", async () => { @@ -159,7 +165,7 @@ describe("SystemContext tests", () => { true, 1 ) - ).to.be.rejectedWith("Callable only by the bootloader"); + ).to.be.revertedWithCustomError(systemContext, "CallerMustBeBootloader"); }); it("should revert The timestamp of the L2 block must be greater than or equal to the timestamp of the current batch", async () => { diff --git a/yarn.lock b/yarn.lock index 2c64e92e6..1b462d2be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1067,6 +1067,27 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@pnpm/config.env-replace@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" + integrity sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w== + +"@pnpm/network.ca-file@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz#2ab05e09c1af0cdf2fcf5035bea1484e222f7983" + integrity sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^2.1.0": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz#0058baf1c26cbb63a828f0193795401684ac86f0" + integrity sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA== + dependencies: + "@pnpm/config.env-replace" "^1.1.0" + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" + "@resolver-engine/core@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" @@ -1211,6 +1232,11 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sindresorhus/is@^5.2.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" + integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== + "@sinonjs/commons@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" @@ -1270,6 +1296,13 @@ resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908" integrity sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA== +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + "@trufflesuite/bigint-buffer@1.1.10": version "1.1.10" resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692" @@ -1394,6 +1427,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@^4.0.2": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + "@types/json-schema@^7.0.12": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -1787,6 +1825,11 @@ antlr4@^4.11.0: resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== +antlr4@^4.13.1-patch-1: + version "4.13.1-patch-1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1-patch-1.tgz#946176f863f890964a050c4f18c47fd6f7e57602" + integrity sha512-OjFLWWLzDMV9rdFhpvroCWR4ooktNg9/nvVYSA5z28wuVpU36QUNuioR1XLnQtcjVlf8npjyz593PxnU/f/Cow== + antlr4ts@^0.5.0-alpha.4: version "0.5.0-alpha.4" resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" @@ -2252,6 +2295,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.8: + version "10.2.14" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" + integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== + dependencies: + "@types/http-cache-semantics" "^4.0.2" + get-stream "^6.0.1" + http-cache-semantics "^4.1.1" + keyv "^4.5.3" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" @@ -2552,6 +2613,14 @@ concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@~1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + cookie@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" @@ -2719,6 +2788,13 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-eql@^4.0.1, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -2736,6 +2812,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + deferred-leveldown@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" @@ -3687,6 +3768,11 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -3860,6 +3946,11 @@ get-stdin@~9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" @@ -4037,6 +4128,28 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +got@^12.1.0: + version "12.6.1" + resolved "https://registry.yarnpkg.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" + integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -4251,6 +4364,11 @@ http-basic@^8.1.1: http-response-object "^3.0.1" parse-cache-control "^1.0.1" +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -4278,6 +4396,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^2.1.10: + version "2.2.1" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" + integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -4359,7 +4485,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@^1.3.5: +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -4813,6 +4939,13 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +latest-version@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-7.0.0.tgz#843201591ea81a4d404932eeb61240fe04e9e5da" + integrity sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg== + dependencies: + package-json "^8.1.0" + level-codec@^9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" @@ -5033,6 +5166,11 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5197,6 +5335,16 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.52.0" +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -5441,6 +5589,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" + integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== + number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" @@ -5553,6 +5706,11 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -5600,6 +5758,16 @@ p-try@^1.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== +package-json@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" + integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== + dependencies: + got "^12.1.0" + registry-auth-token "^5.0.1" + registry-url "^6.0.0" + semver "^7.3.7" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -5798,6 +5966,11 @@ proper-lockfile@^4.1.2: retry "^0.12.0" signal-exit "^3.0.2" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -5861,6 +6034,11 @@ queue-microtask@^1.2.2, queue-microtask@^1.2.3: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.0.1, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -5878,6 +6056,16 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +rc@1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -5951,6 +6139,20 @@ regexp.prototype.flags@^1.5.2: es-errors "^1.3.0" set-function-name "^2.0.1" +registry-auth-token@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" + integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== + dependencies: + "@pnpm/npm-conf" "^2.1.0" + +registry-url@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" + integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== + dependencies: + rc "1.2.8" + req-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" @@ -6001,6 +6203,11 @@ require-from-string@^2.0.0, require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -6028,7 +6235,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.8.1: +resolve@^1.1.6, resolve@^1.22.4, resolve@^1.8.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -6037,6 +6244,13 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.8.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== + dependencies: + lowercase-keys "^3.0.0" + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -6200,6 +6414,11 @@ semver@^7.3.4, semver@^7.5.1, semver@^7.5.2, semver@^7.5.4: dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.6.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" + integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6375,6 +6594,32 @@ solhint-plugin-prettier@^0.0.5: dependencies: prettier-linter-helpers "^1.0.0" +solhint@4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-4.5.4.tgz#171cf33f46c36b8499efe60c0e425f6883a54e50" + integrity sha512-Cu1XiJXub2q1eCr9kkJ9VPv1sGcmj3V7Zb76B0CoezDOB9bu3DxKIFFH7ggCl9fWpEPD6xBmRLfZrYijkVmujQ== + dependencies: + "@solidity-parser/parser" "^0.18.0" + ajv "^6.12.6" + antlr4 "^4.13.1-patch-1" + ast-parents "^0.0.1" + chalk "^4.1.2" + commander "^10.0.0" + cosmiconfig "^8.0.0" + fast-diff "^1.2.0" + glob "^8.0.3" + ignore "^5.2.4" + js-yaml "^4.1.0" + latest-version "^7.0.0" + lodash "^4.17.21" + pluralize "^8.0.0" + semver "^7.5.2" + strip-ansi "^6.0.1" + table "^6.8.1" + text-table "^0.2.0" + optionalDependencies: + prettier "^2.8.3" + solhint@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.6.2.tgz#2b2acbec8fdc37b2c68206a71ba89c7f519943fe" @@ -6598,6 +6843,11 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.1, strip-json-comments@~3.1. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" From d97d8cdec8652ce88a73b7213b77958c46cbc552 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 10:15:27 -0400 Subject: [PATCH 07/42] tests and fix merge conflict --- l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol | 3 ++- l1-contracts/test/test_config/constant/hardhat.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol index 92e90085b..51d24592d 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol @@ -28,6 +28,7 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { // slither-disable-next-line unused-return (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( SafeCast.toUint96(previousProtocolVersion) + ); if (previousMajorVersion != 0) { revert ProtocolMajorVersionNotZero(); @@ -49,7 +50,7 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { // While this is implicitly enforced by other checks above, we still double check just in case if (minorDelta > MAX_ALLOWED_MINOR_VERSION_DELTA) { - revert ProtocolVersionDeltaTooLarge(); + revert ProtocolVersionDeltaTooLarge(minorDelta, MAX_ALLOWED_MINOR_VERSION_DELTA); } // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index 0e63431f0..aeb7ec506 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -95,4 +95,4 @@ "decimals": 18, "address": "0x51E83b811930bb4a3aAb3494894ec237Cb6cEc49" } -] +] \ No newline at end of file From 704b41b39a9e47503f1dab1fe5f8c1293f2bf0a4 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 15:16:57 -0400 Subject: [PATCH 08/42] fix merge conflicts and bump hashes --- .../test/test_config/constant/hardhat.json | 2 +- .../contracts/bridge/L2SharedBridge.sol | 10 ++++---- system-contracts/SystemContractsHashes.json | 25 ------------------- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index aeb7ec506..0e63431f0 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -95,4 +95,4 @@ "decimals": 18, "address": "0x51E83b811930bb4a3aAb3494894ec237Cb6cEc49" } -] \ No newline at end of file +] diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index df0149710..2a0fe1903 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -39,7 +39,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { /// This is non-zero only on Era, and should not be renamed for backward compatibility with the SDKs. address public override l1Bridge; - uint256 internal immutable ERA_CHAIN_ID; + uint256 public immutable ERA_CHAIN_ID; /// @dev Contract is expected to be used as proxy implementation. /// @dev Disable the initialization to prevent Parity hack. @@ -59,7 +59,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { bytes32 _l2TokenProxyBytecodeHash, address _aliasedOwner ) external reinitializer(2) { - if (_l1Bridge == address(0)) { + if (_l1SharedBridge == address(0)) { revert EmptyAddress(); } @@ -79,10 +79,10 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; l2TokenBeacon.transferOwnership(_aliasedOwner); } else { - if (_l1LegacyBridge == address(0)) { + if (_l1Bridge == address(0)) { revert EmptyAddress(); } - l1LegacyBridge = _l1LegacyBridge; + l1Bridge = _l1Bridge; // l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy } } @@ -103,7 +103,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { // Only the L1 bridge counterpart can initiate and finalize the deposit. if ( AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1Bridge && - AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1LegacyBridge + AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1SharedBridge ) { revert InvalidCaller(msg.sender); } diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 9cc1eea74..8dd971976 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -178,60 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", -<<<<<<< HEAD "bytecodeHash": "0x010003cbda052f30cd056d0c758c7cc5be2c31f77461591d4be73dc3291b6ca5", "sourceCodeHash": "0xa13475403f910dff1ea0cf7ebf80633d9dcc37b4f8dd9f0c678a935793580932" -======= - "bytecodeHash": "0x010003cbf67ee7370dd2e77fb9ad39f718ded9354be174ea3009c6cb4fb8c06d", - "sourceCodeHash": "0x232e09be0ce4a92a3b77558e5724ab67e9deaf68e12e8be682a999655203b066" ->>>>>>> release-v23 }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", -<<<<<<< HEAD "bytecodeHash": "0x010009519c960b6baa12091cd1f8538d00fa0d7505c81943ba6e379a5f1c9c9e", "sourceCodeHash": "0xbcdce81799656df718b5dfff4ba6ce8aac82087a78c0c33edb0675e55bb8364c" -======= - "bytecodeHash": "0x01000951968c701c02714779299712d9da6e400e56c78d0d07acd984bfe7242a", - "sourceCodeHash": "0x9b2d51a24186af7ef58f7c8f53d77f6732f3a8d2dbde556fc8c1152957855fa5" ->>>>>>> release-v23 }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", -<<<<<<< HEAD "bytecodeHash": "0x010008d7f0ddbde3a633aa89aff433666ba28dcf3adb35deb26a207ea1824454", "sourceCodeHash": "0xe08f6eaca1995981baf257dd86e5dec8b62c1b5ac53a1173142cebca510b7859" -======= - "bytecodeHash": "0x010008d7dffe019f801bf2ee23b93f83afd80ea6d20c8efe82da71fd57cbcb5c", - "sourceCodeHash": "0xf6624fe716eec6bcd5d513f069f33d758271b304009d2bdf5c5b7d0573868a1c" ->>>>>>> release-v23 }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", -<<<<<<< HEAD "bytecodeHash": "0x01000957fe599ea1dfc3fc958c63b11f46a726d9462078b77c3f28c4db21446c", "sourceCodeHash": "0x97e33d4d96f9ee25e171add92ec7d725de58904dfc68466e4aae1807e9997dc2" -======= - "bytecodeHash": "0x01000957420977a293aab097a368f36b123247d87d4695a6cd27ac62598ab171", - "sourceCodeHash": "0x23293faa6627f60f8b4d61657c615cb2327162dd1e33c0968e9ab4d5dd605a20" ->>>>>>> release-v23 }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", -<<<<<<< HEAD "bytecodeHash": "0x010008e756cd4ef7a22e5bf21b357fda5c90223b7947f38cd3749826a6faff68", "sourceCodeHash": "0x62556a75277d8c72961a1fb9e1d0e1f1cef41c0e8f8d26a6e85cda336a734834" -======= - "bytecodeHash": "0x010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e", - "sourceCodeHash": "0x8ac4971296d0546fc6366caa4089489177656cbc33cc21247947d98c28c6dee4" ->>>>>>> release-v23 } ] From ee5667e5a780774a2f0fa414e5123e206a065d4c Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 15:38:09 -0400 Subject: [PATCH 09/42] fixed lint --- .solhintignore | 3 ++ gas-bound-caller/contracts/GasBoundCaller.sol | 2 +- .../IStateTransitionManager.sol | 1 + .../StateTransitionManager.sol | 2 +- .../chain-deps/facets/Executor.sol | 2 +- l1-contracts/deploy-scripts/AcceptAdmin.s.sol | 2 +- .../deploy-scripts/DeployPaymaster.s.sol | 3 +- .../InitializeSharedBridgeOnL2.sol | 5 +-- .../deploy-scripts/RegisterHyperchain.s.sol | 12 ++++--- l1-contracts/deploy-scripts/Utils.sol | 35 +++++++++++-------- 10 files changed, 41 insertions(+), 26 deletions(-) diff --git a/.solhintignore b/.solhintignore index d6471dfce..8e9f84ade 100644 --- a/.solhintignore +++ b/.solhintignore @@ -22,3 +22,6 @@ system-contracts/contracts/openzeppelin system-contracts/contracts/Constants.sol system-contracts/contracts/test-contracts system-contracts/contracts-preprocessed + +# gas-bound-caller +gas-bound-caller/contracts/test-contracts diff --git a/gas-bound-caller/contracts/GasBoundCaller.sol b/gas-bound-caller/contracts/GasBoundCaller.sol index 4d0ef81cd..78af446ca 100644 --- a/gas-bound-caller/contracts/GasBoundCaller.sol +++ b/gas-bound-caller/contracts/GasBoundCaller.sol @@ -21,7 +21,7 @@ contract GasBoundCaller { uint256 internal constant CALL_ENTRY_OVERHEAD = 800; /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, /// as such relaying the return. - uint256 constant CALL_RETURN_OVERHEAD = 400; + uint256 internal constant CALL_RETURN_OVERHEAD = 400; /// @notice The function that implements limiting of the total gas expenditure of the call. /// @dev On Era, the gas for pubdata is charged at the end of the execution of the entire transaction, meaning diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index 4d7f7fc6b..fef2398a5 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -26,6 +26,7 @@ struct StateTransitionManagerInitializeData { /// @param genesisIndexRepeatedStorageChanges The serial number of the shortcut storage key for the genesis batch /// @param genesisBatchCommitment The zk-proof commitment for the genesis batch /// @param diamondCut The diamond cut for the first upgrade transaction on the newly deployed chain +// solhint-disable-next-line gas-struct-packing struct ChainCreationParams { address genesisUpgrade; bytes32 genesisBatchHash; diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index c0162f468..982e39e58 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors +// solhint-disable gas-custom-errors, reason-string import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 504093d07..217e08a1a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -54,7 +54,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { if (pricingMode == PubdataPricingMode.Validium) { // skipping data validation for validium, we just check that the data is empty require(_newBatch.pubdataCommitments.length == 1, "EF: v0l"); - for (uint8 i = uint8(SystemLogKey.BLOB_ONE_HASH_KEY); i <= uint8(SystemLogKey.BLOB_SIX_HASH_KEY); i++) { + for (uint8 i = uint8(SystemLogKey.BLOB_ONE_HASH_KEY); i <= uint8(SystemLogKey.BLOB_SIX_HASH_KEY); ++i) { logOutput.blobHashes[i - uint8(SystemLogKey.BLOB_ONE_HASH_KEY)] = bytes32(0); } } else if (pubdataSource == uint8(PubdataSource.Blob)) { diff --git a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol index 00ade426a..0af30c279 100644 --- a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol +++ b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol @@ -16,7 +16,7 @@ contract AcceptAdmin is Script { address governor; } - Config config; + Config internal config; function initConfig() public { string memory root = vm.projectRoot(); diff --git a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol index 52b664bc2..f7115a479 100644 --- a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol +++ b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol @@ -8,8 +8,9 @@ import {Utils} from "./Utils.sol"; contract DeployPaymaster is Script { using stdToml for string; - Config config; + Config internal config; + // solhint-disable-next-line gas-struct-packing struct Config { address bridgehubAddress; address l1SharedBridgeProxy; diff --git a/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol b/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol index 8ca7fce03..344ab59a1 100644 --- a/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol +++ b/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol @@ -11,9 +11,10 @@ import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; contract DeployL2Script is Script { using stdToml for string; - Config config; - ContractsBytecodes contracts; + Config internal config; + ContractsBytecodes internal contracts; + // solhint-disable-next-line gas-struct-packing struct Config { address bridgehubAddress; address l1SharedBridgeProxy; diff --git a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol index 4dd8c0636..6da3e5d0b 100644 --- a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol +++ b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -// solhint-disable no-console +// solhint-disable no-console, gas-custom-errors, reason-string import {Script, console2 as console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; @@ -18,9 +18,10 @@ import {PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHy contract RegisterHyperchainScript is Script { using stdToml for string; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - bytes32 constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + bytes32 internal constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); + // solhint-disable-next-line gas-struct-packing struct Config { address deployerAddress; address ownerAddress; @@ -42,7 +43,7 @@ contract RegisterHyperchainScript is Script { address governance; } - Config config; + Config internal config; function run() public { console.log("Deploying Hyperchain"); @@ -175,7 +176,8 @@ contract RegisterHyperchainScript is Script { // Get new diamond proxy address from emitted events Vm.Log[] memory logs = vm.getRecordedLogs(); address diamondProxyAddress; - for (uint256 i = 0; i < logs.length; i++) { + uint256 logsLength = logs.length; + for (uint256 i = 0; i < logsLength; ++i) { if (logs[i].topics[0] == STATE_TRANSITION_NEW_CHAIN_HASH) { diamondProxyAddress = address(uint160(uint256(logs[i].topics[2]))); break; diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 23bcf0ff8..318be6da3 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; +// solhint-disable gas-custom-errors, reason-string + import {Vm} from "forge-std/Vm.sol"; import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; @@ -20,8 +22,8 @@ library Utils { bytes internal constant CREATE2_FACTORY_BYTECODE = hex"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - uint256 constant MAX_PRIORITY_TX_GAS = 72000000; + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + uint256 internal constant MAX_PRIORITY_TX_GAS = 72000000; /** * @dev Get all selectors from the bytecode. @@ -40,12 +42,13 @@ library Utils { // Extract selectors from the result string[] memory parts = vm.split(stringResult, "\n"); - bytes4[] memory selectors = new bytes4[](parts.length); - for (uint256 i = 0; i < parts.length; i++) { + uint256 partsLength = parts.length; + bytes4[] memory selectors = new bytes4[](partsLength); + for (uint256 i = 0; i < partsLength; ++i) { bytes memory part = bytes(parts[i]); bytes memory extractedSelector = new bytes(10); // Selector length 10 is 0x + 4 bytes - for (uint256 j = 0; j < 10; j++) { + for (uint256 j = 0; j < 10; ++j) { extractedSelector[j] = part[j]; } bytes4 selector = bytes4(vm.parseBytes(string(extractedSelector))); @@ -54,7 +57,8 @@ library Utils { // Remove `getName()` selector if existing bool hasGetName = false; - for (uint256 i = 0; i < selectors.length; i++) { + uint256 selectorsLength = selectors.length; + for (uint256 i = 0; i < selectorsLength; ++i) { if (selectors[i] == bytes4(keccak256("getName()"))) { selectors[i] = selectors[selectors.length - 1]; hasGetName = true; @@ -62,8 +66,8 @@ library Utils { } } if (hasGetName) { - bytes4[] memory newSelectors = new bytes4[](selectors.length - 1); - for (uint256 i = 0; i < selectors.length - 1; i++) { + bytes4[] memory newSelectors = new bytes4[](selectorsLength - 1); + for (uint256 i = 0; i < selectorsLength - 1; ++i) { newSelectors[i] = selectors[i]; } return newSelectors; @@ -86,10 +90,11 @@ library Utils { */ function bytesToUint256(bytes memory bys) internal pure returns (uint256 value) { // Add left padding to 32 bytes if needed - if (bys.length < 32) { + uint256 bysLength = bys.length; + if (bysLength < 32) { bytes memory padded = new bytes(32); - for (uint256 i = 0; i < bys.length; i++) { - padded[i + 32 - bys.length] = bys[i]; + for (uint256 i = 0; i < bysLength; ++i) { + padded[i + 32 - bysLength] = bys[i]; } bys = padded; } @@ -192,12 +197,14 @@ library Utils { keccak256(constructorargs) ); - bytes[] memory _factoryDeps = new bytes[](factoryDeps.length + 1); + uint256 factoryDepsLength = factoryDeps.length; + + bytes[] memory _factoryDeps = new bytes[](factoryDepsLength + 1); - for (uint256 i = 0; i < factoryDeps.length; i++) { + for (uint256 i = 0; i < factoryDepsLength; ++i) { _factoryDeps[i] = factoryDeps[i]; } - _factoryDeps[factoryDeps.length] = bytecode; + _factoryDeps[factoryDepsLength] = bytecode; runL1L2Transaction({ l2Calldata: deployData, From 5c4525a603ab37708640c882a61545b1b399d8f3 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 15:49:56 -0400 Subject: [PATCH 10/42] update system contracts hashes and verifier hash --- .../contracts/state-transition/Verifier.sol | 2 +- system-contracts/SystemContractsHashes.json | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 475218a67..cfc1f848b 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -9,7 +9,7 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. /// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. -/// @dev Contract was generated from a verification key with a hash of 0x1d485be42d712856dfe85b3cf7823f020fa5f83cb41c83f9da307fdc2089beee +/// @dev Contract was generated from a verification key with a hash of 0x14f97b81e54b35fe673d8708cc1a19e1ea5b5e348e12d31e39824ed4f42bbca2 /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 8dd971976..5c927c10f 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cbda052f30cd056d0c758c7cc5be2c31f77461591d4be73dc3291b6ca5", - "sourceCodeHash": "0xa13475403f910dff1ea0cf7ebf80633d9dcc37b4f8dd9f0c678a935793580932" + "bytecodeHash": "0x010003cb92f46b717a3351f085b9d0d7cf1b6c164f390487f29da5c3b1f272a1", + "sourceCodeHash": "0xbf798f55f3b5c3d4d29423278bd68c6bb6428f0290f6791b2e20963166b3b21a" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x010009519c960b6baa12091cd1f8538d00fa0d7505c81943ba6e379a5f1c9c9e", - "sourceCodeHash": "0xbcdce81799656df718b5dfff4ba6ce8aac82087a78c0c33edb0675e55bb8364c" + "bytecodeHash": "0x01000951d5e14249434340fe5e6be707157f16d66ca10d0e5fcc110cc674def4", + "sourceCodeHash": "0xc7cd680273e89b1dfc3c6941f69611894c885e26656adfc4586c4eb149285d9d" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d7f0ddbde3a633aa89aff433666ba28dcf3adb35deb26a207ea1824454", - "sourceCodeHash": "0xe08f6eaca1995981baf257dd86e5dec8b62c1b5ac53a1173142cebca510b7859" + "bytecodeHash": "0x010008d7db21670fda613a703321bb109f192ef92a6cef40b07a35a661c4d563", + "sourceCodeHash": "0xaf85e223e2156440f007fed14c9fe8899d33ad2f0aeb7feab3f4fd81d759bfb6" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000957fe599ea1dfc3fc958c63b11f46a726d9462078b77c3f28c4db21446c", - "sourceCodeHash": "0x97e33d4d96f9ee25e171add92ec7d725de58904dfc68466e4aae1807e9997dc2" + "bytecodeHash": "0x0100095722e18e6831abbece78d3bbaac4fe187db091d6be75d0c6f59aff0f7f", + "sourceCodeHash": "0xac0a99374868ffafa2427f23a7fd1f5f8551402904efbdf84f38638cad00ec14" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e756cd4ef7a22e5bf21b357fda5c90223b7947f38cd3749826a6faff68", - "sourceCodeHash": "0x62556a75277d8c72961a1fb9e1d0e1f1cef41c0e8f8d26a6e85cda336a734834" + "bytecodeHash": "0x010008e75c912d19d915dc90467be59c81c8004271b03639354806f669f14ad3", + "sourceCodeHash": "0x25e4cdb4020792f534611de304297e7e0230ed7ea0510bc049862c2540cc458e" } ] From 131f823ef4f91546ce93bc67aaa4b4254cbb22c9 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 16:01:14 -0400 Subject: [PATCH 11/42] update forge-std --- l1-contracts/lib/forge-std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std index 705263c95..52715a217 160000 --- a/l1-contracts/lib/forge-std +++ b/l1-contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit 705263c95892a906d7af65f0f73ce8a4a0c80b80 +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 From 311b82ed6d433f334c2240d1d698662f48407ee0 Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:11:47 +0200 Subject: [PATCH 12/42] chore: zksync-ethers 5.8.0-beta.5 (#387) Co-authored-by: Stanislav Breadless --- .../test-contracts/GasBoundCallerTester.sol | 4 +- gas-bound-caller/package.json | 9 +- gas-bound-caller/test/GasBoundCaller.spec.ts | 5 +- l1-contracts/package.json | 2 +- l1-contracts/scripts/display-governance.ts | 2 +- .../scripts/setup-legacy-bridge-era.ts | 2 +- l1-contracts/src.ts/deploy-test-process.ts | 2 +- .../test/unit_tests/l2-upgrade.test.spec.ts | 2 +- l1-contracts/test/unit_tests/utils.ts | 4 +- l2-contracts/package.json | 6 +- l2-contracts/src/update-l2-erc20-metadata.ts | 2 +- l2-contracts/src/upgrade-bridge-impl.ts | 4 +- l2-contracts/src/utils.ts | 6 +- l2-contracts/test/erc20.test.ts | 4 +- l2-contracts/test/weth.test.ts | 2 +- system-contracts/package.json | 9 +- system-contracts/scripts/calculate-hashes.ts | 2 +- system-contracts/scripts/deploy-preimages.ts | 6 +- system-contracts/scripts/utils.ts | 2 +- .../test/BootloaderUtilities.spec.ts | 2 +- system-contracts/test/CodeOracle.spec.ts | 2 +- system-contracts/test/Create2Factory.spec.ts | 2 +- system-contracts/test/DefaultAccount.spec.ts | 2 +- system-contracts/test/EventWriter.spec.ts | 2 +- system-contracts/test/L1Messenger.spec.ts | 4 +- system-contracts/test/L2BaseToken.spec.ts | 2 +- .../test/PubdataChunkPublisher.spec.ts | 2 +- yarn.lock | 239 ++++++++++++------ 28 files changed, 203 insertions(+), 129 deletions(-) diff --git a/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol b/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol index 8c1b790d6..1314bf0c0 100644 --- a/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol +++ b/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol @@ -57,9 +57,9 @@ contract GasBoundCallerTester is GasBoundCaller { } } - function testReturndataOverhead(uint256 len) external { + function testReturndataOverhead(uint256 _len, uint256 _gasForInner) external { uint256 gasbefore = gasleft(); - this.testReturndataOverheadInner(false, len); + this.testReturndataOverheadInner{gas: _gasForInner}(false, _len); lastRecordedGasLeft = gasbefore - gasleft(); } diff --git a/gas-bound-caller/package.json b/gas-bound-caller/package.json index de6220930..555c18d61 100644 --- a/gas-bound-caller/package.json +++ b/gas-bound-caller/package.json @@ -13,12 +13,11 @@ "eslint-plugin-prettier": "^5.0.1", "ethers": "^5.7.0", "fast-glob": "^3.3.2", - "hardhat": "^2.18.3", - "preprocess": "^3.2.0", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "hardhat": "=2.22.2", + "preprocess": "^3.2.0" }, "devDependencies": { - "@matterlabs/hardhat-zksync-chai-matchers": "^0.1.4", + "@matterlabs/hardhat-zksync-chai-matchers": "^0.2.0", "@matterlabs/hardhat-zksync-node": "^0.0.1-beta.7", "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.0", @@ -38,7 +37,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "zksync-ethers": "5.8.0-beta.5" }, "mocha": { "timeout": 240000, diff --git a/gas-bound-caller/test/GasBoundCaller.spec.ts b/gas-bound-caller/test/GasBoundCaller.spec.ts index 1a970f0fc..5b92e298f 100644 --- a/gas-bound-caller/test/GasBoundCaller.spec.ts +++ b/gas-bound-caller/test/GasBoundCaller.spec.ts @@ -39,15 +39,16 @@ describe("GasBoundCaller tests", function () { }); it("test returndata overhead", async () => { + // The tests' behavior depends on the amount of gas provided to its inner part, so we always provide 40kk await ( - await tester.testReturndataOverhead(10, { + await tester.testReturndataOverhead(10, 40_000_000, { gasLimit: 80_000_000, }) ).wait(); const smallBytecodeGas = await tester.lastRecordedGasLeft(); await ( - await tester.testReturndataOverhead(100000, { + await tester.testReturndataOverhead(100000, 40_000_000, { gasLimit: 80_000_000, }) ).wait(); diff --git a/l1-contracts/package.json b/l1-contracts/package.json index d30c93950..948b1cef9 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -50,7 +50,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "zksync-ethers": "5.8.0-beta.5" }, "scripts": { "build": "hardhat compile", diff --git a/l1-contracts/scripts/display-governance.ts b/l1-contracts/scripts/display-governance.ts index d6b4846f1..0593d580e 100644 --- a/l1-contracts/scripts/display-governance.ts +++ b/l1-contracts/scripts/display-governance.ts @@ -10,7 +10,7 @@ import { applyL1ToL2Alias, getAddressFromEnv } from "../src.ts/utils"; import * as fs from "fs"; import { UpgradeableBeaconFactory } from "../../l2-contracts/typechain/UpgradeableBeaconFactory"; -import { Provider } from "zksync-web3"; +import { Provider } from "zksync-ethers"; const l2SharedBridgeABI = JSON.parse( fs.readFileSync("../zksync/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json").toString() diff --git a/l1-contracts/scripts/setup-legacy-bridge-era.ts b/l1-contracts/scripts/setup-legacy-bridge-era.ts index ffea4ef2d..dde08b6f2 100644 --- a/l1-contracts/scripts/setup-legacy-bridge-era.ts +++ b/l1-contracts/scripts/setup-legacy-bridge-era.ts @@ -15,7 +15,7 @@ import { web3Provider, GAS_MULTIPLIER } from "./utils"; import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; import { ethTestConfig, getAddressFromEnv } from "../src.ts/utils"; import { hashL2Bytecode } from "../../l2-contracts/src/utils"; -import { Provider } from "zksync-web3"; +import { Provider } from "zksync-ethers"; import beaconProxy = require("../../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json"); const provider = web3Provider(); diff --git a/l1-contracts/src.ts/deploy-test-process.ts b/l1-contracts/src.ts/deploy-test-process.ts index fe383e755..d1329d1eb 100644 --- a/l1-contracts/src.ts/deploy-test-process.ts +++ b/l1-contracts/src.ts/deploy-test-process.ts @@ -7,7 +7,7 @@ import * as ethers from "ethers"; import type { BigNumberish, Wallet } from "ethers"; import { Interface } from "ethers/lib/utils"; import * as zkethers from "zksync-ethers"; -import { ETH_ADDRESS_IN_CONTRACTS } from "zksync-ethers/build/src/utils"; +import { ETH_ADDRESS_IN_CONTRACTS } from "zksync-ethers/build/utils"; import * as fs from "fs"; import type { FacetCut } from "./diamondCut"; diff --git a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts index 7352ce8cc..4ea71d99d 100644 --- a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts +++ b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts @@ -3,7 +3,7 @@ import type { BigNumberish } from "ethers"; import { Wallet } from "ethers"; import * as ethers from "ethers"; import * as hardhat from "hardhat"; -import { hashBytecode } from "zksync-ethers/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; import type { AdminFacet, ExecutorFacet, GettersFacet, StateTransitionManager } from "../../typechain"; import { diff --git a/l1-contracts/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts index c42b55c19..2bbf51733 100644 --- a/l1-contracts/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -1,8 +1,8 @@ import * as hardhat from "hardhat"; import type { BigNumberish, BytesLike } from "ethers"; import { BigNumber, ethers } from "ethers"; -import type { Address } from "zksync-ethers/build/src/types"; -import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/src/utils"; +import type { Address } from "zksync-ethers/build/types"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/utils"; import type { IBridgehub } from "../../typechain/IBridgehub"; import type { IL1ERC20Bridge } from "../../typechain/IL1ERC20Bridge"; diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 2f5907461..8cee30d5a 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -3,9 +3,9 @@ "version": "0.1.0", "license": "MIT", "devDependencies": { - "@matterlabs/hardhat-zksync-deploy": "^0.6.5", + "@matterlabs/hardhat-zksync-deploy": "^0.7.0", "@matterlabs/hardhat-zksync-solc": "^0.3.15", - "@matterlabs/hardhat-zksync-verify": "^0.2.0", + "@matterlabs/hardhat-zksync-verify": "^0.4.0", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-verify": "^1.1.0", @@ -28,7 +28,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^5.2.2", - "zksync-web3": "^0.15.4" + "zksync-ethers": "5.8.0-beta.5" }, "scripts": { "build": "hardhat compile", diff --git a/l2-contracts/src/update-l2-erc20-metadata.ts b/l2-contracts/src/update-l2-erc20-metadata.ts index b86589df3..24903acd8 100644 --- a/l2-contracts/src/update-l2-erc20-metadata.ts +++ b/l2-contracts/src/update-l2-erc20-metadata.ts @@ -2,7 +2,7 @@ import * as hre from "hardhat"; import "@nomiclabs/hardhat-ethers"; import { Command } from "commander"; import { Wallet, ethers, BigNumber } from "ethers"; -import { Provider } from "zksync-web3"; +import { Provider } from "zksync-ethers"; import { getNumberFromEnv } from "../../l1-contracts/src.ts/utils"; import { web3Provider } from "../../l1-contracts/scripts/utils"; import { Deployer } from "../../l1-contracts/src.ts/deploy"; diff --git a/l2-contracts/src/upgrade-bridge-impl.ts b/l2-contracts/src/upgrade-bridge-impl.ts index af21fbac0..3d8e77da9 100644 --- a/l2-contracts/src/upgrade-bridge-impl.ts +++ b/l2-contracts/src/upgrade-bridge-impl.ts @@ -6,8 +6,8 @@ import { Command } from "commander"; import { BigNumber, Wallet, ethers } from "ethers"; import * as fs from "fs"; import * as path from "path"; -import { Provider } from "zksync-web3"; -import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-web3/build/src/utils"; +import { Provider } from "zksync-ethers"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/utils"; import { web3Provider } from "../../l1-contracts/scripts/utils"; import { getAddressFromEnv, getNumberFromEnv } from "../../l1-contracts/src.ts/utils"; import { Deployer } from "../../l1-contracts/src.ts/deploy"; diff --git a/l2-contracts/src/utils.ts b/l2-contracts/src/utils.ts index 30fe0876e..c77817a0b 100644 --- a/l2-contracts/src/utils.ts +++ b/l2-contracts/src/utils.ts @@ -9,11 +9,11 @@ import { web3Provider } from "../../l1-contracts/scripts/utils"; import type { BigNumber, BytesLike, Wallet } from "ethers"; import { ethers } from "ethers"; -import type { Provider } from "zksync-web3"; -import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, sleep } from "zksync-web3/build/src/utils"; -import { IERC20Factory } from "zksync-web3/build/typechain"; +import type { Provider } from "zksync-ethers"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, sleep } from "zksync-ethers/build/utils"; import { ERC20Factory } from "../../l1-contracts/typechain"; +import { IERC20Factory } from "../typechain/IERC20Factory"; export const provider = web3Provider(); diff --git a/l2-contracts/test/erc20.test.ts b/l2-contracts/test/erc20.test.ts index 25dfba652..afc5a2ed8 100644 --- a/l2-contracts/test/erc20.test.ts +++ b/l2-contracts/test/erc20.test.ts @@ -2,8 +2,8 @@ import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import { expect } from "chai"; import { ethers } from "ethers"; import * as hre from "hardhat"; -import { Provider, Wallet } from "zksync-web3"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { Provider, Wallet } from "zksync-ethers"; +import { hashBytecode } from "zksync-ethers/build/utils"; import { unapplyL1ToL2Alias } from "./test-utils"; import { L2SharedBridgeFactory, L2StandardERC20Factory } from "../typechain"; import type { L2SharedBridge, L2StandardERC20 } from "../typechain"; diff --git a/l2-contracts/test/weth.test.ts b/l2-contracts/test/weth.test.ts index 00bb921a0..5337b8ae2 100644 --- a/l2-contracts/test/weth.test.ts +++ b/l2-contracts/test/weth.test.ts @@ -2,7 +2,7 @@ import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import { expect } from "chai"; import { ethers } from "ethers"; import * as hre from "hardhat"; -import { Provider, Wallet } from "zksync-web3"; +import { Provider, Wallet } from "zksync-ethers"; import type { L2WrappedBaseToken } from "../typechain/L2WrappedBaseToken"; import type { L2SharedBridge } from "../typechain/L2SharedBridge"; import { L2SharedBridgeFactory } from "../typechain/L2SharedBridgeFactory"; diff --git a/system-contracts/package.json b/system-contracts/package.json index d0d4ff7da..a4e1c45cd 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -4,7 +4,7 @@ "repository": "git@github.com:matter-labs/system-contracts.git", "license": "MIT", "dependencies": { - "@matterlabs/hardhat-zksync-deploy": "^0.6.5", + "@matterlabs/hardhat-zksync-deploy": "^0.7.0", "@matterlabs/hardhat-zksync-solc": "^1.1.4", "commander": "^9.4.1", "eslint": "^8.51.0", @@ -13,11 +13,10 @@ "ethers": "^5.7.0", "fast-glob": "^3.3.2", "hardhat": "=2.22.2", - "preprocess": "^3.2.0", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "preprocess": "^3.2.0" }, "devDependencies": { - "@matterlabs/hardhat-zksync-chai-matchers": "^0.1.4", + "@matterlabs/hardhat-zksync-chai-matchers": "^0.2.0", "@matterlabs/hardhat-zksync-node": "^0.0.1-beta.7", "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.0", @@ -37,7 +36,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "zksync-ethers": "5.8.0-beta.5" }, "mocha": { "timeout": 240000, diff --git a/system-contracts/scripts/calculate-hashes.ts b/system-contracts/scripts/calculate-hashes.ts index 1fe368d75..a8fc8036f 100644 --- a/system-contracts/scripts/calculate-hashes.ts +++ b/system-contracts/scripts/calculate-hashes.ts @@ -3,7 +3,7 @@ import * as fs from "fs"; import _ from "lodash"; import os from "os"; import { join } from "path"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; type ContractDetails = { contractName: string; diff --git a/system-contracts/scripts/deploy-preimages.ts b/system-contracts/scripts/deploy-preimages.ts index 6803f9a53..7a4a96880 100644 --- a/system-contracts/scripts/deploy-preimages.ts +++ b/system-contracts/scripts/deploy-preimages.ts @@ -8,9 +8,9 @@ import { ethers } from "ethers"; import { formatUnits, parseUnits } from "ethers/lib/utils"; import * as fs from "fs"; import * as path from "path"; -import type { types } from "zksync-web3"; -import { Provider, Wallet } from "zksync-web3"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import type { types } from "zksync-ethers"; +import { Provider, Wallet } from "zksync-ethers"; +import { hashBytecode } from "zksync-ethers/build/utils"; import { Language, SYSTEM_CONTRACTS } from "./constants"; import type { Dependency, DeployedDependency } from "./utils"; import { checkMarkers, filterPublishedFactoryDeps, getBytecodes, publishFactoryDeps, readYulBytecode } from "./utils"; diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts index 3314abb83..8df750e6a 100644 --- a/system-contracts/scripts/utils.ts +++ b/system-contracts/scripts/utils.ts @@ -8,7 +8,7 @@ import type { BigNumberish, BytesLike } from "ethers"; import { BigNumber, ethers } from "ethers"; import * as fs from "fs"; import * as fsPr from "fs/promises"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; import type { YulContractDescription, ZasmContractDescription } from "./constants"; import { Language, SYSTEM_CONTRACTS } from "./constants"; import { getCompilersDir } from "hardhat/internal/util/global-dir"; diff --git a/system-contracts/test/BootloaderUtilities.spec.ts b/system-contracts/test/BootloaderUtilities.spec.ts index e47446e33..7c3c8ed69 100644 --- a/system-contracts/test/BootloaderUtilities.spec.ts +++ b/system-contracts/test/BootloaderUtilities.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; import type { Wallet } from "zksync-ethers"; import * as zksync from "zksync-ethers"; -import { serialize } from "zksync-ethers/build/src/utils"; +import { serialize } from "zksync-ethers/build/utils"; import type { BootloaderUtilities } from "../typechain"; import { BootloaderUtilitiesFactory } from "../typechain"; import { TEST_BOOTLOADER_UTILITIES_ADDRESS } from "./shared/constants"; diff --git a/system-contracts/test/CodeOracle.spec.ts b/system-contracts/test/CodeOracle.spec.ts index b4df2ceaf..d9b0c3781 100644 --- a/system-contracts/test/CodeOracle.spec.ts +++ b/system-contracts/test/CodeOracle.spec.ts @@ -1,4 +1,4 @@ -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; import type { CodeOracleTest } from "../typechain"; import { REAL_CODE_ORACLE_CONTRACT_ADDRESS } from "./shared/constants"; import { publishBytecode, setCode, getCode, deployContract } from "./shared/utils"; diff --git a/system-contracts/test/Create2Factory.spec.ts b/system-contracts/test/Create2Factory.spec.ts index 7e84478e0..fc2e689f6 100644 --- a/system-contracts/test/Create2Factory.spec.ts +++ b/system-contracts/test/Create2Factory.spec.ts @@ -3,7 +3,7 @@ import { ethers } from "hardhat"; import type { Wallet } from "zksync-ethers"; import type { Create2Factory } from "../typechain"; import { deployContract, getWallets, loadArtifact } from "./shared/utils"; -import { create2Address, getDeployedContracts, hashBytecode } from "zksync-ethers/build/src/utils"; +import { create2Address, getDeployedContracts, hashBytecode } from "zksync-ethers/build/utils"; describe("Create2Factory tests", function () { let wallet: Wallet; diff --git a/system-contracts/test/DefaultAccount.spec.ts b/system-contracts/test/DefaultAccount.spec.ts index 77dafa1ed..9f3d380d3 100644 --- a/system-contracts/test/DefaultAccount.spec.ts +++ b/system-contracts/test/DefaultAccount.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { ethers, network } from "hardhat"; import type { Wallet } from "zksync-ethers"; import * as zksync from "zksync-ethers"; -import { serialize } from "zksync-web3/build/src/utils"; +import { serialize } from "zksync-ethers/build/utils"; import type { DefaultAccount, DelegateCaller, MockContract } from "../typechain"; import { DefaultAccountFactory } from "../typechain"; import { TEST_BOOTLOADER_FORMAL_ADDRESS } from "./shared/constants"; diff --git a/system-contracts/test/EventWriter.spec.ts b/system-contracts/test/EventWriter.spec.ts index 072f8e35b..35c5d66f7 100644 --- a/system-contracts/test/EventWriter.spec.ts +++ b/system-contracts/test/EventWriter.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; import type { Wallet } from "zksync-ethers"; import { Contract } from "zksync-ethers"; -import type { TransactionResponse } from "zksync-web3/build/src/types"; +import type { TransactionResponse } from "zksync-ethers/build/types"; import { ONE_BYTES32_HEX, REAL_EVENT_WRITER_CONTRACT_ADDRESS } from "./shared/constants"; import { EXTRA_ABI_CALLER_ADDRESS, encodeExtraAbiCallerCalldata } from "./shared/extraAbiCaller"; import { getCode, getWallets, loadYulBytecode, loadZasmBytecode, setCode } from "./shared/utils"; diff --git a/system-contracts/test/L1Messenger.spec.ts b/system-contracts/test/L1Messenger.spec.ts index 6910bc9f5..678da92a9 100644 --- a/system-contracts/test/L1Messenger.spec.ts +++ b/system-contracts/test/L1Messenger.spec.ts @@ -4,8 +4,8 @@ import { L1MessengerFactory } from "../typechain"; import { prepareEnvironment, setResult } from "./shared/mocks"; import type { StateDiff } from "./shared/utils"; import { compressStateDiffs, deployContractOnAddress, encodeStateDiffs, getCode, getWallets } from "./shared/utils"; -import { utils } from "zksync-web3"; -import type { Wallet } from "zksync-web3"; +import { utils } from "zksync-ethers"; +import type { Wallet } from "zksync-ethers"; import { TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, diff --git a/system-contracts/test/L2BaseToken.spec.ts b/system-contracts/test/L2BaseToken.spec.ts index c1b03fb7e..d73f0444d 100644 --- a/system-contracts/test/L2BaseToken.spec.ts +++ b/system-contracts/test/L2BaseToken.spec.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; import { ethers, network } from "hardhat"; -import type { Wallet } from "zksync-web3"; +import type { Wallet } from "zksync-ethers"; import type { L2BaseToken } from "../typechain"; import { L2BaseTokenFactory } from "../typechain"; import { deployContractOnAddress, getWallets, loadArtifact, provider } from "./shared/utils"; diff --git a/system-contracts/test/PubdataChunkPublisher.spec.ts b/system-contracts/test/PubdataChunkPublisher.spec.ts index f007f2018..8dfbfebf9 100644 --- a/system-contracts/test/PubdataChunkPublisher.spec.ts +++ b/system-contracts/test/PubdataChunkPublisher.spec.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; import { ethers, network } from "hardhat"; -import type { Wallet } from "zksync-web3"; +import type { Wallet } from "zksync-ethers"; import type { PubdataChunkPublisher } from "../typechain"; import { PubdataChunkPublisherFactory } from "../typechain"; import { TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, TEST_PUBDATA_CHUNK_PUBLISHER_ADDRESS } from "./shared/constants"; diff --git a/yarn.lock b/yarn.lock index a7f0255e9..903beef88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,10 +10,10 @@ "@babel/highlight" "^7.24.2" picocolors "^1.0.0" -"@babel/helper-validator-identifier@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" - integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== +"@babel/helper-validator-identifier@^7.22.20": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== "@babel/highlight@^7.24.2": version "7.24.2" @@ -679,10 +679,20 @@ resolved "https://registry.yarnpkg.com/@matterlabs/eslint-config-typescript/-/eslint-config-typescript-1.1.2.tgz#a9be4e56aedf298800f247c5049fc412f8b301a7" integrity sha512-AhiWJQr+MSE3RVfgp5XwGoMK7kNSKh6a18+T7hkNJtyycP0306I6IGmuFA5ZVbcakGb+K32fQWzepSkrNCTAGg== -"@matterlabs/hardhat-zksync-chai-matchers@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-chai-matchers/-/hardhat-zksync-chai-matchers-0.1.4.tgz#105cb0ec1367c8fcd3ce7e3773f747c71fff675b" - integrity sha512-eGQWiImg51fmayoQ7smIK/T6QZkSu38PK7xjp1RIrewGzw2ZgqFWGp40jb5oomkf8yOQPk52Hu4TwE3Ntp8CtA== +"@matterlabs/hardhat-zksync-chai-matchers@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-chai-matchers/-/hardhat-zksync-chai-matchers-0.2.1.tgz#d05136d6cf9a53c30f5e7ee9bae95abb72c1000d" + integrity sha512-LXm5r53DLTQC/KXRXzSRmVp5mEJ4tsoKAKyGck2YLHQ9CBdPoC0paVjbyB2MaEuK/k8o4lZu4uaYKgWQNUXeyQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@matterlabs/hardhat-zksync-deploy" "^0.7.0" + "@matterlabs/hardhat-zksync-solc" "1.0.6" + chai "^4.3.7" + chai-as-promised "^7.1.1" + ethers "~5.7.2" + hardhat "^2.14.0" + ordinal "1.0.3" + zksync-ethers "^5.0.0" "@matterlabs/hardhat-zksync-deploy@^0.6.5": version "0.6.6" @@ -693,6 +703,15 @@ chalk "4.1.2" ts-morph "^19.0.0" +"@matterlabs/hardhat-zksync-deploy@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-0.7.0.tgz#e56b73d8f8fbd0f809a779d0028418ea7d914017" + integrity sha512-PGZcuhKsVzZ2IWPt931pK2gA+HDxnCtye+7CwvoOnM6diHeO9tB1QHFX/ywR9ErOW9wpezhPYkVDx9myFrdoqQ== + dependencies: + "@matterlabs/hardhat-zksync-solc" "^1.0.5" + chalk "4.1.2" + ts-morph "^19.0.0" + "@matterlabs/hardhat-zksync-node@^0.0.1-beta.7": version "0.0.1" resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-node/-/hardhat-zksync-node-0.0.1.tgz#d44bda3c0069b149e2a67c9697eb81166b169ea6" @@ -703,25 +722,26 @@ chalk "4.1.2" fs-extra "^11.1.1" -"@matterlabs/hardhat-zksync-solc@0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.1.tgz#e8e67d947098d7bb8925f968544d34e522af5a9c" - integrity sha512-fdlGf/2yZR5ihVNc2ubea1R/nNFXRONL29Fgz5FwB3azB13rPb76fkQgcFIg9zSufHsEy6zUUT029NkxLNA9Sw== +"@matterlabs/hardhat-zksync-solc@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.2.tgz#64121082e88c5ab22eb4e9594d120e504f6af499" + integrity sha512-6NFWPSZiOAoo7wNuhMg4ztj7mMEH+tLrx09WuCbcURrHPijj/KxYNsJD6Uw5lapKr7G8H7SQISGid1/MTXVmXQ== dependencies: "@nomiclabs/hardhat-docker" "^2.0.0" chalk "4.1.2" dockerode "^3.3.4" fs-extra "^11.1.1" + proper-lockfile "^4.1.2" semver "^7.5.1" -"@matterlabs/hardhat-zksync-solc@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.2.tgz#64121082e88c5ab22eb4e9594d120e504f6af499" - integrity sha512-6NFWPSZiOAoo7wNuhMg4ztj7mMEH+tLrx09WuCbcURrHPijj/KxYNsJD6Uw5lapKr7G8H7SQISGid1/MTXVmXQ== +"@matterlabs/hardhat-zksync-solc@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.0.6.tgz#7ef8438e6bb15244691600e2afa77aaff7dff9f0" + integrity sha512-0icYSufXba/Bbb7v2iXuZJ+IbYsiNpR4Wy6UizHnGuFw3OMHgh+saebQphuaN9yyRL2UPGZbPkQFHWBLZj5/xQ== dependencies: "@nomiclabs/hardhat-docker" "^2.0.0" chalk "4.1.2" - dockerode "^3.3.4" + dockerode "^4.0.0" fs-extra "^11.1.1" proper-lockfile "^4.1.2" semver "^7.5.1" @@ -752,16 +772,17 @@ sinon-chai "^3.7.0" undici "^5.14.0" -"@matterlabs/hardhat-zksync-verify@^0.2.0": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.2.2.tgz#daa34bc4404096ed0f44461ee366c1cb0e5a4f2f" - integrity sha512-WgcItoZGY702oJ708uCP5uLvmwzDLBfhMqq2D0Kh1U/3fCTlPza9zMGUFHxKMQYsITKTeQ5zKOjKoi8MXOeUdQ== +"@matterlabs/hardhat-zksync-verify@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.4.0.tgz#f812c19950022fc36728f3796f6bdae5633e2fcd" + integrity sha512-GPZmAumFl3ZMPKbECX7Qw8CriwZKWd1DlCRhoG/6YYc6mFy4+MXkF1XsHLMs5r34N+GDOfbVZVMeftIlJC96Kg== dependencies: - "@matterlabs/hardhat-zksync-solc" "0.4.1" + "@matterlabs/hardhat-zksync-solc" "^1.0.5" "@nomicfoundation/hardhat-verify" "^1.0.2" axios "^1.4.0" chalk "4.1.2" dockerode "^3.3.4" + zksync-ethers "^5.0.0" "@matterlabs/prettier-config@^1.0.3": version "1.0.3" @@ -796,21 +817,16 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== -"@noble/hashes@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@noble/hashes@1.3.3", "@noble/hashes@~1.3.2": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== "@noble/hashes@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== -"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -842,36 +858,71 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.7.tgz#c204edc79643624dbd431b489b254778817d8244" integrity sha512-6tK9Lv/lSfyBvpEQ4nsTfgxyDT1y1Uv/x8Wa+aB+E8qGo3ToexQ1BMVjxJk6PChXCDOWxB3B4KhqaZFjdhl3Ow== +"@nomicfoundation/edr-darwin-arm64@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz#bbb43f0e01f40839b0bd38c2c443cb6910ae955f" + integrity sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg== + "@nomicfoundation/edr-darwin-x64@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.7.tgz#c3b394445084270cc5250d6c1869b0574e7ef810" integrity sha512-1RrQ/1JPwxrYO69e0tglFv5H+ggour5Ii3bb727+yBpBShrxtOTQ7fZyfxA5h62LCN+0Z9wYOPeQ7XFcVurMaQ== +"@nomicfoundation/edr-darwin-x64@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz#b1ffcd9142418fd8498de34a7336b3f977907c86" + integrity sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg== + "@nomicfoundation/edr-linux-arm64-gnu@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.7.tgz#6d65545a44d1323bb7ab08c3306947165d2071de" integrity sha512-ds/CKlBoVXIihjhflhgPn13EdKWed6r5bgvMs/YwRqT5wldQAQJZWAfA2+nYm0Yi2gMGh1RUpBcfkyl4pq7G+g== +"@nomicfoundation/edr-linux-arm64-gnu@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz#8173d16d4f6f2b3e82ba7096d2a1ea3619d8bfa7" + integrity sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ== + "@nomicfoundation/edr-linux-arm64-musl@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.7.tgz#5368534bceac1a8c18b1be6b908caca5d39b0c03" integrity sha512-e29udiRaPujhLkM3+R6ju7QISrcyOqpcaxb2FsDWBkuD7H8uU9JPZEyyUIpEp5uIY0Jh1eEJPKZKIXQmQAEAuw== +"@nomicfoundation/edr-linux-arm64-musl@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz#b1ce293a7c3e0d9f70391e1aef1a82b83b997567" + integrity sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg== + "@nomicfoundation/edr-linux-x64-gnu@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.7.tgz#42349bf5941dbb54a5719942924c6e4e8cde348e" integrity sha512-/xkjmTyv+bbJ4akBCW0qzFKxPOV4AqLOmqurov+s9umHb16oOv72osSa3SdzJED2gHDaKmpMITT4crxbar4Axg== +"@nomicfoundation/edr-linux-x64-gnu@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz#4c12c4e4bfd3d837f5663ad7cbf7cb6d5634ef83" + integrity sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA== + "@nomicfoundation/edr-linux-x64-musl@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.7.tgz#e6babe11c9a8012f1284e6e48c3551861f2a7cd4" integrity sha512-QwBP9xlmsbf/ldZDGLcE4QiAb8Zt46E/+WLpxHBATFhGa7MrpJh6Zse+h2VlrT/SYLPbh2cpHgSmoSlqVxWG9g== +"@nomicfoundation/edr-linux-x64-musl@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz#8842004aa1a47c504f10863687da28b65dca7baa" + integrity sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw== + "@nomicfoundation/edr-win32-x64-msvc@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.7.tgz#1504b98f305f03be153b0220a546985660de9dc6" integrity sha512-j/80DEnkxrF2ewdbk/gQ2EOPvgF0XSsg8D0o4+6cKhUVAW6XwtWKzIphNL6dyD2YaWEPgIrNvqiJK/aln0ww4Q== +"@nomicfoundation/edr-win32-x64-msvc@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz#29d8bbb2edf9912a95f5453855cf17cdcb269957" + integrity sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A== + "@nomicfoundation/edr@^0.3.1": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.3.7.tgz#9c75edf1fcf601617905b2c89acf103f4786d017" @@ -885,6 +936,19 @@ "@nomicfoundation/edr-linux-x64-musl" "0.3.7" "@nomicfoundation/edr-win32-x64-msvc" "0.3.7" +"@nomicfoundation/edr@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.4.0.tgz#4895ecb6ef321136db837458949c37cce4a29459" + integrity sha512-T96DMSogO8TCdbKKctvxfsDljbhFOUKWc9fHJhSeUh71EEho2qR4951LKQF7t7UWEzguVYh/idQr5L/E3QeaMw== + dependencies: + "@nomicfoundation/edr-darwin-arm64" "0.4.0" + "@nomicfoundation/edr-darwin-x64" "0.4.0" + "@nomicfoundation/edr-linux-arm64-gnu" "0.4.0" + "@nomicfoundation/edr-linux-arm64-musl" "0.4.0" + "@nomicfoundation/edr-linux-x64-gnu" "0.4.0" + "@nomicfoundation/edr-linux-x64-musl" "0.4.0" + "@nomicfoundation/edr-win32-x64-msvc" "0.4.0" + "@nomicfoundation/ethereumjs-common@4.0.4": version "4.0.4" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" @@ -2084,11 +2148,6 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - bignumber.js@^9.0.0, bignumber.js@^9.0.1: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -2160,20 +2219,6 @@ boxen@^5.1.2: widest-line "^3.1.0" wrap-ansi "^7.0.0" -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2375,7 +2420,7 @@ chai-as-promised@^7.1.1: dependencies: check-error "^1.0.2" -chai@^4.3.10, chai@^4.3.6: +chai@^4.3.10, chai@^4.3.6, chai@^4.3.7: version "4.4.1" resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== @@ -2851,12 +2896,7 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - -define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -2952,7 +2992,7 @@ dockerode@^3.3.4: docker-modem "^3.0.0" tar-fs "~2.0.1" -dockerode@^4.0.2: +dockerode@^4.0.0, dockerode@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-4.0.2.tgz#dedc8529a1db3ac46d186f5912389899bc309f7d" integrity sha512-9wM1BVpVMFr2Pw3eJNXrYYt6DT9k0xMcsSCjtPvyQ+xa1iPg/Mo3T/gUcwI0B2cczqCeCYRPF8yFYDwtFXT0+w== @@ -3498,7 +3538,7 @@ ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.4, ethereum ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0: +ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0, ethers@~5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -4285,6 +4325,55 @@ hardhat@=2.22.2: uuid "^8.3.2" ws "^7.4.6" +hardhat@^2.14.0: + version "2.22.5" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.5.tgz#7e1a4311fa9e34a1cfe337784eae06706f6469a5" + integrity sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/edr" "^0.4.0" + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-tx" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + adm-zip "^0.4.16" + aggregate-error "^3.0.0" + ansi-escapes "^4.3.0" + boxen "^5.1.2" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + ethereum-cryptography "^1.0.3" + ethereumjs-abi "^0.6.8" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "7.2.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + keccak "^3.0.2" + lodash "^4.17.11" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -5530,21 +5619,11 @@ nan@^2.17.0, nan@^2.18.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== -nan@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" - integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== - nanoid@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - napi-macros@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" @@ -5729,7 +5808,7 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" -ordinal@^1.0.3: +ordinal@1.0.3, ordinal@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== @@ -7393,11 +7472,6 @@ unpipe@1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -7666,15 +7740,16 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== -"zksync-ethers@https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub": - version "5.1.0" - resolved "https://github.com/zksync-sdk/zksync-ethers#28ccbe7d67b170c202b17475e06a82002e6e3acc" +zksync-ethers@5.8.0-beta.5: + version "5.8.0-beta.5" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.8.0-beta.5.tgz#4f70193a86bd1e41b25b0aa5aa32f6d41d52f7c6" + integrity sha512-saT/3OwLgifqzrBG7OujvUMapzXnshAaLzAZMycUtdV20eLSSVkyLIARVwh1M6hMQIUvX2htV0JN82QRMyM3Ig== dependencies: ethers "~5.7.0" -zksync-web3@^0.15.4: - version "0.15.5" - resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.15.5.tgz#aabe379464963ab573e15948660a709f409b5316" - integrity sha512-97gB7OKJL4spegl8fGO54g6cvTd/75G6yFWZWEa2J09zhjTrfqabbwE/GwiUJkFQ5BbzoH4JaTlVz1hoYZI+DQ== +zksync-ethers@^5.0.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.7.2.tgz#e965a9926e6f8168963ab565dd6ad0d38c4f7f18" + integrity sha512-D+wn4nkGixUOek9ZsVvIZ/MHponQ5xvw74FSbDJDv6SLCI4LZALOAc8lF3b1ml8nOkpeE2pGV0VKmHTSquRNJg== dependencies: ethers "~5.7.0" From ab2f13d72e59f449b19fcf979667b94f9fba4b1e Mon Sep 17 00:00:00 2001 From: Dima Zhornyk <55756184+dimazhornyk@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:05:15 +0200 Subject: [PATCH 13/42] feat: check diamond cut hash locally (#525) --- l1-contracts/scripts/register-hyperchain.ts | 14 +++-- l1-contracts/src.ts/deploy-process.ts | 1 + l1-contracts/src.ts/deploy.ts | 59 +++++++++++++++------ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/l1-contracts/scripts/register-hyperchain.ts b/l1-contracts/scripts/register-hyperchain.ts index 755352f9b..3fea4b9f8 100644 --- a/l1-contracts/scripts/register-hyperchain.ts +++ b/l1-contracts/scripts/register-hyperchain.ts @@ -59,12 +59,9 @@ async function main() { program .option("--private-key ") - .option("--chain-id ") .option("--gas-price ") .option("--nonce ") .option("--governor-address ") - .option("--create2-salt ") - .option("--diamond-upgrade-init ") .option("--only-verifier") .option("--validium-mode") .option("--base-token-name ") @@ -106,7 +103,16 @@ async function main() { await deployer.registerToken(baseTokenAddress, useGovernance); } - await deployer.registerHyperchain(baseTokenAddress, cmd.validiumMode, null, gasPrice, useGovernance); + await deployer.registerHyperchain( + baseTokenAddress, + cmd.validiumMode, + null, + gasPrice, + true, + null, + null, + useGovernance + ); await deployer.transferAdminFromDeployerToGovernance(); }); diff --git a/l1-contracts/src.ts/deploy-process.ts b/l1-contracts/src.ts/deploy-process.ts index f495bb69a..94a403fb8 100644 --- a/l1-contracts/src.ts/deploy-process.ts +++ b/l1-contracts/src.ts/deploy-process.ts @@ -93,6 +93,7 @@ export async function registerHyperchain( validiumMode, extraFacets, gasPrice, + false, null, chainId, useGovernance diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 4ff958560..6e3106127 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -34,10 +34,11 @@ import { L1SharedBridgeFactory } from "../typechain/L1SharedBridgeFactory"; import { SingletonFactoryFactory } from "../typechain/SingletonFactoryFactory"; import { ValidatorTimelockFactory } from "../typechain/ValidatorTimelockFactory"; + import type { FacetCut } from "./diamondCut"; import { getCurrentFacetCutsForAdd } from "./diamondCut"; -import { ERC20Factory } from "../typechain"; +import { ERC20Factory, StateTransitionManagerFactory } from "../typechain"; import type { Contract, Overrides } from "@ethersproject/contracts"; let L2_BOOTLOADER_BYTECODE_HASH: string; @@ -81,7 +82,7 @@ export class Deployer { this.chainId = parseInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!); } - public async initialZkSyncHyperchainDiamondCut(extraFacets?: FacetCut[]) { + public async initialZkSyncHyperchainDiamondCut(extraFacets?: FacetCut[], compareDiamondCutHash: boolean = false) { let facetCuts: FacetCut[] = Object.values( await getCurrentFacetCutsForAdd( this.addresses.StateTransition.AdminFacet, @@ -99,7 +100,7 @@ export class Deployer { }; const priorityTxMaxGasLimit = getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT"); - return compileInitialCutHash( + const diamondCut = compileInitialCutHash( facetCuts, verifierParams, L2_BOOTLOADER_BYTECODE_HASH, @@ -110,6 +111,25 @@ export class Deployer { this.addresses.StateTransition.DiamondInit, false ); + + if (compareDiamondCutHash) { + const hash = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCut]) + ); + + console.log(`Diamond cut hash: ${hash}`); + const stm = StateTransitionManagerFactory.connect( + this.addresses.StateTransition.StateTransitionProxy, + this.deployWallet + ); + + const hashFromSTM = await stm.initialCutHash(); + if (hash != hashFromSTM) { + throw new Error(`Has from STM ${hashFromSTM} does not match the computed hash ${hash}`); + } + } + + return diamondCut; } public async deployCreate2Factory(ethTxOptions?: ethers.providers.TransactionRequest) { @@ -685,6 +705,7 @@ export class Deployer { validiumMode: boolean, extraFacets?: FacetCut[], gasPrice?: BigNumberish, + compareDiamondCutHash: boolean = false, nonce?, predefinedChainId?: string, useGovernance: boolean = false @@ -698,7 +719,7 @@ export class Deployer { const inputChainId = predefinedChainId || getNumberFromEnv("CHAIN_ETH_ZKSYNC_NETWORK_ID"); const admin = process.env.CHAIN_ADMIN_ADDRESS || this.ownerAddress; - const diamondCutData = await this.initialZkSyncHyperchainDiamondCut(extraFacets); + const diamondCutData = await this.initialZkSyncHyperchainDiamondCut(extraFacets, compareDiamondCutHash); const initialDiamondCut = new ethers.utils.AbiCoder().encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCutData]); const receipt = await this.executeDirectOrGovernance( @@ -751,7 +772,8 @@ export class Deployer { console.log(`CONTRACTS_DIAMOND_PROXY_ADDR=${diamondProxyAddress}`); } } - this.chainId = parseInt(chainId, 16); + const intChainId = parseInt(chainId, 16); + this.chainId = intChainId; const validatorOneAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR"); const validatorTwoAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR"); @@ -783,18 +805,25 @@ export class Deployer { } const diamondProxy = this.stateTransitionContract(this.deployWallet); - const tx4 = await diamondProxy.setTokenMultiplier(1, 1); - const receipt4 = await tx4.wait(); - if (this.verbose) { - console.log(`BaseTokenMultiplier set, gas used: ${receipt4.gasUsed.toString()}`); - } - - if (validiumMode) { - const tx5 = await diamondProxy.setPubdataPricingMode(PubdataPricingMode.Validium); - const receipt5 = await tx5.wait(); + // if we are using governance, the deployer will not be the admin, so we can't call the diamond proxy directly + if (admin == this.deployWallet.address) { + const tx4 = await diamondProxy.setTokenMultiplier(1, 1); + const receipt4 = await tx4.wait(); if (this.verbose) { - console.log(`Validium mode set, gas used: ${receipt5.gasUsed.toString()}`); + console.log(`BaseTokenMultiplier set, gas used: ${receipt4.gasUsed.toString()}`); } + + if (validiumMode) { + const tx5 = await diamondProxy.setPubdataPricingMode(PubdataPricingMode.Validium); + const receipt5 = await tx5.wait(); + if (this.verbose) { + console.log(`Validium mode set, gas used: ${receipt5.gasUsed.toString()}`); + } + } + } else { + console.warn( + "BaseTokenMultiplier and Validium mode can't be set through the governance, please set it separately, using the admin account" + ); } } From 7d7af53d3e6e8b373145015f8cc9c842bab433f1 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Tue, 18 Jun 2024 10:38:48 +0200 Subject: [PATCH 14/42] Fix incorrect clause (#535) --- .gitignore | 1 + system-contracts/SystemContractsHashes.json | 4 ++-- system-contracts/contracts/ContractDeployer.sol | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 63f96063b..1897dead9 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ l1-contracts/broadcast/* l1-contracts/script-config/* l1-contracts/script-out/* !l1-contracts/script-out/.gitkeep +*.timestamp diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 5c927c10f..f45ca6844 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -31,8 +31,8 @@ "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010004e5219e70c32d67ed1df0c46983a83a382e482abb5c4310ad554f55f738", - "sourceCodeHash": "0x28208c532ed8851077a9bb0a87636215840ce964397ab0767692f956a0fd11b3" + "bytecodeHash": "0x010004e5b06e78c8ffbdf6c578ce9d101d8d852e62e71f79ff8f845e7ada7fc9", + "sourceCodeHash": "0xdc95cb75554260ef8793c7899dbbc681165a441109458b3d058b03a0857d00e3" }, { "contractName": "Create2Factory", diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index 30d5e3930..3148de8ff 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -78,7 +78,7 @@ contract ContractDeployer is IContractDeployer, ISystemContract { AccountInfo memory currentInfo = accountInfo[msg.sender]; if ( - _nonceOrdering != AccountNonceOrdering.Arbitrary && + _nonceOrdering != AccountNonceOrdering.Arbitrary || currentInfo.nonceOrdering != AccountNonceOrdering.Sequential ) { revert InvalidNonceOrderingChange(); From 100b3bfea3444767a04dbeab68c7f0ee6b277d82 Mon Sep 17 00:00:00 2001 From: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:01:14 +0200 Subject: [PATCH 15/42] Adding doc comments to the chain contracts (#530) Signed-off-by: Danil Co-authored-by: Lyova Potyomkin Co-authored-by: kelemeno Co-authored-by: Stanislav Bezkorovainyi Co-authored-by: Raid Ateir Co-authored-by: kelemeno <34402761+kelemeno@users.noreply.github.com> Co-authored-by: Jmunoz Co-authored-by: Bence Haromi Co-authored-by: Danil --- .../contracts/bridge/L1SharedBridge.sol | 21 +++++++++++++-- .../contracts/bridgehub/Bridgehub.sol | 26 +++++++++++++++++++ .../chain-deps/facets/Mailbox.sol | 2 +- .../contracts/bridge/L2SharedBridge.sol | 4 +-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index 541b0e8eb..442f15e8a 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -156,7 +156,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @dev This sets the first post upgrade batch for era, used to check old withdrawals - /// @param _eraLegacyBridgeLastDepositBatch The the zkSync Era batch number that processes the last deposit tx initiated by the legacy bridge + /// @param _eraLegacyBridgeLastDepositBatch The the zkSync Era batch number that processes the last deposit tx initiated by the legacy bridge /// @param _eraLegacyBridgeLastDepositTxNumber The tx number in the _eraLegacyBridgeLastDepositBatch of the last deposit tx initiated by the legacy bridge function setEraLegacyBridgeLastDepositTime( uint256 _eraLegacyBridgeLastDepositBatch, @@ -168,7 +168,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade eraLegacyBridgeLastDepositTxNumber = _eraLegacyBridgeLastDepositTxNumber; } - /// @dev transfer tokens from legacy erc20 bridge or mailbox and set chainBalance as part of migration process + /// @dev Transfer tokens from legacy erc20 bridge or mailbox and set chainBalance as part of migration process. + /// @param _token The address of token to be transferred (address(1) for ether and contract address for ERC20). + /// @param _target The hyperchain or bridge contract address from where to transfer funds. + /// @param _targetChainId The chain ID of the corresponding hyperchain. function transferFundsFromLegacy(address _token, address _target, uint256 _targetChainId) external onlySelf { if (_token == ETH_TOKEN_ADDRESS) { uint256 balanceBefore = address(this).balance; @@ -204,6 +207,8 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } } + /// @dev Accepts ether only from the hyperchain associated with the specified chain ID. + /// @param _chainId The chain ID corresponding to the hyperchain allowed to send ether. function receiveEth(uint256 _chainId) external payable { require(BRIDGE_HUB.getHyperchain(_chainId) == msg.sender, "receiveEth not state transition"); } @@ -215,6 +220,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @notice Allows bridgehub to acquire mintValue for L1->L2 transactions. /// @dev If the corresponding L2 transaction fails, refunds are issued to a refund recipient on L2. + /// @param _chainId The chain ID of the hyperchain to which deposit. + /// @param _prevMsgSender The `msg.sender` address from the external call that initiated current one. + /// @param _l1Token The L1 token address which is deposited. + /// @param _amount The total amount of tokens to be bridged. function bridgehubDepositBaseToken( uint256 _chainId, address _prevMsgSender, @@ -250,6 +259,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @notice Initiates a deposit transaction within Bridgehub, used by `requestL2TransactionTwoBridges`. + /// @param _chainId The chain ID of the hyperchain to which deposit. + /// @param _prevMsgSender The `msg.sender` address from the external call that initiated current one. + /// @param _l2Value The L2 `msg.value` from the L1 -> L2 deposit transaction. + /// @param _data The calldata for the second bridge deposit. function bridgehubDeposit( uint256 _chainId, address _prevMsgSender, @@ -315,6 +328,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @notice Confirms the acceptance of a transaction by the Mailbox, as part of the L2 transaction process within Bridgehub. /// This function is utilized by `requestL2TransactionTwoBridges` to validate the execution of a transaction. + /// @param _chainId The chain ID of the hyperchain to which confirm the deposit. + /// @param _txDataHash The keccak256 hash of abi.encode(msgSender, l1Token, amount) + /// @param _txHash The hash of the L1->L2 transaction to confirm the deposit. function bridgehubConfirmL2Transaction( uint256 _chainId, bytes32 _txDataHash, @@ -665,6 +681,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// of processing an L2 transaction where tokens would be minted. /// @dev If the token is bridged for the first time, the L2 token contract will be deployed. Note however, that the /// newly-deployed token does not support any custom logic, i.e. rebase tokens' functionality is not supported. + /// @param _prevMsgSender The `msg.sender` address from the external call that initiated current one. /// @param _l2Receiver The account address that should receive funds on L2 /// @param _l1Token The L1 token address which is deposited /// @param _amount The total amount of tokens to be bridged diff --git a/l1-contracts/contracts/bridgehub/Bridgehub.sol b/l1-contracts/contracts/bridgehub/Bridgehub.sol index 8a1498fec..51e3af1eb 100644 --- a/l1-contracts/contracts/bridgehub/Bridgehub.sol +++ b/l1-contracts/contracts/bridgehub/Bridgehub.sol @@ -16,6 +16,11 @@ import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE, BRIDGEHUB_MIN_SECOND_BRIDGE_ import {BridgehubL2TransactionRequest, L2Message, L2Log, TxStatus} from "../common/Messaging.sol"; import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +/// @dev The Bridgehub contract serves as the primary entry point for L1<->L2 communication, +/// facilitating interactions between end user and bridges. +/// It also manages state transition managers, base tokens, and chain registrations. contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, PausableUpgradeable { /// @notice all the ether is held by the weth bridge IL1SharedBridge public sharedBridge; @@ -155,6 +160,12 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus //// Mailbox forwarder /// @notice forwards function call to Mailbox based on ChainId + /// @param _chainId The chain ID of the hyperchain where to prove L2 message inclusion. + /// @param _batchNumber The executed L2 batch number in which the message appeared + /// @param _index The position in the L2 logs Merkle tree of the l2Log that was sent with the message + /// @param _message Information about the sent message: sender address, the message itself, tx index in the L2 batch where the message was sent + /// @param _proof Merkle proof for inclusion of L2 log that was sent with the message + /// @return Whether the proof is valid function proveL2MessageInclusion( uint256 _chainId, uint256 _batchNumber, @@ -167,6 +178,12 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus } /// @notice forwards function call to Mailbox based on ChainId + /// @param _chainId The chain ID of the hyperchain where to prove L2 log inclusion. + /// @param _batchNumber The executed L2 batch number in which the log appeared + /// @param _index The position of the l2log in the L2 logs Merkle tree + /// @param _log Information about the sent log + /// @param _proof Merkle proof for inclusion of the L2 log + /// @return Whether the proof is correct and L2 log is included in batch function proveL2LogInclusion( uint256 _chainId, uint256 _batchNumber, @@ -179,6 +196,15 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus } /// @notice forwards function call to Mailbox based on ChainId + /// @param _chainId The chain ID of the hyperchain where to prove L1->L2 tx status. + /// @param _l2TxHash The L2 canonical transaction hash + /// @param _l2BatchNumber The L2 batch number where the transaction was processed + /// @param _l2MessageIndex The position in the L2 logs Merkle tree of the l2Log that was sent with the message + /// @param _l2TxNumberInBatch The L2 transaction number in the batch, in which the log was sent + /// @param _merkleProof The Merkle proof of the processing L1 -> L2 transaction + /// @param _status The execution status of the L1 -> L2 transaction (true - success & 0 - fail) + /// @return Whether the proof is correct and the transaction was actually executed with provided status + /// NOTE: It may return `false` for incorrect proof, but it doesn't mean that the L1 -> L2 transaction has an opposite status! function proveL1ToL2TransactionStatus( uint256 _chainId, bytes32 _l2TxHash, diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol index a65a47b55..4c38ef4a2 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -36,7 +36,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { string public constant override getName = "MailboxFacet"; /// @dev Era's chainID - uint256 public immutable ERA_CHAIN_ID; + uint256 internal immutable ERA_CHAIN_ID; constructor(uint256 _eraChainId) { ERA_CHAIN_ID = _eraChainId; diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index 2a0fe1903..a96b45252 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -39,10 +39,10 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { /// This is non-zero only on Era, and should not be renamed for backward compatibility with the SDKs. address public override l1Bridge; - uint256 public immutable ERA_CHAIN_ID; - /// @dev Contract is expected to be used as proxy implementation. /// @dev Disable the initialization to prevent Parity hack. + uint256 public immutable ERA_CHAIN_ID; + constructor(uint256 _eraChainId) { ERA_CHAIN_ID = _eraChainId; _disableInitializers(); From dc7bd136fca7f7bd5e0e9557b8959d0f325fb890 Mon Sep 17 00:00:00 2001 From: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:55:51 +0200 Subject: [PATCH 16/42] Add CI coverage (reopenned to dev) (#543) --- .github/workflows/l1-contracts-ci.yaml | 70 ++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/.github/workflows/l1-contracts-ci.yaml b/.github/workflows/l1-contracts-ci.yaml index 2123b47cb..d761b63ed 100644 --- a/.github/workflows/l1-contracts-ci.yaml +++ b/.github/workflows/l1-contracts-ci.yaml @@ -145,3 +145,73 @@ jobs: - name: Compare run: diff tools/data/Verifier.sol l1-contracts/contracts/state-transition/Verifier.sol + + coverage: + defaults: + run: + working-directory: l1-contracts + needs: [build, lint] + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.18.0 + cache: yarn + + - name: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-l1-${{ github.sha }} + path: | + l1-contracts/artifacts + l1-contracts/cache + l1-contracts/typechain + + - name: Run coverage + run: FOUNDRY_PROFILE=default yarn test:foundry && FOUNDRY_PROFILE=default yarn coverage:foundry --report summary --report lcov + + # To ignore coverage for certain directories modify the paths in this step as needed. The + # below default ignores coverage results for the test and script directories. Alternatively, + # to include coverage in all directories, comment out this step. Note that because this + # filtering applies to the lcov file, the summary table generated in the previous step will + # still include all files and directories. + # The `--rc lcov_branch_coverage=1` part keeps branch info in the filtered report, since lcov + # defaults to removing branch info. + - name: Filter directories + run: | + sudo apt update && sudo apt install -y lcov + lcov --remove lcov.info 'test/*' 'contracts/dev-contracts/*' 'lib/*' --output-file lcov.info --rc lcov_branch_coverage=1 + + # This step posts a detailed coverage report as a comment and deletes previous comments on + # each push. The below step is used to fail coverage if the specified coverage threshold is + # not met. The below step can post a comment (when it's `github-token` is specified) but it's + # not as useful, and this action cannot fail CI based on a minimum coverage threshold, which + # is why we use both in this way. + - name: Post coverage report + if: github.event_name == 'pull_request' # This action fails when ran outside of a pull request. + uses: romeovs/lcov-reporter-action@v0.3.1 + with: + delete-old-comments: true + lcov-file: ./l1-contracts/lcov.info + github-token: ${{ secrets.GITHUB_TOKEN }} # Adds a coverage summary comment to the PR. + + - name: Verify minimum coverage + uses: zgosalvez/github-actions-report-lcov@v2 + with: + coverage-files: ./l1-contracts/lcov.info + working-directory: l1-contracts + minimum-coverage: 85 # Set coverage threshold. From 8fec7ec84138863ed2830da6547a6c55fbb219d8 Mon Sep 17 00:00:00 2001 From: Neo <128649481+neotheprogramist@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:46:02 +0200 Subject: [PATCH 17/42] Mailbox unit testing (#489) Co-authored-by: tommysr <47206288+tommysr@users.noreply.github.com> --- .../dev-contracts/test/DummyBridgehub.sol | 18 ++ .../dev-contracts/test/DummySharedBridge.sol | 53 +++- .../foundry/unit/concrete/Utils/Utils.sol | 8 +- .../unit/concrete/Utils/UtilsFacet.sol | 12 + .../facets/Mailbox/BaseMailboxTests.t.sol | 81 +++++ .../BridgehubRequestL2Transaction.t.sol | 22 +- .../facets/Mailbox/FinalizeWithdrawal.t.sol | 63 ++++ .../Mailbox/ProvingL2LogsInclusion.t.sol | 285 ++++++++++++++++++ .../facets/Mailbox/RequestL2Transaction.t.sol | 153 ++++++++++ .../Mailbox/TransferEthToSharedBridge.t.sol | 53 ++++ .../facets/Mailbox/_Mailbox_Shared.t.sol | 28 +- 11 files changed, 755 insertions(+), 21 deletions(-) create mode 100644 l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol diff --git a/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol b/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol new file mode 100644 index 000000000..79f9dc6e6 --- /dev/null +++ b/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {Bridgehub} from "../../bridgehub/Bridgehub.sol"; + +/// @title DummyBridgehub +/// @notice A test smart contract that allows to set State Transition Manager for a given chain +contract DummyBridgehub is Bridgehub { + // add this to be excluded from coverage report + function test() internal virtual {} + + constructor() Bridgehub() {} + + function setStateTransitionManager(uint256 _chainId, address _stm) external { + stateTransitionManager[_chainId] = _stm; + } +} diff --git a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol index 6e61902f0..18124d860 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol @@ -6,8 +6,14 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; import {TWO_BRIDGES_MAGIC_VALUE} from "../../common/Config.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import {UnsafeBytes} from "contracts/common/libraries/UnsafeBytes.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract DummySharedBridge is PausableUpgradeable { + using SafeERC20 for IERC20; -contract DummySharedBridge { event BridgehubDepositBaseTokenInitiated( uint256 indexed chainId, address indexed from, @@ -19,7 +25,7 @@ contract DummySharedBridge { /// @dev Maps token balances for each chain to prevent unauthorized spending across hyperchains. /// This serves as a security measure until hyperbridging is implemented. - mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) internal chainBalance; + mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) public chainBalance; /// @dev Indicates whether the hyperbridging is enabled for a given chain. mapping(uint256 chainId => bool enabled) internal hyperbridgingEnabled; @@ -38,6 +44,8 @@ contract DummySharedBridge { amountReturnInFinalizeWithdrawal = _amount; } + function receiveEth(uint256 _chainId) external payable {} + function depositLegacyErc20Bridge( address, //_msgSender, address, //_l2Receiver, @@ -75,12 +83,51 @@ contract DummySharedBridge { event Debugger(uint256); + function pause() external { + _pause(); + } + + function unpause() external { + _unpause(); + } + + // This function expects abi encoded data + function _parseL2WithdrawalMessage( + bytes memory _l2ToL1message + ) internal view returns (address l1Receiver, address l1Token, uint256 amount) { + (l1Receiver, l1Token, amount) = abi.decode(_l2ToL1message, (address, address, uint256)); + } + + // simple function to just transfer the funds + function finalizeWithdrawal( + uint256 _chainId, + uint256 _l2BatchNumber, + uint256 _l2MessageIndex, + uint16 _l2TxNumberInBatch, + bytes calldata _message, + bytes32[] calldata _merkleProof + ) external { + (address l1Receiver, address l1Token, uint256 amount) = _parseL2WithdrawalMessage(_message); + + if (l1Token == address(1)) { + bool callSuccess; + // Low-level assembly call, to avoid any memory copying (save gas) + assembly { + callSuccess := call(gas(), l1Receiver, amount, 0, 0, 0, 0) + } + require(callSuccess, "ShB: withdraw failed"); + } else { + // Withdraw funds + IERC20(l1Token).safeTransfer(l1Receiver, amount); + } + } + function bridgehubDepositBaseToken( uint256 _chainId, address _prevMsgSender, address _l1Token, uint256 _amount - ) external payable { + ) external payable whenNotPaused { if (_l1Token == address(1)) { require(msg.value == _amount, "L1SharedBridge: msg.value not equal to amount"); } else { diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol index b52d1e122..1260334fd 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol @@ -244,7 +244,7 @@ library Utils { } function getMailboxSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](7); + bytes4[] memory selectors = new bytes4[](8); selectors[0] = MailboxFacet.proveL2MessageInclusion.selector; selectors[1] = MailboxFacet.proveL2LogInclusion.selector; selectors[2] = MailboxFacet.proveL1ToL2TransactionStatus.selector; @@ -252,11 +252,12 @@ library Utils { selectors[4] = MailboxFacet.requestL2Transaction.selector; selectors[5] = MailboxFacet.bridgehubRequestL2Transaction.selector; selectors[6] = MailboxFacet.l2TransactionBaseCost.selector; + selectors[7] = MailboxFacet.transferEthToSharedBridge.selector; return selectors; } function getUtilsFacetSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](38); + bytes4[] memory selectors = new bytes4[](41); selectors[0] = UtilsFacet.util_setChainId.selector; selectors[1] = UtilsFacet.util_getChainId.selector; selectors[2] = UtilsFacet.util_setBridgehub.selector; @@ -295,6 +296,9 @@ library Utils { selectors[35] = UtilsFacet.util_getIsFrozen.selector; selectors[36] = UtilsFacet.util_setTransactionFilterer.selector; selectors[37] = UtilsFacet.util_setBaseTokenGasPriceMultiplierDenominator.selector; + selectors[38] = UtilsFacet.util_setTotalBatchesExecuted.selector; + selectors[39] = UtilsFacet.util_setL2LogsRootHash.selector; + selectors[40] = UtilsFacet.util_setBaseTokenGasPriceMultiplierNominator.selector; return selectors; } diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol index 01864697d..ce9e659a0 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol @@ -162,6 +162,18 @@ contract UtilsFacet is ZkSyncHyperchainBase { return s.isFrozen; } + function util_setTotalBatchesExecuted(uint256 _numberOfBatches) external { + s.totalBatchesExecuted = _numberOfBatches; + } + + function util_setL2LogsRootHash(uint256 _batchNumber, bytes32 _newHash) external { + s.l2LogsRootHashes[_batchNumber] = _newHash; + } + + function util_setBaseTokenGasPriceMultiplierNominator(uint128 _nominator) external { + s.baseTokenGasPriceMultiplierNominator = _nominator; + } + // add this to be excluded from coverage report function test() internal virtual {} } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol new file mode 100644 index 000000000..8d3d446ef --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; +import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; + +contract MailboxBaseTests is MailboxTest { + function setUp() public virtual { + setupDiamondProxy(); + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + utilsFacet.util_setBaseTokenGasPriceMultiplierNominator(1); + } + + function test_mailboxConstructor() public { + MailboxFacet m = new MailboxFacet(eraChainId); + assertEq(m.ERA_CHAIN_ID(), eraChainId); + } + + function test_RevertWhen_badDenominatorInL2TransactionBaseCost() public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(0); + vm.expectRevert("Mailbox: baseTokenGasPriceDenominator not set"); + mailboxFacet.l2TransactionBaseCost(100, 10000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + } + + function test_successful_getL2TransactionBaseCostPricingModeValidium() public { + uint256 gasPrice = 10000000; + uint256 l2GasLimit = 1000000; + uint256 l2GasPerPubdataByteLimit = REQUIRED_L2_GAS_PRICE_PER_PUBDATA; + + FeeParams memory feeParams = FeeParams({ + pubdataPricingMode: PubdataPricingMode.Validium, + batchOverheadL1Gas: 1000000, + maxPubdataPerBatch: 120000, + maxL2GasPerBatch: 80000000, + priorityTxMaxPubdata: 99000, + minimalL2GasPrice: 250000000 + }); + + utilsFacet.util_setFeeParams(feeParams); + + // this was get from running the function, but more reasonable would be to + // have some invariants that the calculation should keep for min required gas + // price and also gas limit + uint256 l2TransactionBaseCost = 250125000000000; + + assertEq( + mailboxFacet.l2TransactionBaseCost(gasPrice, l2GasLimit, l2GasPerPubdataByteLimit), + l2TransactionBaseCost + ); + } + + function test_successful_getL2TransactionBaseCostPricingModeRollup() public { + uint256 gasPrice = 10000000; + uint256 l2GasLimit = 1000000; + uint256 l2GasPerPubdataByteLimit = REQUIRED_L2_GAS_PRICE_PER_PUBDATA; + + FeeParams memory feeParams = FeeParams({ + pubdataPricingMode: PubdataPricingMode.Rollup, + batchOverheadL1Gas: 1000000, + maxPubdataPerBatch: 120000, + maxL2GasPerBatch: 80000000, + priorityTxMaxPubdata: 99000, + minimalL2GasPrice: 250000000 + }); + + utilsFacet.util_setFeeParams(feeParams); + + // this was get from running the function, but more reasonable would be to + // have some invariants that the calculation should keep for min required gas + // price and also gas limit + uint256 l2TransactionBaseCost = 250125000000000; + + assertEq( + mailboxFacet.l2TransactionBaseCost(gasPrice, l2GasLimit, l2GasPerPubdataByteLimit), + l2TransactionBaseCost + ); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol index d34a6bd7d..73ffff2bf 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol @@ -4,12 +4,16 @@ pragma solidity 0.8.24; import {MailboxTest} from "./_Mailbox_Shared.t.sol"; import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; -import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS} from "contracts/common/Config.sol"; import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; -contract BridgehubRequestL2TransactionTest is MailboxTest { - function test_successWithoutFilterer() public { +contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { + function setUp() public virtual { + setupDiamondProxy(); + } + + function test_success_withoutFilterer() public { address bridgehub = makeAddr("bridgehub"); utilsFacet.util_setBridgehub(bridgehub); @@ -24,7 +28,7 @@ contract BridgehubRequestL2TransactionTest is MailboxTest { assertTrue(canonicalTxHash != bytes32(0), "canonicalTxHash should not be 0"); } - function test_successWithFilterer() public { + function test_success_withFilterer() public { address bridgehub = makeAddr("bridgehub"); TransactionFiltererTrue tf = new TransactionFiltererTrue(); @@ -58,6 +62,16 @@ contract BridgehubRequestL2TransactionTest is MailboxTest { mailboxFacet.bridgehubRequestL2Transaction(req); } + function test_revertWhen_notBridgehub() public { + address bridgehub = makeAddr("bridgehub"); + utilsFacet.util_setBridgehub(bridgehub); + BridgehubL2TransactionRequest memory req = getBridgehubRequestL2TransactionRequest(); + vm.deal(bridgehub, 100 ether); + vm.prank(address(sender)); + vm.expectRevert("Hyperchain: not bridgehub"); + mailboxFacet.bridgehubRequestL2Transaction(req); + } + function getBridgehubRequestL2TransactionRequest() private returns (BridgehubL2TransactionRequest memory req) { bytes[] memory factoryDeps = new bytes[](1); factoryDeps[0] = "11111111111111111111111111111111"; diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol new file mode 100644 index 000000000..14fe3130e --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {DummyBridgehub} from "contracts/dev-contracts/test/DummyBridgehub.sol"; +import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; +import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; + +contract MailboxFinalizeWithdrawal is MailboxTest { + bytes32[] proof; + bytes message; + DummySharedBridge l1SharedBridge; + address baseTokenBridgeAddress; + + function setUp() public virtual { + setupDiamondProxy(); + + l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); + baseTokenBridgeAddress = address(l1SharedBridge); + + proof = new bytes32[](0); + message = "message"; + } + + function test_RevertWhen_notEra() public { + utilsFacet.util_setChainId(eraChainId + 1); + + vm.expectRevert("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + mailboxFacet.finalizeEthWithdrawal({ + _l2BatchNumber: 0, + _l2MessageIndex: 0, + _l2TxNumberInBatch: 0, + _message: message, + _merkleProof: proof + }); + } + + function test_success_withdrawal(uint256 amount) public { + address baseTokenBridge = makeAddr("baseTokenBridge"); + utilsFacet.util_setChainId(eraChainId); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + + address l1Receiver = makeAddr("receiver"); + address l1Token = address(1); + vm.deal(baseTokenBridgeAddress, amount); + + bytes memory message = abi.encode(l1Receiver, l1Token, amount); + + mailboxFacet.finalizeEthWithdrawal({ + _l2BatchNumber: 0, + _l2MessageIndex: 0, + _l2TxNumberInBatch: 0, + _message: message, + _merkleProof: proof + }); + + assertEq(l1Receiver.balance, amount); + assertEq(baseTokenBridgeAddress.balance, 0); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol new file mode 100644 index 000000000..7fa5d8c3c --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {L2Message, L2Log} from "contracts/common/Messaging.sol"; +import "forge-std/Test.sol"; +import {L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L1_GAS_PER_PUBDATA_BYTE, L2_TO_L1_LOG_SERIALIZE_SIZE} from "contracts/common/Config.sol"; +import {L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_BOOTLOADER_ADDRESS} from "contracts/common/L2ContractAddresses.sol"; +import {Merkle} from "contracts/state-transition/libraries/Merkle.sol"; +import {MurkyBase} from "murky/common/MurkyBase.sol"; +import {MerkleTest} from "contracts/dev-contracts/test/MerkleTest.sol"; +import {TxStatus} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; +import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; +import {MerkleTreeNoSort} from "test/foundry/unit/concrete/state-transition/libraries/Merkle/MerkleTreeNoSort.sol"; + +contract MailboxL2LogsProve is MailboxTest { + bytes32[] elements; + MerkleTest merkle; + MerkleTreeNoSort merkleTree; + bytes data; + uint256 batchNumber; + bool isService; + uint8 shardId; + + function setUp() public virtual { + setupDiamondProxy(); + + data = abi.encodePacked("test data"); + merkleTree = new MerkleTreeNoSort(); + merkle = new MerkleTest(); + batchNumber = gettersFacet.getTotalBatchesExecuted(); + isService = true; + shardId = 0; + } + + function _addHashedLogToMerkleTree( + uint8 _shardId, + bool _isService, + uint16 _txNumberInBatch, + address _sender, + bytes32 _key, + bytes32 _value + ) internal returns (uint256 index) { + elements.push(keccak256(abi.encodePacked(_shardId, _isService, _txNumberInBatch, _sender, _key, _value))); + + index = elements.length - 1; + } + + function test_RevertWhen_batchNumberGreaterThanBatchesExecuted() public { + L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); + bytes32[] memory proof = new bytes32[](0); + + vm.expectRevert(bytes("xx")); + mailboxFacet.proveL2MessageInclusion({ + _batchNumber: batchNumber + 1, + _index: 0, + _message: message, + _proof: proof + }); + } + + function test_success_proveL2MessageInclusion() public { + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: 0, + _isService: true, + _txNumberInBatch: 0, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + uint256 secondLogIndex = _addHashedLogToMerkleTree({ + _shardId: 0, + _isService: true, + _txNumberInBatch: 1, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Create L2 message + L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); + + // Get Merkle proof for the first element + bytes32[] memory firstLogProof = merkleTree.getProof(elements, firstLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[firstLogIndex]; + bytes32 calculatedRoot = merkle.calculateRoot(firstLogProof, firstLogIndex, leaf); + + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove L2 message inclusion + bool ret = mailboxFacet.proveL2MessageInclusion(batchNumber, firstLogIndex, message, firstLogProof); + + // Assert that the proof was successful + assertEq(ret, true); + + // Prove L2 message inclusion for wrong leaf + ret = mailboxFacet.proveL2MessageInclusion(batchNumber, secondLogIndex, message, firstLogProof); + + // Assert that the proof has failed + assertEq(ret, false); + } + + function test_success_proveL2LogInclusion() public { + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 0, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + uint256 secondLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 1, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + L2Log memory log = L2Log({ + l2ShardId: shardId, + isService: isService, + txNumberInBatch: 1, + sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + key: bytes32(uint256(uint160(sender))), + value: keccak256(data) + }); + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + // Set root hash for current batch + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Get Merkle proof for the first element + bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[secondLogIndex]; + + bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove l2 log inclusion with correct proof + bool ret = mailboxFacet.proveL2LogInclusion({ + _batchNumber: batchNumber, + _index: secondLogIndex, + _proof: secondLogProof, + _log: log + }); + + // Assert that the proof was successful + assertEq(ret, true); + + // Prove l2 log inclusion with wrong proof + ret = mailboxFacet.proveL2LogInclusion({ + _batchNumber: batchNumber, + _index: firstLogIndex, + _proof: secondLogProof, + _log: log + }); + + // Assert that the proof was successful + assertEq(ret, false); + } + + // this is not possible in case of message, because some default values + // are set during translation from message to log + function test_RevertWhen_proveL2LogInclusionDefaultLog() public { + L2Log memory log = L2Log({ + l2ShardId: 0, + isService: false, + txNumberInBatch: 0, + sender: address(0), + key: bytes32(0), + value: bytes32(0) + }); + + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: 0, + _isService: true, + _txNumberInBatch: 1, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + // Add first element to the Merkle tree + elements.push(keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))); + uint256 secondLogIndex = 1; + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + // Set root hash for current batch + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Get Merkle proof for the first element + bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[secondLogIndex]; + bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove log inclusion reverts + vm.expectRevert(bytes("tw")); + mailboxFacet.proveL2LogInclusion({ + _batchNumber: batchNumber, + _index: secondLogIndex, + _proof: secondLogProof, + _log: log + }); + } + + function test_success_proveL1ToL2TransactionStatus() public { + bytes32 firstL2TxHash = keccak256("firstL2Transaction"); + bytes32 secondL2TxHash = keccak256("SecondL2Transaction"); + TxStatus txStatus = TxStatus.Success; + + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 0, + _sender: L2_BOOTLOADER_ADDRESS, + _key: firstL2TxHash, + _value: bytes32(uint256(txStatus)) + }); + + uint256 secondLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 1, + _sender: L2_BOOTLOADER_ADDRESS, + _key: secondL2TxHash, + _value: bytes32(uint256(txStatus)) + }); + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + // Set root hash for current batch + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Get Merkle proof for the first element + bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[secondLogIndex]; + bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove L1 to L2 transaction status + bool ret = mailboxFacet.proveL1ToL2TransactionStatus({ + _l2TxHash: secondL2TxHash, + _l2BatchNumber: batchNumber, + _l2MessageIndex: secondLogIndex, + _l2TxNumberInBatch: 1, + _merkleProof: secondLogProof, + _status: txStatus + }); + + // Assert that the proof was successful + assertEq(ret, true); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol new file mode 100644 index 000000000..2eee1eefb --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS, ETH_TOKEN_ADDRESS} from "contracts/common/Config.sol"; +import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; +import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; +import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; + +contract MailboxRequestL2TransactionTest is MailboxTest { + address tempAddress; + bytes[] tempBytesArr; + bytes tempBytes; + DummySharedBridge l1SharedBridge; + address baseTokenBridgeAddress; + + function setUp() public virtual { + setupDiamondProxy(); + + l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); + baseTokenBridgeAddress = address(l1SharedBridge); + + tempAddress = makeAddr("temp"); + tempBytesArr = new bytes[](0); + tempBytes = ""; + utilsFacet.util_setChainId(eraChainId); + } + + function test_RevertWhen_NotEra(uint256 randomChainId) public { + vm.assume(eraChainId != randomChainId); + + utilsFacet.util_setChainId(randomChainId); + + vm.expectRevert("Mailbox: legacy interface only available for Era"); + mailboxFacet.requestL2Transaction({ + _contractL2: tempAddress, + _l2Value: 0, + _calldata: tempBytes, + _l2GasLimit: 0, + _l2GasPerPubdataByteLimit: 0, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_wrongL2GasPerPubdataByteLimit() public { + vm.expectRevert(bytes("qp")); + mailboxFacet.requestL2Transaction({ + _contractL2: tempAddress, + _l2Value: 0, + _calldata: tempBytes, + _l2GasLimit: 0, + _l2GasPerPubdataByteLimit: 0, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_msgValueDoesntCoverTx() public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + tempBytesArr = new bytes[](1); + + uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, 1000000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + uint256 l2Value = 1 ether; + uint256 mintValue = baseCost + l2Value; + + vm.expectRevert(bytes("mv")); + mailboxFacet.requestL2Transaction{value: mintValue - 1}({ + _contractL2: tempAddress, + _l2Value: l2Value, + _calldata: tempBytes, + _l2GasLimit: 1000000, + _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_factoryDepsLengthExceeded() public { + tempBytesArr = new bytes[](MAX_NEW_FACTORY_DEPS + 1); + + vm.expectRevert(bytes("uj")); + mailboxFacet.requestL2Transaction({ + _contractL2: tempAddress, + _l2Value: 0, + _calldata: tempBytes, + _l2GasLimit: 0, + _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function _requestL2Transaction( + uint256 amount, + uint256 baseCost, + uint256 l2GasLimit + ) internal returns (bytes32 canonicalTxHash, uint256 mintValue) { + bytes[] memory factoryDeps = new bytes[](1); + factoryDeps[0] = "11111111111111111111111111111111"; + + mintValue = baseCost + amount; + + vm.deal(sender, mintValue); + vm.prank(sender); + canonicalTxHash = mailboxFacet.requestL2Transaction{value: mintValue}({ + _contractL2: tempAddress, + _l2Value: amount, + _calldata: tempBytes, + _l2GasLimit: l2GasLimit, + _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + _factoryDeps: factoryDeps, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_bridgePaused(uint256 randomValue) public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + utilsFacet.util_setPriorityTxMaxGasLimit(100000000); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + + uint256 l2GasLimit = 1000000; + uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + randomValue = bound(randomValue, 0, type(uint256).max - baseCost); + + l1SharedBridge.pause(); + + vm.expectRevert("Pausable: paused"); + _requestL2Transaction(randomValue, baseCost, l2GasLimit); + } + + function test_success_requestL2Transaction(uint256 randomValue) public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + utilsFacet.util_setPriorityTxMaxGasLimit(100000000); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + + uint256 l2GasLimit = 1000000; + uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + randomValue = bound(randomValue, 0, type(uint256).max - baseCost); + + bytes32 canonicalTxHash; + uint256 mintValue; + + (canonicalTxHash, mintValue) = _requestL2Transaction(randomValue, baseCost, l2GasLimit); + assertTrue(canonicalTxHash != bytes32(0), "canonicalTxHash should not be 0"); + assertEq(baseTokenBridgeAddress.balance, mintValue); + assertEq(l1SharedBridge.chainBalance(eraChainId, ETH_TOKEN_ADDRESS), mintValue); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol new file mode 100644 index 000000000..d5815ddc2 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; + + +contract MailboxTransferEthToSharedBridge is MailboxTest { + address baseTokenBridgeAddress; + DummySharedBridge l1SharedBridge; + + function setUp() public virtual { + setupDiamondProxy(); + + l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); + baseTokenBridgeAddress = address(l1SharedBridge); + + utilsFacet.util_setChainId(eraChainId); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + } + + modifier useBaseTokenBridge() { + vm.startPrank(baseTokenBridgeAddress); + _; + vm.stopPrank(); + } + + function test_success_transfer(uint256 randomAmount) public useBaseTokenBridge { + vm.deal(diamondProxy, randomAmount); + + assertEq(address(l1SharedBridge).balance, 0); + assertEq(address(diamondProxy).balance, randomAmount); + mailboxFacet.transferEthToSharedBridge(); + assertEq(address(l1SharedBridge).balance, randomAmount); + assertEq(address(diamondProxy).balance, 0); + } + + function test_RevertWhen_wrongCaller() public { + vm.expectRevert("Hyperchain: Only base token bridge can call this function"); + vm.prank(sender); + mailboxFacet.transferEthToSharedBridge(); + } + + function test_RevertWhen_hyperchainIsNotEra(uint256 randomChainId) public useBaseTokenBridge { + vm.assume(eraChainId != randomChainId); + utilsFacet.util_setChainId(randomChainId); + + vm.expectRevert("Mailbox: transferEthToSharedBridge only available for Era on mailbox"); + mailboxFacet.transferEthToSharedBridge(); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol index 03ab74a8d..32a1e9c55 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol @@ -5,35 +5,32 @@ import {Test} from "forge-std/Test.sol"; import {Utils} from "foundry-test/unit/concrete/Utils/Utils.sol"; import {UtilsFacet} from "foundry-test/unit/concrete/Utils/UtilsFacet.sol"; - +import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {IMailbox} from "contracts/state-transition/chain-interfaces/IMailbox.sol"; +import {IGetters} from "contracts/state-transition/chain-interfaces/IGetters.sol"; import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; contract MailboxTest is Test { IMailbox internal mailboxFacet; UtilsFacet internal utilsFacet; + IGetters internal gettersFacet; address sender; - uint256 eraChainId = 9; + uint256 constant eraChainId = 9; address internal testnetVerifier = address(new TestnetVerifier()); + address diamondProxy; - function getMailboxSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](1); - selectors[0] = IMailbox.bridgehubRequestL2Transaction.selector; - return selectors; - } - - function setUp() public virtual { + function setupDiamondProxy() public { sender = makeAddr("sender"); vm.deal(sender, 100 ether); - Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](2); + Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](3); facetCuts[0] = Diamond.FacetCut({ facet: address(new MailboxFacet(eraChainId)), action: Diamond.Action.Add, isFreezable: true, - selectors: getMailboxSelectors() + selectors: Utils.getMailboxSelectors() }); facetCuts[1] = Diamond.FacetCut({ facet: address(new UtilsFacet()), @@ -41,10 +38,17 @@ contract MailboxTest is Test { isFreezable: true, selectors: Utils.getUtilsFacetSelectors() }); + facetCuts[2] = Diamond.FacetCut({ + facet: address(new GettersFacet()), + action: Diamond.Action.Add, + isFreezable: true, + selectors: Utils.getGettersSelectors() + }); - address diamondProxy = Utils.makeDiamondProxy(facetCuts, testnetVerifier); + diamondProxy = Utils.makeDiamondProxy(facetCuts, testnetVerifier); mailboxFacet = IMailbox(diamondProxy); utilsFacet = UtilsFacet(diamondProxy); + gettersFacet = IGetters(diamondProxy); } // add this to be excluded from coverage report From 116206cf610d438297fc8a41f10fa16a9ad70538 Mon Sep 17 00:00:00 2001 From: Rahul Saxena Date: Thu, 27 Jun 2024 19:28:34 +0530 Subject: [PATCH 18/42] Revert "Mailbox unit testing (#489)" (#558) CI checks were failing in the earlier branch --- .../dev-contracts/test/DummyBridgehub.sol | 18 -- .../dev-contracts/test/DummySharedBridge.sol | 53 +--- .../foundry/unit/concrete/Utils/Utils.sol | 8 +- .../unit/concrete/Utils/UtilsFacet.sol | 12 - .../facets/Mailbox/BaseMailboxTests.t.sol | 81 ----- .../BridgehubRequestL2Transaction.t.sol | 22 +- .../facets/Mailbox/FinalizeWithdrawal.t.sol | 63 ---- .../Mailbox/ProvingL2LogsInclusion.t.sol | 285 ------------------ .../facets/Mailbox/RequestL2Transaction.t.sol | 153 ---------- .../Mailbox/TransferEthToSharedBridge.t.sol | 53 ---- .../facets/Mailbox/_Mailbox_Shared.t.sol | 28 +- 11 files changed, 21 insertions(+), 755 deletions(-) delete mode 100644 l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol delete mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol delete mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol delete mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol delete mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol delete mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol diff --git a/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol b/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol deleted file mode 100644 index 79f9dc6e6..000000000 --- a/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {Bridgehub} from "../../bridgehub/Bridgehub.sol"; - -/// @title DummyBridgehub -/// @notice A test smart contract that allows to set State Transition Manager for a given chain -contract DummyBridgehub is Bridgehub { - // add this to be excluded from coverage report - function test() internal virtual {} - - constructor() Bridgehub() {} - - function setStateTransitionManager(uint256 _chainId, address _stm) external { - stateTransitionManager[_chainId] = _stm; - } -} diff --git a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol index 18124d860..6e61902f0 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol @@ -6,14 +6,8 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; import {TWO_BRIDGES_MAGIC_VALUE} from "../../common/Config.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {UnsafeBytes} from "contracts/common/libraries/UnsafeBytes.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -contract DummySharedBridge is PausableUpgradeable { - using SafeERC20 for IERC20; +contract DummySharedBridge { event BridgehubDepositBaseTokenInitiated( uint256 indexed chainId, address indexed from, @@ -25,7 +19,7 @@ contract DummySharedBridge is PausableUpgradeable { /// @dev Maps token balances for each chain to prevent unauthorized spending across hyperchains. /// This serves as a security measure until hyperbridging is implemented. - mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) public chainBalance; + mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) internal chainBalance; /// @dev Indicates whether the hyperbridging is enabled for a given chain. mapping(uint256 chainId => bool enabled) internal hyperbridgingEnabled; @@ -44,8 +38,6 @@ contract DummySharedBridge is PausableUpgradeable { amountReturnInFinalizeWithdrawal = _amount; } - function receiveEth(uint256 _chainId) external payable {} - function depositLegacyErc20Bridge( address, //_msgSender, address, //_l2Receiver, @@ -83,51 +75,12 @@ contract DummySharedBridge is PausableUpgradeable { event Debugger(uint256); - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - // This function expects abi encoded data - function _parseL2WithdrawalMessage( - bytes memory _l2ToL1message - ) internal view returns (address l1Receiver, address l1Token, uint256 amount) { - (l1Receiver, l1Token, amount) = abi.decode(_l2ToL1message, (address, address, uint256)); - } - - // simple function to just transfer the funds - function finalizeWithdrawal( - uint256 _chainId, - uint256 _l2BatchNumber, - uint256 _l2MessageIndex, - uint16 _l2TxNumberInBatch, - bytes calldata _message, - bytes32[] calldata _merkleProof - ) external { - (address l1Receiver, address l1Token, uint256 amount) = _parseL2WithdrawalMessage(_message); - - if (l1Token == address(1)) { - bool callSuccess; - // Low-level assembly call, to avoid any memory copying (save gas) - assembly { - callSuccess := call(gas(), l1Receiver, amount, 0, 0, 0, 0) - } - require(callSuccess, "ShB: withdraw failed"); - } else { - // Withdraw funds - IERC20(l1Token).safeTransfer(l1Receiver, amount); - } - } - function bridgehubDepositBaseToken( uint256 _chainId, address _prevMsgSender, address _l1Token, uint256 _amount - ) external payable whenNotPaused { + ) external payable { if (_l1Token == address(1)) { require(msg.value == _amount, "L1SharedBridge: msg.value not equal to amount"); } else { diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol index 1260334fd..b52d1e122 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol @@ -244,7 +244,7 @@ library Utils { } function getMailboxSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](8); + bytes4[] memory selectors = new bytes4[](7); selectors[0] = MailboxFacet.proveL2MessageInclusion.selector; selectors[1] = MailboxFacet.proveL2LogInclusion.selector; selectors[2] = MailboxFacet.proveL1ToL2TransactionStatus.selector; @@ -252,12 +252,11 @@ library Utils { selectors[4] = MailboxFacet.requestL2Transaction.selector; selectors[5] = MailboxFacet.bridgehubRequestL2Transaction.selector; selectors[6] = MailboxFacet.l2TransactionBaseCost.selector; - selectors[7] = MailboxFacet.transferEthToSharedBridge.selector; return selectors; } function getUtilsFacetSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](41); + bytes4[] memory selectors = new bytes4[](38); selectors[0] = UtilsFacet.util_setChainId.selector; selectors[1] = UtilsFacet.util_getChainId.selector; selectors[2] = UtilsFacet.util_setBridgehub.selector; @@ -296,9 +295,6 @@ library Utils { selectors[35] = UtilsFacet.util_getIsFrozen.selector; selectors[36] = UtilsFacet.util_setTransactionFilterer.selector; selectors[37] = UtilsFacet.util_setBaseTokenGasPriceMultiplierDenominator.selector; - selectors[38] = UtilsFacet.util_setTotalBatchesExecuted.selector; - selectors[39] = UtilsFacet.util_setL2LogsRootHash.selector; - selectors[40] = UtilsFacet.util_setBaseTokenGasPriceMultiplierNominator.selector; return selectors; } diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol index ce9e659a0..01864697d 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol @@ -162,18 +162,6 @@ contract UtilsFacet is ZkSyncHyperchainBase { return s.isFrozen; } - function util_setTotalBatchesExecuted(uint256 _numberOfBatches) external { - s.totalBatchesExecuted = _numberOfBatches; - } - - function util_setL2LogsRootHash(uint256 _batchNumber, bytes32 _newHash) external { - s.l2LogsRootHashes[_batchNumber] = _newHash; - } - - function util_setBaseTokenGasPriceMultiplierNominator(uint128 _nominator) external { - s.baseTokenGasPriceMultiplierNominator = _nominator; - } - // add this to be excluded from coverage report function test() internal virtual {} } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol deleted file mode 100644 index 8d3d446ef..000000000 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {MailboxTest} from "./_Mailbox_Shared.t.sol"; -import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; -import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; -import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; - -contract MailboxBaseTests is MailboxTest { - function setUp() public virtual { - setupDiamondProxy(); - utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); - utilsFacet.util_setBaseTokenGasPriceMultiplierNominator(1); - } - - function test_mailboxConstructor() public { - MailboxFacet m = new MailboxFacet(eraChainId); - assertEq(m.ERA_CHAIN_ID(), eraChainId); - } - - function test_RevertWhen_badDenominatorInL2TransactionBaseCost() public { - utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(0); - vm.expectRevert("Mailbox: baseTokenGasPriceDenominator not set"); - mailboxFacet.l2TransactionBaseCost(100, 10000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); - } - - function test_successful_getL2TransactionBaseCostPricingModeValidium() public { - uint256 gasPrice = 10000000; - uint256 l2GasLimit = 1000000; - uint256 l2GasPerPubdataByteLimit = REQUIRED_L2_GAS_PRICE_PER_PUBDATA; - - FeeParams memory feeParams = FeeParams({ - pubdataPricingMode: PubdataPricingMode.Validium, - batchOverheadL1Gas: 1000000, - maxPubdataPerBatch: 120000, - maxL2GasPerBatch: 80000000, - priorityTxMaxPubdata: 99000, - minimalL2GasPrice: 250000000 - }); - - utilsFacet.util_setFeeParams(feeParams); - - // this was get from running the function, but more reasonable would be to - // have some invariants that the calculation should keep for min required gas - // price and also gas limit - uint256 l2TransactionBaseCost = 250125000000000; - - assertEq( - mailboxFacet.l2TransactionBaseCost(gasPrice, l2GasLimit, l2GasPerPubdataByteLimit), - l2TransactionBaseCost - ); - } - - function test_successful_getL2TransactionBaseCostPricingModeRollup() public { - uint256 gasPrice = 10000000; - uint256 l2GasLimit = 1000000; - uint256 l2GasPerPubdataByteLimit = REQUIRED_L2_GAS_PRICE_PER_PUBDATA; - - FeeParams memory feeParams = FeeParams({ - pubdataPricingMode: PubdataPricingMode.Rollup, - batchOverheadL1Gas: 1000000, - maxPubdataPerBatch: 120000, - maxL2GasPerBatch: 80000000, - priorityTxMaxPubdata: 99000, - minimalL2GasPrice: 250000000 - }); - - utilsFacet.util_setFeeParams(feeParams); - - // this was get from running the function, but more reasonable would be to - // have some invariants that the calculation should keep for min required gas - // price and also gas limit - uint256 l2TransactionBaseCost = 250125000000000; - - assertEq( - mailboxFacet.l2TransactionBaseCost(gasPrice, l2GasLimit, l2GasPerPubdataByteLimit), - l2TransactionBaseCost - ); - } -} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol index 73ffff2bf..d34a6bd7d 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol @@ -4,16 +4,12 @@ pragma solidity 0.8.24; import {MailboxTest} from "./_Mailbox_Shared.t.sol"; import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; -import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS} from "contracts/common/Config.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; -contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { - function setUp() public virtual { - setupDiamondProxy(); - } - - function test_success_withoutFilterer() public { +contract BridgehubRequestL2TransactionTest is MailboxTest { + function test_successWithoutFilterer() public { address bridgehub = makeAddr("bridgehub"); utilsFacet.util_setBridgehub(bridgehub); @@ -28,7 +24,7 @@ contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { assertTrue(canonicalTxHash != bytes32(0), "canonicalTxHash should not be 0"); } - function test_success_withFilterer() public { + function test_successWithFilterer() public { address bridgehub = makeAddr("bridgehub"); TransactionFiltererTrue tf = new TransactionFiltererTrue(); @@ -62,16 +58,6 @@ contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { mailboxFacet.bridgehubRequestL2Transaction(req); } - function test_revertWhen_notBridgehub() public { - address bridgehub = makeAddr("bridgehub"); - utilsFacet.util_setBridgehub(bridgehub); - BridgehubL2TransactionRequest memory req = getBridgehubRequestL2TransactionRequest(); - vm.deal(bridgehub, 100 ether); - vm.prank(address(sender)); - vm.expectRevert("Hyperchain: not bridgehub"); - mailboxFacet.bridgehubRequestL2Transaction(req); - } - function getBridgehubRequestL2TransactionRequest() private returns (BridgehubL2TransactionRequest memory req) { bytes[] memory factoryDeps = new bytes[](1); factoryDeps[0] = "11111111111111111111111111111111"; diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol deleted file mode 100644 index 14fe3130e..000000000 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {MailboxTest} from "./_Mailbox_Shared.t.sol"; -import {DummyBridgehub} from "contracts/dev-contracts/test/DummyBridgehub.sol"; -import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; -import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; -import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; -import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; - -contract MailboxFinalizeWithdrawal is MailboxTest { - bytes32[] proof; - bytes message; - DummySharedBridge l1SharedBridge; - address baseTokenBridgeAddress; - - function setUp() public virtual { - setupDiamondProxy(); - - l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); - baseTokenBridgeAddress = address(l1SharedBridge); - - proof = new bytes32[](0); - message = "message"; - } - - function test_RevertWhen_notEra() public { - utilsFacet.util_setChainId(eraChainId + 1); - - vm.expectRevert("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); - mailboxFacet.finalizeEthWithdrawal({ - _l2BatchNumber: 0, - _l2MessageIndex: 0, - _l2TxNumberInBatch: 0, - _message: message, - _merkleProof: proof - }); - } - - function test_success_withdrawal(uint256 amount) public { - address baseTokenBridge = makeAddr("baseTokenBridge"); - utilsFacet.util_setChainId(eraChainId); - utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); - - address l1Receiver = makeAddr("receiver"); - address l1Token = address(1); - vm.deal(baseTokenBridgeAddress, amount); - - bytes memory message = abi.encode(l1Receiver, l1Token, amount); - - mailboxFacet.finalizeEthWithdrawal({ - _l2BatchNumber: 0, - _l2MessageIndex: 0, - _l2TxNumberInBatch: 0, - _message: message, - _merkleProof: proof - }); - - assertEq(l1Receiver.balance, amount); - assertEq(baseTokenBridgeAddress.balance, 0); - } -} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol deleted file mode 100644 index 7fa5d8c3c..000000000 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol +++ /dev/null @@ -1,285 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {MailboxTest} from "./_Mailbox_Shared.t.sol"; -import {L2Message, L2Log} from "contracts/common/Messaging.sol"; -import "forge-std/Test.sol"; -import {L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L1_GAS_PER_PUBDATA_BYTE, L2_TO_L1_LOG_SERIALIZE_SIZE} from "contracts/common/Config.sol"; -import {L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_BOOTLOADER_ADDRESS} from "contracts/common/L2ContractAddresses.sol"; -import {Merkle} from "contracts/state-transition/libraries/Merkle.sol"; -import {MurkyBase} from "murky/common/MurkyBase.sol"; -import {MerkleTest} from "contracts/dev-contracts/test/MerkleTest.sol"; -import {TxStatus} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; -import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; -import {MerkleTreeNoSort} from "test/foundry/unit/concrete/state-transition/libraries/Merkle/MerkleTreeNoSort.sol"; - -contract MailboxL2LogsProve is MailboxTest { - bytes32[] elements; - MerkleTest merkle; - MerkleTreeNoSort merkleTree; - bytes data; - uint256 batchNumber; - bool isService; - uint8 shardId; - - function setUp() public virtual { - setupDiamondProxy(); - - data = abi.encodePacked("test data"); - merkleTree = new MerkleTreeNoSort(); - merkle = new MerkleTest(); - batchNumber = gettersFacet.getTotalBatchesExecuted(); - isService = true; - shardId = 0; - } - - function _addHashedLogToMerkleTree( - uint8 _shardId, - bool _isService, - uint16 _txNumberInBatch, - address _sender, - bytes32 _key, - bytes32 _value - ) internal returns (uint256 index) { - elements.push(keccak256(abi.encodePacked(_shardId, _isService, _txNumberInBatch, _sender, _key, _value))); - - index = elements.length - 1; - } - - function test_RevertWhen_batchNumberGreaterThanBatchesExecuted() public { - L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); - bytes32[] memory proof = new bytes32[](0); - - vm.expectRevert(bytes("xx")); - mailboxFacet.proveL2MessageInclusion({ - _batchNumber: batchNumber + 1, - _index: 0, - _message: message, - _proof: proof - }); - } - - function test_success_proveL2MessageInclusion() public { - uint256 firstLogIndex = _addHashedLogToMerkleTree({ - _shardId: 0, - _isService: true, - _txNumberInBatch: 0, - _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, - _key: bytes32(uint256(uint160(sender))), - _value: keccak256(data) - }); - - uint256 secondLogIndex = _addHashedLogToMerkleTree({ - _shardId: 0, - _isService: true, - _txNumberInBatch: 1, - _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, - _key: bytes32(uint256(uint160(sender))), - _value: keccak256(data) - }); - - // Calculate the Merkle root - bytes32 root = merkleTree.getRoot(elements); - utilsFacet.util_setL2LogsRootHash(batchNumber, root); - - // Create L2 message - L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); - - // Get Merkle proof for the first element - bytes32[] memory firstLogProof = merkleTree.getProof(elements, firstLogIndex); - - { - // Calculate the root using the Merkle proof - bytes32 leaf = elements[firstLogIndex]; - bytes32 calculatedRoot = merkle.calculateRoot(firstLogProof, firstLogIndex, leaf); - - // Assert that the calculated root matches the expected root - assertEq(calculatedRoot, root); - } - - // Prove L2 message inclusion - bool ret = mailboxFacet.proveL2MessageInclusion(batchNumber, firstLogIndex, message, firstLogProof); - - // Assert that the proof was successful - assertEq(ret, true); - - // Prove L2 message inclusion for wrong leaf - ret = mailboxFacet.proveL2MessageInclusion(batchNumber, secondLogIndex, message, firstLogProof); - - // Assert that the proof has failed - assertEq(ret, false); - } - - function test_success_proveL2LogInclusion() public { - uint256 firstLogIndex = _addHashedLogToMerkleTree({ - _shardId: shardId, - _isService: isService, - _txNumberInBatch: 0, - _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, - _key: bytes32(uint256(uint160(sender))), - _value: keccak256(data) - }); - - uint256 secondLogIndex = _addHashedLogToMerkleTree({ - _shardId: shardId, - _isService: isService, - _txNumberInBatch: 1, - _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, - _key: bytes32(uint256(uint160(sender))), - _value: keccak256(data) - }); - - L2Log memory log = L2Log({ - l2ShardId: shardId, - isService: isService, - txNumberInBatch: 1, - sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, - key: bytes32(uint256(uint160(sender))), - value: keccak256(data) - }); - - // Calculate the Merkle root - bytes32 root = merkleTree.getRoot(elements); - // Set root hash for current batch - utilsFacet.util_setL2LogsRootHash(batchNumber, root); - - // Get Merkle proof for the first element - bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); - - { - // Calculate the root using the Merkle proof - bytes32 leaf = elements[secondLogIndex]; - - bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); - // Assert that the calculated root matches the expected root - assertEq(calculatedRoot, root); - } - - // Prove l2 log inclusion with correct proof - bool ret = mailboxFacet.proveL2LogInclusion({ - _batchNumber: batchNumber, - _index: secondLogIndex, - _proof: secondLogProof, - _log: log - }); - - // Assert that the proof was successful - assertEq(ret, true); - - // Prove l2 log inclusion with wrong proof - ret = mailboxFacet.proveL2LogInclusion({ - _batchNumber: batchNumber, - _index: firstLogIndex, - _proof: secondLogProof, - _log: log - }); - - // Assert that the proof was successful - assertEq(ret, false); - } - - // this is not possible in case of message, because some default values - // are set during translation from message to log - function test_RevertWhen_proveL2LogInclusionDefaultLog() public { - L2Log memory log = L2Log({ - l2ShardId: 0, - isService: false, - txNumberInBatch: 0, - sender: address(0), - key: bytes32(0), - value: bytes32(0) - }); - - uint256 firstLogIndex = _addHashedLogToMerkleTree({ - _shardId: 0, - _isService: true, - _txNumberInBatch: 1, - _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, - _key: bytes32(uint256(uint160(sender))), - _value: keccak256(data) - }); - - // Add first element to the Merkle tree - elements.push(keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))); - uint256 secondLogIndex = 1; - - // Calculate the Merkle root - bytes32 root = merkleTree.getRoot(elements); - // Set root hash for current batch - utilsFacet.util_setL2LogsRootHash(batchNumber, root); - - // Get Merkle proof for the first element - bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); - - { - // Calculate the root using the Merkle proof - bytes32 leaf = elements[secondLogIndex]; - bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); - // Assert that the calculated root matches the expected root - assertEq(calculatedRoot, root); - } - - // Prove log inclusion reverts - vm.expectRevert(bytes("tw")); - mailboxFacet.proveL2LogInclusion({ - _batchNumber: batchNumber, - _index: secondLogIndex, - _proof: secondLogProof, - _log: log - }); - } - - function test_success_proveL1ToL2TransactionStatus() public { - bytes32 firstL2TxHash = keccak256("firstL2Transaction"); - bytes32 secondL2TxHash = keccak256("SecondL2Transaction"); - TxStatus txStatus = TxStatus.Success; - - uint256 firstLogIndex = _addHashedLogToMerkleTree({ - _shardId: shardId, - _isService: isService, - _txNumberInBatch: 0, - _sender: L2_BOOTLOADER_ADDRESS, - _key: firstL2TxHash, - _value: bytes32(uint256(txStatus)) - }); - - uint256 secondLogIndex = _addHashedLogToMerkleTree({ - _shardId: shardId, - _isService: isService, - _txNumberInBatch: 1, - _sender: L2_BOOTLOADER_ADDRESS, - _key: secondL2TxHash, - _value: bytes32(uint256(txStatus)) - }); - - // Calculate the Merkle root - bytes32 root = merkleTree.getRoot(elements); - // Set root hash for current batch - utilsFacet.util_setL2LogsRootHash(batchNumber, root); - - // Get Merkle proof for the first element - bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); - - { - // Calculate the root using the Merkle proof - bytes32 leaf = elements[secondLogIndex]; - bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); - // Assert that the calculated root matches the expected root - assertEq(calculatedRoot, root); - } - - // Prove L1 to L2 transaction status - bool ret = mailboxFacet.proveL1ToL2TransactionStatus({ - _l2TxHash: secondL2TxHash, - _l2BatchNumber: batchNumber, - _l2MessageIndex: secondLogIndex, - _l2TxNumberInBatch: 1, - _merkleProof: secondLogProof, - _status: txStatus - }); - - // Assert that the proof was successful - assertEq(ret, true); - } -} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol deleted file mode 100644 index 2eee1eefb..000000000 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {MailboxTest} from "./_Mailbox_Shared.t.sol"; -import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; -import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS, ETH_TOKEN_ADDRESS} from "contracts/common/Config.sol"; -import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; -import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; -import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; -import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; -import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; - -contract MailboxRequestL2TransactionTest is MailboxTest { - address tempAddress; - bytes[] tempBytesArr; - bytes tempBytes; - DummySharedBridge l1SharedBridge; - address baseTokenBridgeAddress; - - function setUp() public virtual { - setupDiamondProxy(); - - l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); - baseTokenBridgeAddress = address(l1SharedBridge); - - tempAddress = makeAddr("temp"); - tempBytesArr = new bytes[](0); - tempBytes = ""; - utilsFacet.util_setChainId(eraChainId); - } - - function test_RevertWhen_NotEra(uint256 randomChainId) public { - vm.assume(eraChainId != randomChainId); - - utilsFacet.util_setChainId(randomChainId); - - vm.expectRevert("Mailbox: legacy interface only available for Era"); - mailboxFacet.requestL2Transaction({ - _contractL2: tempAddress, - _l2Value: 0, - _calldata: tempBytes, - _l2GasLimit: 0, - _l2GasPerPubdataByteLimit: 0, - _factoryDeps: tempBytesArr, - _refundRecipient: tempAddress - }); - } - - function test_RevertWhen_wrongL2GasPerPubdataByteLimit() public { - vm.expectRevert(bytes("qp")); - mailboxFacet.requestL2Transaction({ - _contractL2: tempAddress, - _l2Value: 0, - _calldata: tempBytes, - _l2GasLimit: 0, - _l2GasPerPubdataByteLimit: 0, - _factoryDeps: tempBytesArr, - _refundRecipient: tempAddress - }); - } - - function test_RevertWhen_msgValueDoesntCoverTx() public { - utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); - tempBytesArr = new bytes[](1); - - uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, 1000000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); - uint256 l2Value = 1 ether; - uint256 mintValue = baseCost + l2Value; - - vm.expectRevert(bytes("mv")); - mailboxFacet.requestL2Transaction{value: mintValue - 1}({ - _contractL2: tempAddress, - _l2Value: l2Value, - _calldata: tempBytes, - _l2GasLimit: 1000000, - _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - _factoryDeps: tempBytesArr, - _refundRecipient: tempAddress - }); - } - - function test_RevertWhen_factoryDepsLengthExceeded() public { - tempBytesArr = new bytes[](MAX_NEW_FACTORY_DEPS + 1); - - vm.expectRevert(bytes("uj")); - mailboxFacet.requestL2Transaction({ - _contractL2: tempAddress, - _l2Value: 0, - _calldata: tempBytes, - _l2GasLimit: 0, - _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - _factoryDeps: tempBytesArr, - _refundRecipient: tempAddress - }); - } - - function _requestL2Transaction( - uint256 amount, - uint256 baseCost, - uint256 l2GasLimit - ) internal returns (bytes32 canonicalTxHash, uint256 mintValue) { - bytes[] memory factoryDeps = new bytes[](1); - factoryDeps[0] = "11111111111111111111111111111111"; - - mintValue = baseCost + amount; - - vm.deal(sender, mintValue); - vm.prank(sender); - canonicalTxHash = mailboxFacet.requestL2Transaction{value: mintValue}({ - _contractL2: tempAddress, - _l2Value: amount, - _calldata: tempBytes, - _l2GasLimit: l2GasLimit, - _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - _factoryDeps: factoryDeps, - _refundRecipient: tempAddress - }); - } - - function test_RevertWhen_bridgePaused(uint256 randomValue) public { - utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); - utilsFacet.util_setPriorityTxMaxGasLimit(100000000); - utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); - - uint256 l2GasLimit = 1000000; - uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); - randomValue = bound(randomValue, 0, type(uint256).max - baseCost); - - l1SharedBridge.pause(); - - vm.expectRevert("Pausable: paused"); - _requestL2Transaction(randomValue, baseCost, l2GasLimit); - } - - function test_success_requestL2Transaction(uint256 randomValue) public { - utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); - utilsFacet.util_setPriorityTxMaxGasLimit(100000000); - utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); - - uint256 l2GasLimit = 1000000; - uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); - randomValue = bound(randomValue, 0, type(uint256).max - baseCost); - - bytes32 canonicalTxHash; - uint256 mintValue; - - (canonicalTxHash, mintValue) = _requestL2Transaction(randomValue, baseCost, l2GasLimit); - assertTrue(canonicalTxHash != bytes32(0), "canonicalTxHash should not be 0"); - assertEq(baseTokenBridgeAddress.balance, mintValue); - assertEq(l1SharedBridge.chainBalance(eraChainId, ETH_TOKEN_ADDRESS), mintValue); - } -} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol deleted file mode 100644 index d5815ddc2..000000000 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {MailboxTest} from "./_Mailbox_Shared.t.sol"; -import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; -import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; - - -contract MailboxTransferEthToSharedBridge is MailboxTest { - address baseTokenBridgeAddress; - DummySharedBridge l1SharedBridge; - - function setUp() public virtual { - setupDiamondProxy(); - - l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); - baseTokenBridgeAddress = address(l1SharedBridge); - - utilsFacet.util_setChainId(eraChainId); - utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); - } - - modifier useBaseTokenBridge() { - vm.startPrank(baseTokenBridgeAddress); - _; - vm.stopPrank(); - } - - function test_success_transfer(uint256 randomAmount) public useBaseTokenBridge { - vm.deal(diamondProxy, randomAmount); - - assertEq(address(l1SharedBridge).balance, 0); - assertEq(address(diamondProxy).balance, randomAmount); - mailboxFacet.transferEthToSharedBridge(); - assertEq(address(l1SharedBridge).balance, randomAmount); - assertEq(address(diamondProxy).balance, 0); - } - - function test_RevertWhen_wrongCaller() public { - vm.expectRevert("Hyperchain: Only base token bridge can call this function"); - vm.prank(sender); - mailboxFacet.transferEthToSharedBridge(); - } - - function test_RevertWhen_hyperchainIsNotEra(uint256 randomChainId) public useBaseTokenBridge { - vm.assume(eraChainId != randomChainId); - utilsFacet.util_setChainId(randomChainId); - - vm.expectRevert("Mailbox: transferEthToSharedBridge only available for Era on mailbox"); - mailboxFacet.transferEthToSharedBridge(); - } -} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol index 32a1e9c55..03ab74a8d 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol @@ -5,32 +5,35 @@ import {Test} from "forge-std/Test.sol"; import {Utils} from "foundry-test/unit/concrete/Utils/Utils.sol"; import {UtilsFacet} from "foundry-test/unit/concrete/Utils/UtilsFacet.sol"; -import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; + import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {IMailbox} from "contracts/state-transition/chain-interfaces/IMailbox.sol"; -import {IGetters} from "contracts/state-transition/chain-interfaces/IGetters.sol"; import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; contract MailboxTest is Test { IMailbox internal mailboxFacet; UtilsFacet internal utilsFacet; - IGetters internal gettersFacet; address sender; - uint256 constant eraChainId = 9; + uint256 eraChainId = 9; address internal testnetVerifier = address(new TestnetVerifier()); - address diamondProxy; - function setupDiamondProxy() public { + function getMailboxSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory selectors = new bytes4[](1); + selectors[0] = IMailbox.bridgehubRequestL2Transaction.selector; + return selectors; + } + + function setUp() public virtual { sender = makeAddr("sender"); vm.deal(sender, 100 ether); - Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](3); + Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](2); facetCuts[0] = Diamond.FacetCut({ facet: address(new MailboxFacet(eraChainId)), action: Diamond.Action.Add, isFreezable: true, - selectors: Utils.getMailboxSelectors() + selectors: getMailboxSelectors() }); facetCuts[1] = Diamond.FacetCut({ facet: address(new UtilsFacet()), @@ -38,17 +41,10 @@ contract MailboxTest is Test { isFreezable: true, selectors: Utils.getUtilsFacetSelectors() }); - facetCuts[2] = Diamond.FacetCut({ - facet: address(new GettersFacet()), - action: Diamond.Action.Add, - isFreezable: true, - selectors: Utils.getGettersSelectors() - }); - diamondProxy = Utils.makeDiamondProxy(facetCuts, testnetVerifier); + address diamondProxy = Utils.makeDiamondProxy(facetCuts, testnetVerifier); mailboxFacet = IMailbox(diamondProxy); utilsFacet = UtilsFacet(diamondProxy); - gettersFacet = IGetters(diamondProxy); } // add this to be excluded from coverage report From fb3a5d8fe010a18aa0cc1ee0ee68565a72e1225a Mon Sep 17 00:00:00 2001 From: Artem Makhortov <13339874+artmakh@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:02:53 +0700 Subject: [PATCH 19/42] chore(ci): Additional permissions for CI token (#565) --- .github/workflows/l1-contracts-ci.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/l1-contracts-ci.yaml b/.github/workflows/l1-contracts-ci.yaml index d761b63ed..e876be9f2 100644 --- a/.github/workflows/l1-contracts-ci.yaml +++ b/.github/workflows/l1-contracts-ci.yaml @@ -3,6 +3,11 @@ name: L1 contracts CI on: pull_request: +# We need this permissions for this CI to work with external contributions +permissions: + contents: read + pull-requests: write + jobs: build: runs-on: ubuntu-latest From 1c1b93ba55f2fb0c678307ec8093540f927a8829 Mon Sep 17 00:00:00 2001 From: Tomasz Jakubas <47206288+tommysr@users.noreply.github.com> Date: Wed, 3 Jul 2024 03:59:19 +0200 Subject: [PATCH 20/42] Mailbox unit testing (#559) Failing CI check is for coverage and for external contributors, they are not permissioned enough to run this check. The reason being Github doesn't allow granting anything except read for tokens, when PR is from fork https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token --- .../dev-contracts/test/DummyBridgehub.sol | 18 ++ .../dev-contracts/test/DummyHyperchain.sol | 4 + .../dev-contracts/test/DummySharedBridge.sol | 53 +++- .../foundry/unit/concrete/Utils/Utils.sol | 8 +- .../unit/concrete/Utils/UtilsFacet.sol | 12 + .../facets/Mailbox/BaseMailboxTests.t.sol | 81 +++++ .../BridgehubRequestL2Transaction.t.sol | 22 +- .../facets/Mailbox/FinalizeWithdrawal.t.sol | 63 ++++ .../Mailbox/ProvingL2LogsInclusion.t.sol | 285 ++++++++++++++++++ .../facets/Mailbox/RequestL2Transaction.t.sol | 153 ++++++++++ .../Mailbox/TransferEthToSharedBridge.t.sol | 52 ++++ .../facets/Mailbox/_Mailbox_Shared.t.sol | 28 +- 12 files changed, 758 insertions(+), 21 deletions(-) create mode 100644 l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol diff --git a/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol b/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol new file mode 100644 index 000000000..79f9dc6e6 --- /dev/null +++ b/l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {Bridgehub} from "../../bridgehub/Bridgehub.sol"; + +/// @title DummyBridgehub +/// @notice A test smart contract that allows to set State Transition Manager for a given chain +contract DummyBridgehub is Bridgehub { + // add this to be excluded from coverage report + function test() internal virtual {} + + constructor() Bridgehub() {} + + function setStateTransitionManager(uint256 _chainId, address _stm) external { + stateTransitionManager[_chainId] = _stm; + } +} diff --git a/l1-contracts/contracts/dev-contracts/test/DummyHyperchain.sol b/l1-contracts/contracts/dev-contracts/test/DummyHyperchain.sol index b626142a7..11be65a2b 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummyHyperchain.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummyHyperchain.sol @@ -9,6 +9,10 @@ contract DummyHyperchain is MailboxFacet { s.bridgehub = bridgeHubAddress; } + function getEraChainId() public view returns (uint256) { + return ERA_CHAIN_ID; + } + function setBridgeHubAddress(address bridgeHubAddress) public { s.bridgehub = bridgeHubAddress; } diff --git a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol index 6e61902f0..18124d860 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol @@ -6,8 +6,14 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; import {TWO_BRIDGES_MAGIC_VALUE} from "../../common/Config.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import {UnsafeBytes} from "contracts/common/libraries/UnsafeBytes.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract DummySharedBridge is PausableUpgradeable { + using SafeERC20 for IERC20; -contract DummySharedBridge { event BridgehubDepositBaseTokenInitiated( uint256 indexed chainId, address indexed from, @@ -19,7 +25,7 @@ contract DummySharedBridge { /// @dev Maps token balances for each chain to prevent unauthorized spending across hyperchains. /// This serves as a security measure until hyperbridging is implemented. - mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) internal chainBalance; + mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) public chainBalance; /// @dev Indicates whether the hyperbridging is enabled for a given chain. mapping(uint256 chainId => bool enabled) internal hyperbridgingEnabled; @@ -38,6 +44,8 @@ contract DummySharedBridge { amountReturnInFinalizeWithdrawal = _amount; } + function receiveEth(uint256 _chainId) external payable {} + function depositLegacyErc20Bridge( address, //_msgSender, address, //_l2Receiver, @@ -75,12 +83,51 @@ contract DummySharedBridge { event Debugger(uint256); + function pause() external { + _pause(); + } + + function unpause() external { + _unpause(); + } + + // This function expects abi encoded data + function _parseL2WithdrawalMessage( + bytes memory _l2ToL1message + ) internal view returns (address l1Receiver, address l1Token, uint256 amount) { + (l1Receiver, l1Token, amount) = abi.decode(_l2ToL1message, (address, address, uint256)); + } + + // simple function to just transfer the funds + function finalizeWithdrawal( + uint256 _chainId, + uint256 _l2BatchNumber, + uint256 _l2MessageIndex, + uint16 _l2TxNumberInBatch, + bytes calldata _message, + bytes32[] calldata _merkleProof + ) external { + (address l1Receiver, address l1Token, uint256 amount) = _parseL2WithdrawalMessage(_message); + + if (l1Token == address(1)) { + bool callSuccess; + // Low-level assembly call, to avoid any memory copying (save gas) + assembly { + callSuccess := call(gas(), l1Receiver, amount, 0, 0, 0, 0) + } + require(callSuccess, "ShB: withdraw failed"); + } else { + // Withdraw funds + IERC20(l1Token).safeTransfer(l1Receiver, amount); + } + } + function bridgehubDepositBaseToken( uint256 _chainId, address _prevMsgSender, address _l1Token, uint256 _amount - ) external payable { + ) external payable whenNotPaused { if (_l1Token == address(1)) { require(msg.value == _amount, "L1SharedBridge: msg.value not equal to amount"); } else { diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol index b52d1e122..1260334fd 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol @@ -244,7 +244,7 @@ library Utils { } function getMailboxSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](7); + bytes4[] memory selectors = new bytes4[](8); selectors[0] = MailboxFacet.proveL2MessageInclusion.selector; selectors[1] = MailboxFacet.proveL2LogInclusion.selector; selectors[2] = MailboxFacet.proveL1ToL2TransactionStatus.selector; @@ -252,11 +252,12 @@ library Utils { selectors[4] = MailboxFacet.requestL2Transaction.selector; selectors[5] = MailboxFacet.bridgehubRequestL2Transaction.selector; selectors[6] = MailboxFacet.l2TransactionBaseCost.selector; + selectors[7] = MailboxFacet.transferEthToSharedBridge.selector; return selectors; } function getUtilsFacetSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](38); + bytes4[] memory selectors = new bytes4[](41); selectors[0] = UtilsFacet.util_setChainId.selector; selectors[1] = UtilsFacet.util_getChainId.selector; selectors[2] = UtilsFacet.util_setBridgehub.selector; @@ -295,6 +296,9 @@ library Utils { selectors[35] = UtilsFacet.util_getIsFrozen.selector; selectors[36] = UtilsFacet.util_setTransactionFilterer.selector; selectors[37] = UtilsFacet.util_setBaseTokenGasPriceMultiplierDenominator.selector; + selectors[38] = UtilsFacet.util_setTotalBatchesExecuted.selector; + selectors[39] = UtilsFacet.util_setL2LogsRootHash.selector; + selectors[40] = UtilsFacet.util_setBaseTokenGasPriceMultiplierNominator.selector; return selectors; } diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol index 01864697d..ce9e659a0 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol @@ -162,6 +162,18 @@ contract UtilsFacet is ZkSyncHyperchainBase { return s.isFrozen; } + function util_setTotalBatchesExecuted(uint256 _numberOfBatches) external { + s.totalBatchesExecuted = _numberOfBatches; + } + + function util_setL2LogsRootHash(uint256 _batchNumber, bytes32 _newHash) external { + s.l2LogsRootHashes[_batchNumber] = _newHash; + } + + function util_setBaseTokenGasPriceMultiplierNominator(uint128 _nominator) external { + s.baseTokenGasPriceMultiplierNominator = _nominator; + } + // add this to be excluded from coverage report function test() internal virtual {} } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol new file mode 100644 index 000000000..0a484d366 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; +import {DummyHyperchain} from "contracts/dev-contracts/test/DummyHyperchain.sol"; + +contract MailboxBaseTests is MailboxTest { + function setUp() public virtual { + setupDiamondProxy(); + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + utilsFacet.util_setBaseTokenGasPriceMultiplierNominator(1); + } + + function test_mailboxConstructor() public { + DummyHyperchain h = new DummyHyperchain(address(0), eraChainId); + assertEq(h.getEraChainId(), eraChainId); + } + + function test_RevertWhen_badDenominatorInL2TransactionBaseCost() public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(0); + vm.expectRevert("Mailbox: baseTokenGasPriceDenominator not set"); + mailboxFacet.l2TransactionBaseCost(100, 10000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + } + + function test_successful_getL2TransactionBaseCostPricingModeValidium() public { + uint256 gasPrice = 10000000; + uint256 l2GasLimit = 1000000; + uint256 l2GasPerPubdataByteLimit = REQUIRED_L2_GAS_PRICE_PER_PUBDATA; + + FeeParams memory feeParams = FeeParams({ + pubdataPricingMode: PubdataPricingMode.Validium, + batchOverheadL1Gas: 1000000, + maxPubdataPerBatch: 120000, + maxL2GasPerBatch: 80000000, + priorityTxMaxPubdata: 99000, + minimalL2GasPrice: 250000000 + }); + + utilsFacet.util_setFeeParams(feeParams); + + // this was get from running the function, but more reasonable would be to + // have some invariants that the calculation should keep for min required gas + // price and also gas limit + uint256 l2TransactionBaseCost = 250125000000000; + + assertEq( + mailboxFacet.l2TransactionBaseCost(gasPrice, l2GasLimit, l2GasPerPubdataByteLimit), + l2TransactionBaseCost + ); + } + + function test_successful_getL2TransactionBaseCostPricingModeRollup() public { + uint256 gasPrice = 10000000; + uint256 l2GasLimit = 1000000; + uint256 l2GasPerPubdataByteLimit = REQUIRED_L2_GAS_PRICE_PER_PUBDATA; + + FeeParams memory feeParams = FeeParams({ + pubdataPricingMode: PubdataPricingMode.Rollup, + batchOverheadL1Gas: 1000000, + maxPubdataPerBatch: 120000, + maxL2GasPerBatch: 80000000, + priorityTxMaxPubdata: 99000, + minimalL2GasPrice: 250000000 + }); + + utilsFacet.util_setFeeParams(feeParams); + + // this was get from running the function, but more reasonable would be to + // have some invariants that the calculation should keep for min required gas + // price and also gas limit + uint256 l2TransactionBaseCost = 250125000000000; + + assertEq( + mailboxFacet.l2TransactionBaseCost(gasPrice, l2GasLimit, l2GasPerPubdataByteLimit), + l2TransactionBaseCost + ); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol index d34a6bd7d..73ffff2bf 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol @@ -4,12 +4,16 @@ pragma solidity 0.8.24; import {MailboxTest} from "./_Mailbox_Shared.t.sol"; import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; -import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS} from "contracts/common/Config.sol"; import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; -contract BridgehubRequestL2TransactionTest is MailboxTest { - function test_successWithoutFilterer() public { +contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { + function setUp() public virtual { + setupDiamondProxy(); + } + + function test_success_withoutFilterer() public { address bridgehub = makeAddr("bridgehub"); utilsFacet.util_setBridgehub(bridgehub); @@ -24,7 +28,7 @@ contract BridgehubRequestL2TransactionTest is MailboxTest { assertTrue(canonicalTxHash != bytes32(0), "canonicalTxHash should not be 0"); } - function test_successWithFilterer() public { + function test_success_withFilterer() public { address bridgehub = makeAddr("bridgehub"); TransactionFiltererTrue tf = new TransactionFiltererTrue(); @@ -58,6 +62,16 @@ contract BridgehubRequestL2TransactionTest is MailboxTest { mailboxFacet.bridgehubRequestL2Transaction(req); } + function test_revertWhen_notBridgehub() public { + address bridgehub = makeAddr("bridgehub"); + utilsFacet.util_setBridgehub(bridgehub); + BridgehubL2TransactionRequest memory req = getBridgehubRequestL2TransactionRequest(); + vm.deal(bridgehub, 100 ether); + vm.prank(address(sender)); + vm.expectRevert("Hyperchain: not bridgehub"); + mailboxFacet.bridgehubRequestL2Transaction(req); + } + function getBridgehubRequestL2TransactionRequest() private returns (BridgehubL2TransactionRequest memory req) { bytes[] memory factoryDeps = new bytes[](1); factoryDeps[0] = "11111111111111111111111111111111"; diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol new file mode 100644 index 000000000..14fe3130e --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {DummyBridgehub} from "contracts/dev-contracts/test/DummyBridgehub.sol"; +import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; +import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; + +contract MailboxFinalizeWithdrawal is MailboxTest { + bytes32[] proof; + bytes message; + DummySharedBridge l1SharedBridge; + address baseTokenBridgeAddress; + + function setUp() public virtual { + setupDiamondProxy(); + + l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); + baseTokenBridgeAddress = address(l1SharedBridge); + + proof = new bytes32[](0); + message = "message"; + } + + function test_RevertWhen_notEra() public { + utilsFacet.util_setChainId(eraChainId + 1); + + vm.expectRevert("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + mailboxFacet.finalizeEthWithdrawal({ + _l2BatchNumber: 0, + _l2MessageIndex: 0, + _l2TxNumberInBatch: 0, + _message: message, + _merkleProof: proof + }); + } + + function test_success_withdrawal(uint256 amount) public { + address baseTokenBridge = makeAddr("baseTokenBridge"); + utilsFacet.util_setChainId(eraChainId); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + + address l1Receiver = makeAddr("receiver"); + address l1Token = address(1); + vm.deal(baseTokenBridgeAddress, amount); + + bytes memory message = abi.encode(l1Receiver, l1Token, amount); + + mailboxFacet.finalizeEthWithdrawal({ + _l2BatchNumber: 0, + _l2MessageIndex: 0, + _l2TxNumberInBatch: 0, + _message: message, + _merkleProof: proof + }); + + assertEq(l1Receiver.balance, amount); + assertEq(baseTokenBridgeAddress.balance, 0); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol new file mode 100644 index 000000000..7fa5d8c3c --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {L2Message, L2Log} from "contracts/common/Messaging.sol"; +import "forge-std/Test.sol"; +import {L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L1_GAS_PER_PUBDATA_BYTE, L2_TO_L1_LOG_SERIALIZE_SIZE} from "contracts/common/Config.sol"; +import {L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_BOOTLOADER_ADDRESS} from "contracts/common/L2ContractAddresses.sol"; +import {Merkle} from "contracts/state-transition/libraries/Merkle.sol"; +import {MurkyBase} from "murky/common/MurkyBase.sol"; +import {MerkleTest} from "contracts/dev-contracts/test/MerkleTest.sol"; +import {TxStatus} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; +import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; +import {MerkleTreeNoSort} from "test/foundry/unit/concrete/state-transition/libraries/Merkle/MerkleTreeNoSort.sol"; + +contract MailboxL2LogsProve is MailboxTest { + bytes32[] elements; + MerkleTest merkle; + MerkleTreeNoSort merkleTree; + bytes data; + uint256 batchNumber; + bool isService; + uint8 shardId; + + function setUp() public virtual { + setupDiamondProxy(); + + data = abi.encodePacked("test data"); + merkleTree = new MerkleTreeNoSort(); + merkle = new MerkleTest(); + batchNumber = gettersFacet.getTotalBatchesExecuted(); + isService = true; + shardId = 0; + } + + function _addHashedLogToMerkleTree( + uint8 _shardId, + bool _isService, + uint16 _txNumberInBatch, + address _sender, + bytes32 _key, + bytes32 _value + ) internal returns (uint256 index) { + elements.push(keccak256(abi.encodePacked(_shardId, _isService, _txNumberInBatch, _sender, _key, _value))); + + index = elements.length - 1; + } + + function test_RevertWhen_batchNumberGreaterThanBatchesExecuted() public { + L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); + bytes32[] memory proof = new bytes32[](0); + + vm.expectRevert(bytes("xx")); + mailboxFacet.proveL2MessageInclusion({ + _batchNumber: batchNumber + 1, + _index: 0, + _message: message, + _proof: proof + }); + } + + function test_success_proveL2MessageInclusion() public { + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: 0, + _isService: true, + _txNumberInBatch: 0, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + uint256 secondLogIndex = _addHashedLogToMerkleTree({ + _shardId: 0, + _isService: true, + _txNumberInBatch: 1, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Create L2 message + L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); + + // Get Merkle proof for the first element + bytes32[] memory firstLogProof = merkleTree.getProof(elements, firstLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[firstLogIndex]; + bytes32 calculatedRoot = merkle.calculateRoot(firstLogProof, firstLogIndex, leaf); + + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove L2 message inclusion + bool ret = mailboxFacet.proveL2MessageInclusion(batchNumber, firstLogIndex, message, firstLogProof); + + // Assert that the proof was successful + assertEq(ret, true); + + // Prove L2 message inclusion for wrong leaf + ret = mailboxFacet.proveL2MessageInclusion(batchNumber, secondLogIndex, message, firstLogProof); + + // Assert that the proof has failed + assertEq(ret, false); + } + + function test_success_proveL2LogInclusion() public { + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 0, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + uint256 secondLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 1, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + L2Log memory log = L2Log({ + l2ShardId: shardId, + isService: isService, + txNumberInBatch: 1, + sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + key: bytes32(uint256(uint160(sender))), + value: keccak256(data) + }); + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + // Set root hash for current batch + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Get Merkle proof for the first element + bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[secondLogIndex]; + + bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove l2 log inclusion with correct proof + bool ret = mailboxFacet.proveL2LogInclusion({ + _batchNumber: batchNumber, + _index: secondLogIndex, + _proof: secondLogProof, + _log: log + }); + + // Assert that the proof was successful + assertEq(ret, true); + + // Prove l2 log inclusion with wrong proof + ret = mailboxFacet.proveL2LogInclusion({ + _batchNumber: batchNumber, + _index: firstLogIndex, + _proof: secondLogProof, + _log: log + }); + + // Assert that the proof was successful + assertEq(ret, false); + } + + // this is not possible in case of message, because some default values + // are set during translation from message to log + function test_RevertWhen_proveL2LogInclusionDefaultLog() public { + L2Log memory log = L2Log({ + l2ShardId: 0, + isService: false, + txNumberInBatch: 0, + sender: address(0), + key: bytes32(0), + value: bytes32(0) + }); + + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: 0, + _isService: true, + _txNumberInBatch: 1, + _sender: L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, + _key: bytes32(uint256(uint160(sender))), + _value: keccak256(data) + }); + + // Add first element to the Merkle tree + elements.push(keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))); + uint256 secondLogIndex = 1; + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + // Set root hash for current batch + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Get Merkle proof for the first element + bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[secondLogIndex]; + bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove log inclusion reverts + vm.expectRevert(bytes("tw")); + mailboxFacet.proveL2LogInclusion({ + _batchNumber: batchNumber, + _index: secondLogIndex, + _proof: secondLogProof, + _log: log + }); + } + + function test_success_proveL1ToL2TransactionStatus() public { + bytes32 firstL2TxHash = keccak256("firstL2Transaction"); + bytes32 secondL2TxHash = keccak256("SecondL2Transaction"); + TxStatus txStatus = TxStatus.Success; + + uint256 firstLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 0, + _sender: L2_BOOTLOADER_ADDRESS, + _key: firstL2TxHash, + _value: bytes32(uint256(txStatus)) + }); + + uint256 secondLogIndex = _addHashedLogToMerkleTree({ + _shardId: shardId, + _isService: isService, + _txNumberInBatch: 1, + _sender: L2_BOOTLOADER_ADDRESS, + _key: secondL2TxHash, + _value: bytes32(uint256(txStatus)) + }); + + // Calculate the Merkle root + bytes32 root = merkleTree.getRoot(elements); + // Set root hash for current batch + utilsFacet.util_setL2LogsRootHash(batchNumber, root); + + // Get Merkle proof for the first element + bytes32[] memory secondLogProof = merkleTree.getProof(elements, secondLogIndex); + + { + // Calculate the root using the Merkle proof + bytes32 leaf = elements[secondLogIndex]; + bytes32 calculatedRoot = merkle.calculateRoot(secondLogProof, secondLogIndex, leaf); + // Assert that the calculated root matches the expected root + assertEq(calculatedRoot, root); + } + + // Prove L1 to L2 transaction status + bool ret = mailboxFacet.proveL1ToL2TransactionStatus({ + _l2TxHash: secondL2TxHash, + _l2BatchNumber: batchNumber, + _l2MessageIndex: secondLogIndex, + _l2TxNumberInBatch: 1, + _merkleProof: secondLogProof, + _status: txStatus + }); + + // Assert that the proof was successful + assertEq(ret, true); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol new file mode 100644 index 000000000..2eee1eefb --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS, ETH_TOKEN_ADDRESS} from "contracts/common/Config.sol"; +import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; +import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; +import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; + +contract MailboxRequestL2TransactionTest is MailboxTest { + address tempAddress; + bytes[] tempBytesArr; + bytes tempBytes; + DummySharedBridge l1SharedBridge; + address baseTokenBridgeAddress; + + function setUp() public virtual { + setupDiamondProxy(); + + l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); + baseTokenBridgeAddress = address(l1SharedBridge); + + tempAddress = makeAddr("temp"); + tempBytesArr = new bytes[](0); + tempBytes = ""; + utilsFacet.util_setChainId(eraChainId); + } + + function test_RevertWhen_NotEra(uint256 randomChainId) public { + vm.assume(eraChainId != randomChainId); + + utilsFacet.util_setChainId(randomChainId); + + vm.expectRevert("Mailbox: legacy interface only available for Era"); + mailboxFacet.requestL2Transaction({ + _contractL2: tempAddress, + _l2Value: 0, + _calldata: tempBytes, + _l2GasLimit: 0, + _l2GasPerPubdataByteLimit: 0, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_wrongL2GasPerPubdataByteLimit() public { + vm.expectRevert(bytes("qp")); + mailboxFacet.requestL2Transaction({ + _contractL2: tempAddress, + _l2Value: 0, + _calldata: tempBytes, + _l2GasLimit: 0, + _l2GasPerPubdataByteLimit: 0, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_msgValueDoesntCoverTx() public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + tempBytesArr = new bytes[](1); + + uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, 1000000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + uint256 l2Value = 1 ether; + uint256 mintValue = baseCost + l2Value; + + vm.expectRevert(bytes("mv")); + mailboxFacet.requestL2Transaction{value: mintValue - 1}({ + _contractL2: tempAddress, + _l2Value: l2Value, + _calldata: tempBytes, + _l2GasLimit: 1000000, + _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_factoryDepsLengthExceeded() public { + tempBytesArr = new bytes[](MAX_NEW_FACTORY_DEPS + 1); + + vm.expectRevert(bytes("uj")); + mailboxFacet.requestL2Transaction({ + _contractL2: tempAddress, + _l2Value: 0, + _calldata: tempBytes, + _l2GasLimit: 0, + _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + _factoryDeps: tempBytesArr, + _refundRecipient: tempAddress + }); + } + + function _requestL2Transaction( + uint256 amount, + uint256 baseCost, + uint256 l2GasLimit + ) internal returns (bytes32 canonicalTxHash, uint256 mintValue) { + bytes[] memory factoryDeps = new bytes[](1); + factoryDeps[0] = "11111111111111111111111111111111"; + + mintValue = baseCost + amount; + + vm.deal(sender, mintValue); + vm.prank(sender); + canonicalTxHash = mailboxFacet.requestL2Transaction{value: mintValue}({ + _contractL2: tempAddress, + _l2Value: amount, + _calldata: tempBytes, + _l2GasLimit: l2GasLimit, + _l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + _factoryDeps: factoryDeps, + _refundRecipient: tempAddress + }); + } + + function test_RevertWhen_bridgePaused(uint256 randomValue) public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + utilsFacet.util_setPriorityTxMaxGasLimit(100000000); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + + uint256 l2GasLimit = 1000000; + uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + randomValue = bound(randomValue, 0, type(uint256).max - baseCost); + + l1SharedBridge.pause(); + + vm.expectRevert("Pausable: paused"); + _requestL2Transaction(randomValue, baseCost, l2GasLimit); + } + + function test_success_requestL2Transaction(uint256 randomValue) public { + utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(1); + utilsFacet.util_setPriorityTxMaxGasLimit(100000000); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + + uint256 l2GasLimit = 1000000; + uint256 baseCost = mailboxFacet.l2TransactionBaseCost(10000000, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); + randomValue = bound(randomValue, 0, type(uint256).max - baseCost); + + bytes32 canonicalTxHash; + uint256 mintValue; + + (canonicalTxHash, mintValue) = _requestL2Transaction(randomValue, baseCost, l2GasLimit); + assertTrue(canonicalTxHash != bytes32(0), "canonicalTxHash should not be 0"); + assertEq(baseTokenBridgeAddress.balance, mintValue); + assertEq(l1SharedBridge.chainBalance(eraChainId, ETH_TOKEN_ADDRESS), mintValue); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol new file mode 100644 index 000000000..90e5068b6 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {MailboxTest} from "./_Mailbox_Shared.t.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; + +contract MailboxTransferEthToSharedBridge is MailboxTest { + address baseTokenBridgeAddress; + DummySharedBridge l1SharedBridge; + + function setUp() public virtual { + setupDiamondProxy(); + + l1SharedBridge = new DummySharedBridge(keccak256("dummyDepositHash")); + baseTokenBridgeAddress = address(l1SharedBridge); + + utilsFacet.util_setChainId(eraChainId); + utilsFacet.util_setBaseTokenBridge(baseTokenBridgeAddress); + } + + modifier useBaseTokenBridge() { + vm.startPrank(baseTokenBridgeAddress); + _; + vm.stopPrank(); + } + + function test_success_transfer(uint256 randomAmount) public useBaseTokenBridge { + vm.deal(diamondProxy, randomAmount); + + assertEq(address(l1SharedBridge).balance, 0); + assertEq(address(diamondProxy).balance, randomAmount); + mailboxFacet.transferEthToSharedBridge(); + assertEq(address(l1SharedBridge).balance, randomAmount); + assertEq(address(diamondProxy).balance, 0); + } + + function test_RevertWhen_wrongCaller() public { + vm.expectRevert("Hyperchain: Only base token bridge can call this function"); + vm.prank(sender); + mailboxFacet.transferEthToSharedBridge(); + } + + function test_RevertWhen_hyperchainIsNotEra(uint256 randomChainId) public useBaseTokenBridge { + vm.assume(eraChainId != randomChainId); + utilsFacet.util_setChainId(randomChainId); + + vm.expectRevert("Mailbox: transferEthToSharedBridge only available for Era on mailbox"); + mailboxFacet.transferEthToSharedBridge(); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol index 03ab74a8d..32a1e9c55 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/_Mailbox_Shared.t.sol @@ -5,35 +5,32 @@ import {Test} from "forge-std/Test.sol"; import {Utils} from "foundry-test/unit/concrete/Utils/Utils.sol"; import {UtilsFacet} from "foundry-test/unit/concrete/Utils/UtilsFacet.sol"; - +import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {IMailbox} from "contracts/state-transition/chain-interfaces/IMailbox.sol"; +import {IGetters} from "contracts/state-transition/chain-interfaces/IGetters.sol"; import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; contract MailboxTest is Test { IMailbox internal mailboxFacet; UtilsFacet internal utilsFacet; + IGetters internal gettersFacet; address sender; - uint256 eraChainId = 9; + uint256 constant eraChainId = 9; address internal testnetVerifier = address(new TestnetVerifier()); + address diamondProxy; - function getMailboxSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](1); - selectors[0] = IMailbox.bridgehubRequestL2Transaction.selector; - return selectors; - } - - function setUp() public virtual { + function setupDiamondProxy() public { sender = makeAddr("sender"); vm.deal(sender, 100 ether); - Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](2); + Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](3); facetCuts[0] = Diamond.FacetCut({ facet: address(new MailboxFacet(eraChainId)), action: Diamond.Action.Add, isFreezable: true, - selectors: getMailboxSelectors() + selectors: Utils.getMailboxSelectors() }); facetCuts[1] = Diamond.FacetCut({ facet: address(new UtilsFacet()), @@ -41,10 +38,17 @@ contract MailboxTest is Test { isFreezable: true, selectors: Utils.getUtilsFacetSelectors() }); + facetCuts[2] = Diamond.FacetCut({ + facet: address(new GettersFacet()), + action: Diamond.Action.Add, + isFreezable: true, + selectors: Utils.getGettersSelectors() + }); - address diamondProxy = Utils.makeDiamondProxy(facetCuts, testnetVerifier); + diamondProxy = Utils.makeDiamondProxy(facetCuts, testnetVerifier); mailboxFacet = IMailbox(diamondProxy); utilsFacet = UtilsFacet(diamondProxy); + gettersFacet = IGetters(diamondProxy); } // add this to be excluded from coverage report From c9a8a684b1f46724a55cb8180f7ed6105a861342 Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:20:53 +0100 Subject: [PATCH 21/42] chore: zksync-ethers to stable v5.9.0 (#567) --- gas-bound-caller/package.json | 2 +- l1-contracts/package.json | 2 +- l2-contracts/package.json | 2 +- system-contracts/package.json | 2 +- yarn.lock | 14 +++++++------- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gas-bound-caller/package.json b/gas-bound-caller/package.json index 555c18d61..fc7bd351e 100644 --- a/gas-bound-caller/package.json +++ b/gas-bound-caller/package.json @@ -37,7 +37,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "5.8.0-beta.5" + "zksync-ethers": "^5.9.0" }, "mocha": { "timeout": 240000, diff --git a/l1-contracts/package.json b/l1-contracts/package.json index 948b1cef9..de33649f8 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -50,7 +50,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "5.8.0-beta.5" + "zksync-ethers": "^5.9.0" }, "scripts": { "build": "hardhat compile", diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 8cee30d5a..a9dfc2779 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -28,7 +28,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^5.2.2", - "zksync-ethers": "5.8.0-beta.5" + "zksync-ethers": "^5.9.0" }, "scripts": { "build": "hardhat compile", diff --git a/system-contracts/package.json b/system-contracts/package.json index a4e1c45cd..e42f76559 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -36,7 +36,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "5.8.0-beta.5" + "zksync-ethers": "^5.9.0" }, "mocha": { "timeout": 240000, diff --git a/yarn.lock b/yarn.lock index 903beef88..d876789a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7740,16 +7740,16 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== -zksync-ethers@5.8.0-beta.5: - version "5.8.0-beta.5" - resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.8.0-beta.5.tgz#4f70193a86bd1e41b25b0aa5aa32f6d41d52f7c6" - integrity sha512-saT/3OwLgifqzrBG7OujvUMapzXnshAaLzAZMycUtdV20eLSSVkyLIARVwh1M6hMQIUvX2htV0JN82QRMyM3Ig== - dependencies: - ethers "~5.7.0" - zksync-ethers@^5.0.0: version "5.7.2" resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.7.2.tgz#e965a9926e6f8168963ab565dd6ad0d38c4f7f18" integrity sha512-D+wn4nkGixUOek9ZsVvIZ/MHponQ5xvw74FSbDJDv6SLCI4LZALOAc8lF3b1ml8nOkpeE2pGV0VKmHTSquRNJg== dependencies: ethers "~5.7.0" + +zksync-ethers@^5.9.0: + version "5.9.0" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.9.0.tgz#96dc29e4eaaf0aa70d927886fd6e1e4c545786e3" + integrity sha512-VnRUesrBcPBmiTYTAp+WreIazK2qCIJEHE7j8BiK+cDApHzjAfIXX+x8SXXJpG1npGJANxiJKnPwA5wjGZtCRg== + dependencies: + ethers "~5.7.0" From bc98e4b984c1528a0b78d426d3c29730a2592405 Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Mon, 8 Jul 2024 20:09:11 +0100 Subject: [PATCH 22/42] remove outdated folder (#601) --- .../script/RegisterHyperchain.s.sol | 294 ------------------ l1-contracts-foundry/script/Utils.sol | 160 ---------- 2 files changed, 454 deletions(-) delete mode 100644 l1-contracts-foundry/script/RegisterHyperchain.s.sol delete mode 100644 l1-contracts-foundry/script/Utils.sol diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol deleted file mode 100644 index c0d776813..000000000 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ /dev/null @@ -1,294 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -// solhint-disable no-console - -import {Script, console2 as console} from "forge-std/Script.sol"; -import {Vm} from "forge-std/Vm.sol"; -import {stdToml} from "forge-std/StdToml.sol"; - -import {Utils} from "./Utils.sol"; -import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; -import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; -import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; -import {VerifierParams, IVerifier} from "contracts/state-transition/chain-interfaces/IVerifier.sol"; -import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; -import {InitializeDataNewChain as DiamondInitializeDataNewChain} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; -import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; -import {ZksyncContract, MissingAddress, AddressHasNoCode} from "./ZkSyncScriptErrors.sol"; - -contract RegisterHyperchainScript is Script { - using stdToml for string; - - address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - bytes32 internal constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); - - struct Config { - ContractsConfig contracts; - AddressesConfig addresses; - address deployerAddress; - address ownerAddress; - uint256 hyperchainChainId; - } - - struct ContractsConfig { - uint256 bridgehubCreateNewChainSalt; - PubdataPricingMode diamondInitPubdataPricingMode; - uint256 diamondInitBatchOverheadL1Gas; - uint256 diamondInitMaxPubdataPerBatch; - uint256 diamondInitMaxL2GasPerBatch; - uint256 diamondInitPriorityTxMaxPubdata; - uint256 diamondInitMinimalL2GasPrice; - bytes32 recursionNodeLevelVkHash; - bytes32 recursionLeafLevelVkHash; - bytes32 recursionCircuitsSetVksHash; - uint256 priorityTxMaxGasLimit; - bool validiumMode; - address validatorSenderOperatorCommitEth; - address validatorSenderOperatorBlobsEth; - uint128 baseTokenGasPriceMultiplierNominator; - uint128 baseTokenGasPriceMultiplierDenominator; - } - - // solhint-disable-next-line gas-struct-packing - struct AddressesConfig { - address baseToken; - address bridgehub; - address stateTransitionProxy; - address adminFacet; - address gettersFacet; - address mailboxFacet; - address executorFacet; - address verifier; - address blobVersionedHashRetriever; - address diamondInit; - address validatorTimelock; - address newDiamondProxy; - } - - Config internal config; - - function run() public { - console.log("Deploying Hyperchain"); - - initializeConfig(); - - checkTokenAddress(); - registerTokenOnBridgehub(); - registerHyperchain(); - addValidators(); - configureZkSyncStateTransition(); - } - - function initializeConfig() internal { - // Grab config from output of l1 deployment - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/script-out/output-deploy-l1.toml"); - string memory toml = vm.readFile(path); - - config.deployerAddress = msg.sender; - - // Config file must be parsed key by key, otherwise values returned - // are parsed alfabetically and not by key. - // https://book.getfoundry.sh/cheatcodes/parse-toml - config.ownerAddress = toml.readAddress("$.l1.owner_addr"); - - config.addresses.bridgehub = toml.readAddress("$.l1.bridgehub.bridgehub_proxy_addr"); - config.addresses.stateTransitionProxy = toml.readAddress("$.l1.state_transition.state_transition_proxy_addr"); - config.addresses.adminFacet = toml.readAddress("$.l1.state_transition.admin_facet_addr"); - config.addresses.gettersFacet = toml.readAddress("$.l1.state_transition.getters_facet_addr"); - config.addresses.mailboxFacet = toml.readAddress("$.l1.state_transition.mailbox_facet_addr"); - config.addresses.executorFacet = toml.readAddress("$.l1.state_transition.executor_facet_addr"); - config.addresses.verifier = toml.readAddress("$.l1.state_transition.verifier_addr"); - config.addresses.blobVersionedHashRetriever = toml.readAddress("$.l1.blob_versioned_hash_retriever_addr"); - config.addresses.diamondInit = toml.readAddress("$.l1.state_transition.diamond_init_addr"); - config.addresses.validatorTimelock = toml.readAddress("$.l1.validator_timelock_addr"); - - config.contracts.diamondInitPubdataPricingMode = PubdataPricingMode( - toml.readUint("$.l1.config.diamond_init_pubdata_pricing_mode") - ); - config.contracts.diamondInitBatchOverheadL1Gas = toml.readUint( - "$.l1.config.diamond_init_batch_overhead_l1_gas" - ); - config.contracts.diamondInitMaxPubdataPerBatch = toml.readUint( - "$.l1.config.diamond_init_max_pubdata_per_batch" - ); - config.contracts.diamondInitMaxL2GasPerBatch = toml.readUint("$.l1.config.diamond_init_max_l2_gas_per_batch"); - config.contracts.diamondInitPriorityTxMaxPubdata = toml.readUint( - "$.l1.config.diamond_init_priority_tx_max_pubdata" - ); - config.contracts.diamondInitMinimalL2GasPrice = toml.readUint("$.l1.config.diamond_init_minimal_l2_gas_price"); - config.contracts.recursionNodeLevelVkHash = toml.readBytes32("$.l1.config.recursion_node_level_vk_hash"); - config.contracts.recursionLeafLevelVkHash = toml.readBytes32("$.l1.config.recursion_leaf_level_vk_hash"); - config.contracts.recursionCircuitsSetVksHash = toml.readBytes32("$.l1.config.recursion_circuits_set_vks_hash"); - config.contracts.priorityTxMaxGasLimit = toml.readUint("$.l1.config.priority_tx_max_gas_limit"); - - // Grab config from l1 deployment config - root = vm.projectRoot(); - path = string.concat(root, "/script-config/config-deploy-l1.toml"); - toml = vm.readFile(path); - - config.hyperchainChainId = toml.readUint("$.hyperchain.hyperchain_chain_id"); - config.contracts.bridgehubCreateNewChainSalt = toml.readUint("$.hyperchain.bridgehub_create_new_chain_salt"); - config.addresses.baseToken = toml.readAddress("$.hyperchain.base_token_addr"); - config.contracts.validiumMode = toml.readBool("$.hyperchain.validium_mode"); - config.contracts.validatorSenderOperatorCommitEth = toml.readAddress( - "$.hyperchain.validator_sender_operator_commit_eth" - ); - config.contracts.validatorSenderOperatorBlobsEth = toml.readAddress( - "$.hyperchain.validator_sender_operator_blobs_eth" - ); - config.contracts.baseTokenGasPriceMultiplierNominator = uint128( - toml.readUint("$.hyperchain.base_token_gas_price_multiplier_nominator") - ); - config.contracts.baseTokenGasPriceMultiplierDenominator = uint128( - toml.readUint("$.hyperchain.base_token_gas_price_multiplier_denominator") - ); - } - - function checkTokenAddress() internal { - if (config.addresses.baseToken == address(0)) { - revert MissingAddress(ZksyncContract.BaseToken); - } - - // Check if it's ethereum address - if (config.addresses.baseToken == ADDRESS_ONE) { - return; - } - - if (config.addresses.baseToken.code.length == 0) { - revert AddressHasNoCode(config.addresses.baseToken); - } - - console.log("Using base token address:", config.addresses.baseToken); - } - - function registerTokenOnBridgehub() internal { - IBridgehub bridgehub = IBridgehub(config.addresses.bridgehub); - - if (bridgehub.tokenIsRegistered(config.addresses.baseToken)) { - console.log("Token already registered on Bridgehub"); - } else { - vm.broadcast(); - bridgehub.addToken(config.addresses.baseToken); - console.log("Token registered on Bridgehub"); - } - } - - function registerHyperchain() internal { - Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](4); - facetCuts[0] = Diamond.FacetCut({ - facet: config.addresses.adminFacet, - action: Diamond.Action.Add, - isFreezable: false, - selectors: Utils.getAllSelectors(config.addresses.adminFacet.code) - }); - facetCuts[1] = Diamond.FacetCut({ - facet: config.addresses.gettersFacet, - action: Diamond.Action.Add, - isFreezable: false, - selectors: Utils.getAllSelectors(config.addresses.gettersFacet.code) - }); - facetCuts[2] = Diamond.FacetCut({ - facet: config.addresses.mailboxFacet, - action: Diamond.Action.Add, - isFreezable: true, - selectors: Utils.getAllSelectors(config.addresses.mailboxFacet.code) - }); - facetCuts[3] = Diamond.FacetCut({ - facet: config.addresses.executorFacet, - action: Diamond.Action.Add, - isFreezable: true, - selectors: Utils.getAllSelectors(config.addresses.executorFacet.code) - }); - - VerifierParams memory verifierParams = VerifierParams({ - recursionNodeLevelVkHash: config.contracts.recursionNodeLevelVkHash, - recursionLeafLevelVkHash: config.contracts.recursionLeafLevelVkHash, - recursionCircuitsSetVksHash: config.contracts.recursionCircuitsSetVksHash - }); - - FeeParams memory feeParams = FeeParams({ - pubdataPricingMode: config.contracts.diamondInitPubdataPricingMode, - batchOverheadL1Gas: uint32(config.contracts.diamondInitBatchOverheadL1Gas), - maxPubdataPerBatch: uint32(config.contracts.diamondInitMaxPubdataPerBatch), - maxL2GasPerBatch: uint32(config.contracts.diamondInitMaxL2GasPerBatch), - priorityTxMaxPubdata: uint32(config.contracts.diamondInitPriorityTxMaxPubdata), - minimalL2GasPrice: uint64(config.contracts.diamondInitMinimalL2GasPrice) - }); - - DiamondInitializeDataNewChain memory initializeData = DiamondInitializeDataNewChain({ - verifier: IVerifier(config.addresses.verifier), - verifierParams: verifierParams, - l2BootloaderBytecodeHash: bytes32(Utils.getBatchBootloaderBytecodeHash()), - l2DefaultAccountBytecodeHash: bytes32(Utils.readSystemContractsBytecode("DefaultAccount")), - priorityTxMaxGasLimit: config.contracts.priorityTxMaxGasLimit, - feeParams: feeParams, - blobVersionedHashRetriever: config.addresses.blobVersionedHashRetriever - }); - - Diamond.DiamondCutData memory initData = Diamond.DiamondCutData({ - facetCuts: facetCuts, - initAddress: config.addresses.diamondInit, - initCalldata: abi.encode(initializeData) - }); - - IBridgehub bridgehub = IBridgehub(config.addresses.bridgehub); - - vm.broadcast(); - vm.recordLogs(); - bridgehub.createNewChain({ - _chainId: config.hyperchainChainId, - _stateTransitionManager: config.addresses.stateTransitionProxy, - _baseToken: config.addresses.baseToken, - _salt: config.contracts.bridgehubCreateNewChainSalt, - _admin: msg.sender, - _initData: abi.encode(initData) - }); - console.log("Hyperchain registered"); - - // Get new diamond proxy address from emitted events - Vm.Log[] memory logs = vm.getRecordedLogs(); - address diamondProxyAddress; - uint256 logsLength = logs.length; - for (uint256 i = 0; i < logsLength; ++i) { - if (logs[i].topics[0] == STATE_TRANSITION_NEW_CHAIN_HASH) { - diamondProxyAddress = address(uint160(uint256(logs[i].topics[2]))); - break; - } - } - if (diamondProxyAddress == address(0)) { - revert MissingAddress(ZksyncContract.DiamondProxy); - } - config.addresses.newDiamondProxy = diamondProxyAddress; - } - - function addValidators() internal { - ValidatorTimelock validatorTimelock = ValidatorTimelock(config.addresses.validatorTimelock); - - vm.startBroadcast(); - validatorTimelock.addValidator(config.hyperchainChainId, config.contracts.validatorSenderOperatorCommitEth); - validatorTimelock.addValidator(config.hyperchainChainId, config.contracts.validatorSenderOperatorBlobsEth); - vm.stopBroadcast(); - - console.log("Validators added"); - } - - function configureZkSyncStateTransition() internal { - IZkSyncHyperchain zkSyncStateTransition = IZkSyncHyperchain(config.addresses.newDiamondProxy); - - vm.startBroadcast(); - zkSyncStateTransition.setTokenMultiplier( - config.contracts.baseTokenGasPriceMultiplierNominator, - config.contracts.baseTokenGasPriceMultiplierDenominator - ); - - // TODO: support validium mode when available - // if (config.contractsMode) { - // zkSyncStateTransition.setValidiumMode(PubdataPricingMode.Validium); - // } - - vm.stopBroadcast(); - console.log("ZkSync State Transition configured"); - } -} diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts-foundry/script/Utils.sol deleted file mode 100644 index c694db463..000000000 --- a/l1-contracts-foundry/script/Utils.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import {Vm} from "forge-std/Vm.sol"; -import {ZksyncContract, FailedToDeploy, BytecodeNotSet, FailedToDeployViaCreate2} from "./ZkSyncScriptErrors.sol"; - -library Utils { - // Cheatcodes address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. - address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); - // Create2Factory deterministic bytecode. - // https://github.com/Arachnid/deterministic-deployment-proxy - bytes internal constant CREATE2_FACTORY_BYTECODE = - hex"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; - - Vm internal constant vm = Vm(VM_ADDRESS); - - /** - * @dev Get all selectors from the bytecode. - * - * Selectors are extracted by calling `cast selectors ` from foundry. - * Then, the result is parsed to extract the selectors, removing - * the `getName()` selector if existing. - */ - function getAllSelectors(bytes memory bytecode) internal returns (bytes4[] memory) { - string[] memory input = new string[](3); - input[0] = "cast"; - input[1] = "selectors"; - input[2] = vm.toString(bytecode); - bytes memory result = vm.ffi(input); - string memory stringResult = string(abi.encodePacked(result)); - - // Extract selectors from the result - string[] memory parts = vm.split(stringResult, "\n"); - uint256 partsLength = parts.length; - bytes4[] memory selectors = new bytes4[](partsLength); - for (uint256 i = 0; i < partsLength; ++i) { - bytes memory part = bytes(parts[i]); - bytes memory extractedSelector = new bytes(10); - // Selector length 10 is 0x + 4 bytes - for (uint256 j = 0; j < 10; ++j) { - extractedSelector[j] = part[j]; - } - bytes4 selector = bytes4(vm.parseBytes(string(extractedSelector))); - selectors[i] = selector; - } - - // Remove `getName()` selector if existing - bool hasGetName = false; - uint256 selectorsLength = selectors.length; - for (uint256 i = 0; i < selectorsLength; ++i) { - if (selectors[i] == bytes4(keccak256("getName()"))) { - selectors[i] = selectors[selectorsLength - 1]; - hasGetName = true; - break; - } - } - if (hasGetName) { - bytes4[] memory newSelectors = new bytes4[](selectorsLength - 1); - for (uint256 i = 0; i < selectorsLength - 1; ++i) { - newSelectors[i] = selectors[i]; - } - return newSelectors; - } - - return selectors; - } - - /** - * @dev Extract an address from bytes. - */ - function bytesToAddress(bytes memory bys) internal pure returns (address addr) { - assembly { - addr := mload(add(bys, 20)) - } - } - - /** - * @dev Extract a uint256 from bytes. - */ - function bytesToUint256(bytes memory bys) internal pure returns (uint256 value) { - // Add left padding to 32 bytes if needed - uint256 bytesLength = bys.length; - if (bytesLength < 32) { - bytes memory padded = new bytes(32); - for (uint256 i = 0; i < bytesLength; ++i) { - padded[i + 32 - bytesLength] = bys[i]; - } - bys = padded; - } - - assembly { - value := mload(add(bys, 0x20)) - } - } - - /** - * @dev Returns the bytecode hash of the batch bootloader. - */ - function getBatchBootloaderBytecodeHash() internal view returns (bytes memory) { - return vm.readFileBinary("../system-contracts/bootloader/build/artifacts/proved_batch.yul.zbin"); - } - - /** - * @dev Returns the bytecode of a given system contract. - */ - function readSystemContractsBytecode(string memory filename) internal view returns (bytes memory) { - string memory file = vm.readFile( - // solhint-disable-next-line func-named-parameters - string.concat( - "../system-contracts/artifacts-zk/contracts-preprocessed/", - filename, - ".sol/", - filename, - ".json" - ) - ); - bytes memory bytecode = vm.parseJson(file, "$.bytecode"); - return bytecode; - } - - /** - * @dev Deploy a Create2Factory contract. - */ - function deployCreate2Factory() internal returns (address) { - address child; - bytes memory bytecode = CREATE2_FACTORY_BYTECODE; - vm.startBroadcast(); - assembly { - child := create(0, add(bytecode, 0x20), mload(bytecode)) - } - vm.stopBroadcast(); - if (child == address(0) || child.code.length == 0) { - revert FailedToDeploy(ZksyncContract.Create2Factory); - } - return child; - } - - /** - * @dev Deploys contract using CREATE2. - */ - function deployViaCreate2(bytes memory _bytecode, bytes32 _salt, address _factory) internal returns (address) { - if (_bytecode.length == 0) { - revert BytecodeNotSet(); - } - address contractAddress = vm.computeCreate2Address(_salt, keccak256(_bytecode), _factory); - if (contractAddress.code.length != 0) { - return contractAddress; - } - - vm.broadcast(); - (bool success, bytes memory data) = _factory.call(abi.encodePacked(_salt, _bytecode)); - contractAddress = Utils.bytesToAddress(data); - - if (!success || contractAddress == address(0) || contractAddress.code.length == 0) { - revert FailedToDeployViaCreate2(); - } - - return contractAddress; - } -} From 118f08100477d6fdfb523f69d28070176290caa4 Mon Sep 17 00:00:00 2001 From: Neo <128649481+neotheprogramist@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:14:41 -0400 Subject: [PATCH 23/42] Bridgehub Test Coverage Increase (#494) Co-authored-by: tommysr <47206288+tommysr@users.noreply.github.com> --- .../dev-contracts/test/DummySharedBridge.sol | 36 +- .../Bridgehub/experimental_bridge.t.sol | 693 ++++++++++++++++-- .../L1Erc20Bridge/ClaimFailedDeposit.t.sol | 36 +- .../Bridges/L1Erc20Bridge/Deposit.t.sol | 51 +- .../L1Erc20Bridge/FinalizeWithdrawal.sol | 18 +- .../Bridges/L1Erc20Bridge/Reentrancy.t.sol | 4 +- .../L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol | 9 +- 7 files changed, 763 insertions(+), 84 deletions(-) diff --git a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol index 18124d860..a69f4c69b 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol @@ -5,11 +5,12 @@ pragma solidity 0.8.24; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; -import {TWO_BRIDGES_MAGIC_VALUE} from "../../common/Config.sol"; +import {TWO_BRIDGES_MAGIC_VALUE, ETH_TOKEN_ADDRESS} from "../../common/Config.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import {UnsafeBytes} from "contracts/common/libraries/UnsafeBytes.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IL2Bridge} from "../../bridge/interfaces/IL2Bridge.sol"; contract DummySharedBridge is PausableUpgradeable { using SafeERC20 for IERC20; @@ -155,14 +156,33 @@ contract DummySharedBridge is PausableUpgradeable { } function bridgehubDeposit( - uint256, //_chainId, - address, //_prevMsgSender, - uint256, // l2Value, needed for Weth deposits in the future - bytes calldata //_data + uint256, + address _prevMsgSender, + uint256, + bytes calldata _data ) external payable returns (L2TransactionRequestTwoBridgesInner memory request) { - // Request the finalization of the deposit on the L2 side - bytes memory l2TxCalldata = bytes("0xabcd123"); - bytes32 txDataHash = bytes32("0x1212121212abf"); + (address _l1Token, uint256 _depositAmount, address _l2Receiver) = abi.decode( + _data, + (address, uint256, address) + ); + uint256 amount; + + if (_l1Token == ETH_TOKEN_ADDRESS) { + amount = msg.value; + require(_depositAmount == 0, "ShB wrong withdraw amount"); + } else { + require(msg.value == 0, "ShB m.v > 0 for BH d.it 2"); + amount = _depositAmount; + + uint256 withdrawAmount = _depositFunds(_prevMsgSender, IERC20(_l1Token), _depositAmount); + require(withdrawAmount == _depositAmount, "5T"); // The token has non-standard transfer logic + } + + bytes memory l2TxCalldata = abi.encodeCall( + IL2Bridge.finalizeDeposit, + (_prevMsgSender, _l2Receiver, _l1Token, amount, new bytes(0)) + ); + bytes32 txDataHash = keccak256(abi.encode(_prevMsgSender, _l1Token, amount)); request = L2TransactionRequestTwoBridgesInner({ magicValue: TWO_BRIDGES_MAGIC_VALUE, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol index 9ef3ae0fb..2f15cdc88 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol @@ -11,11 +11,12 @@ import {ChainCreationParams} from "contracts/state-transition/IStateTransitionMa import {L2TransactionRequestDirect, L2TransactionRequestTwoBridgesOuter} from "contracts/bridgehub/IBridgehub.sol"; import {DummyStateTransitionManagerWBH} from "contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol"; import {DummyHyperchain} from "contracts/dev-contracts/test/DummyHyperchain.sol"; -import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; - +import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; +import {L2TransactionRequestTwoBridgesInner} from "contracts/bridgehub/IBridgehub.sol"; import {L2Message, L2Log, TxStatus, BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; -import {ETH_TOKEN_ADDRESS, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS} from "contracts/common/Config.sol"; +import {ETH_TOKEN_ADDRESS, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS, TWO_BRIDGES_MAGIC_VALUE} from "contracts/common/Config.sol"; +import {L1ERC20Bridge} from "contracts/bridge/L1ERC20Bridge.sol"; contract ExperimentalBridgeTest is Test { using stdStorage for StdStorage; @@ -24,24 +25,73 @@ contract ExperimentalBridgeTest is Test { address public bridgeOwner; DummyStateTransitionManagerWBH mockSTM; DummyHyperchain mockChainContract; - DummySharedBridge mockSharedBridge; - DummySharedBridge mockSecondSharedBridge; + L1SharedBridge sharedBridge; + address sharedBridgeAddress; + address secondBridgeAddress; + L1SharedBridge secondBridge; TestnetERC20Token testToken; + TestnetERC20Token testToken6; + TestnetERC20Token testToken8; + TestnetERC20Token testToken18; + + address mockL2Contract; uint256 eraChainId; + event NewChain(uint256 indexed chainId, address stateTransitionManager, address indexed chainGovernance); + + modifier useRandomToken(uint256 randomValue) { + _setRandomToken(randomValue); + + _; + } + + function _setRandomToken(uint256 randomValue) internal { + uint256 tokenIndex = randomValue % 3; + TestnetERC20Token token; + if (tokenIndex == 0) { + testToken = testToken18; + } else if (tokenIndex == 1) { + testToken = testToken6; + } else { + testToken = testToken8; + } + } + function setUp() public { eraChainId = 9; bridgeHub = new Bridgehub(); bridgeOwner = makeAddr("BRIDGE_OWNER"); mockSTM = new DummyStateTransitionManagerWBH(address(bridgeHub)); mockChainContract = new DummyHyperchain(address(bridgeHub), eraChainId); - mockSharedBridge = new DummySharedBridge(keccak256("0xabc")); - mockSecondSharedBridge = new DummySharedBridge(keccak256("0xdef")); - testToken = new TestnetERC20Token("ZKSTT", "ZkSync Test Token", 18); + mockL2Contract = makeAddr("mockL2Contract"); + + // mocks to use in bridges instead of using a dummy one + address mockL1WethAddress = makeAddr("Weth"); + address eraDiamondProxy = makeAddr("eraDiamondProxy"); + + sharedBridge = new L1SharedBridge(mockL1WethAddress, bridgeHub, eraChainId, eraDiamondProxy); + address defaultOwner = sharedBridge.owner(); + vm.prank(defaultOwner); + sharedBridge.transferOwnership(bridgeOwner); + vm.prank(bridgeOwner); + sharedBridge.acceptOwnership(); + + secondBridge = new L1SharedBridge(mockL1WethAddress, bridgeHub, eraChainId, eraDiamondProxy); + defaultOwner = secondBridge.owner(); + vm.prank(defaultOwner); + secondBridge.transferOwnership(bridgeOwner); + vm.prank(bridgeOwner); + secondBridge.acceptOwnership(); + + sharedBridgeAddress = address(sharedBridge); + secondBridgeAddress = address(secondBridge); + testToken18 = new TestnetERC20Token("ZKSTT", "ZkSync Test Token", 18); + testToken6 = new TestnetERC20Token("USDC", "USD Coin", 6); + testToken8 = new TestnetERC20Token("WBTC", "Wrapped Bitcoin", 8); // test if the ownership of the bridgeHub is set correctly or not - address defaultOwner = bridgeHub.owner(); + defaultOwner = bridgeHub.owner(); // Now, the `reentrancyGuardInitializer` should prevent anyone from calling `initialize` since we have called the constructor of the contract vm.expectRevert(bytes("1B")); @@ -72,8 +122,39 @@ contract ExperimentalBridgeTest is Test { assertEq(bridgeHub.owner(), bridgeOwner); } + function test_newPendingAdminReplacesPrevious(address randomDeployer, address otherRandomDeployer) public { + assertEq(address(0), bridgeHub.admin()); + vm.assume(randomDeployer != otherRandomDeployer); + + vm.prank(bridgeHub.owner()); + bridgeHub.setPendingAdmin(randomDeployer); + + vm.prank(bridgeHub.owner()); + bridgeHub.setPendingAdmin(otherRandomDeployer); + + vm.prank(otherRandomDeployer); + bridgeHub.acceptAdmin(); + + assertEq(otherRandomDeployer, bridgeHub.admin()); + } + + function test_onlyPendingAdminCanAccept(address randomDeployer, address otherRandomDeployer) public { + assertEq(address(0), bridgeHub.admin()); + vm.assume(randomDeployer != otherRandomDeployer); + + vm.prank(bridgeHub.owner()); + bridgeHub.setPendingAdmin(randomDeployer); + + vm.expectRevert(bytes("n42")); + vm.prank(otherRandomDeployer); + bridgeHub.acceptAdmin(); + + assertEq(address(0), bridgeHub.admin()); + } + function test_onlyOwnerCanSetDeployer(address randomDeployer) public { assertEq(address(0), bridgeHub.admin()); + vm.prank(bridgeHub.owner()); bridgeHub.setPendingAdmin(randomDeployer); vm.prank(randomDeployer); @@ -223,7 +304,7 @@ contract ExperimentalBridgeTest is Test { } } - function test_addToken(address, address randomAddress) public { + function test_addToken(address, address randomAddress, uint256 randomValue) public useRandomToken(randomValue) { assertTrue(!bridgeHub.tokenIsRegistered(randomAddress), "This random address is not registered as a token"); vm.prank(bridgeOwner); @@ -248,7 +329,11 @@ contract ExperimentalBridgeTest is Test { bridgeHub.addToken(randomAddress); } - function test_addToken_cannotBeCalledByRandomAddress(address randomAddress, address randomCaller) public { + function test_addToken_cannotBeCalledByRandomAddress( + address randomAddress, + address randomCaller, + uint256 randomValue + ) public useRandomToken(randomValue) { if (randomCaller != bridgeOwner) { vm.prank(randomCaller); vm.expectRevert(bytes("Ownable: caller is not the owner")); @@ -320,26 +405,233 @@ contract ExperimentalBridgeTest is Test { uint256 newChainId; address admin; + function test_pause_createNewChain( + uint256 chainId, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { + chainId = bound(chainId, 1, type(uint48).max); + address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); + admin = makeAddr("NEW_CHAIN_ADMIN"); + + vm.prank(bridgeOwner); + bridgeHub.pause(); + vm.prank(bridgeOwner); + bridgeHub.setPendingAdmin(deployerAddress); + vm.prank(deployerAddress); + bridgeHub.acceptAdmin(); + + vm.expectRevert("Pausable: paused"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + + vm.prank(bridgeOwner); + bridgeHub.unpause(); + + vm.expectRevert("Bridgehub: state transition not registered"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: 1, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: uint256(123), + _admin: admin, + _initData: bytes("") + }); + } + + function test_RevertWhen_STMNotRegisteredOnCreate( + uint256 chainId, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { + chainId = bound(chainId, 1, type(uint48).max); + address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); + admin = makeAddr("NEW_CHAIN_ADMIN"); + + vm.prank(bridgeOwner); + bridgeHub.setPendingAdmin(deployerAddress); + vm.prank(deployerAddress); + bridgeHub.acceptAdmin(); + + chainId = bound(chainId, 1, type(uint48).max); + vm.expectRevert("Bridgehub: state transition not registered"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + } + + function test_RevertWhen_wrongChainIdOnCreate( + uint256 chainId, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { + chainId = bound(chainId, 1, type(uint48).max); + address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); + admin = makeAddr("NEW_CHAIN_ADMIN"); + + vm.prank(bridgeOwner); + bridgeHub.setPendingAdmin(deployerAddress); + vm.prank(deployerAddress); + bridgeHub.acceptAdmin(); + + chainId = bound(chainId, type(uint48).max + uint256(1), type(uint256).max); + vm.expectRevert("Bridgehub: chainId too large"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + + chainId = 0; + vm.expectRevert("Bridgehub: chainId cannot be 0"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + } + + function test_RevertWhen_tokenNotRegistered( + uint256 chainId, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { + chainId = bound(chainId, 1, type(uint48).max); + address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); + admin = makeAddr("NEW_CHAIN_ADMIN"); + + vm.prank(bridgeOwner); + bridgeHub.setPendingAdmin(deployerAddress); + vm.prank(deployerAddress); + bridgeHub.acceptAdmin(); + + vm.startPrank(bridgeOwner); + bridgeHub.addStateTransitionManager(address(mockSTM)); + vm.stopPrank(); + + vm.expectRevert("Bridgehub: token not registered"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + } + + function test_RevertWhen_wethBridgeNotSet( + uint256 chainId, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { + chainId = bound(chainId, 1, type(uint48).max); + address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); + admin = makeAddr("NEW_CHAIN_ADMIN"); + + vm.prank(bridgeOwner); + bridgeHub.setPendingAdmin(deployerAddress); + vm.prank(deployerAddress); + bridgeHub.acceptAdmin(); + + vm.startPrank(bridgeOwner); + bridgeHub.addStateTransitionManager(address(mockSTM)); + bridgeHub.addToken(address(testToken)); + vm.stopPrank(); + + vm.expectRevert("Bridgehub: weth bridge not set"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + } + + function test_RevertWhen_chainIdAlreadyRegistered( + uint256 chainId, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { + address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); + admin = makeAddr("NEW_CHAIN_ADMIN"); + vm.prank(bridgeOwner); + bridgeHub.setPendingAdmin(deployerAddress); + vm.prank(deployerAddress); + bridgeHub.acceptAdmin(); + + vm.startPrank(bridgeOwner); + bridgeHub.addStateTransitionManager(address(mockSTM)); + bridgeHub.addToken(address(testToken)); + bridgeHub.setSharedBridge(sharedBridgeAddress); + vm.stopPrank(); + + chainId = bound(chainId, 1, type(uint48).max); + stdstore.target(address(bridgeHub)).sig("stateTransitionManager(uint256)").with_key(chainId).checked_write( + address(mockSTM) + ); + + vm.expectRevert("Bridgehub: chainId already registered"); + vm.prank(deployerAddress); + bridgeHub.createNewChain({ + _chainId: chainId, + _stateTransitionManager: address(mockSTM), + _baseToken: address(testToken), + _salt: salt, + _admin: admin, + _initData: bytes("") + }); + } + function test_createNewChain( address randomCaller, uint256 chainId, bool isFreezable, bytes4[] memory mockSelectors, address mockInitAddress, - bytes memory mockInitCalldata - ) public { + bytes memory mockInitCalldata, + uint256 salt, + uint256 randomValue + ) public useRandomToken(randomValue) { address deployerAddress = makeAddr("DEPLOYER_ADDRESS"); admin = makeAddr("NEW_CHAIN_ADMIN"); - // Diamond.DiamondCutData memory dcData; + chainId = bound(chainId, 1, type(uint48).max); vm.prank(bridgeOwner); bridgeHub.setPendingAdmin(deployerAddress); vm.prank(deployerAddress); bridgeHub.acceptAdmin(); + vm.startPrank(bridgeOwner); bridgeHub.addStateTransitionManager(address(mockSTM)); bridgeHub.addToken(address(testToken)); - bridgeHub.setSharedBridge(address(mockSharedBridge)); + bridgeHub.setSharedBridge(sharedBridgeAddress); vm.stopPrank(); if (randomCaller != deployerAddress && randomCaller != bridgeOwner) { @@ -349,13 +641,12 @@ contract ExperimentalBridgeTest is Test { _chainId: chainId, _stateTransitionManager: address(mockSTM), _baseToken: address(testToken), - _salt: uint256(123), + _salt: salt, _admin: admin, _initData: bytes("") }); } - chainId = bound(chainId, 1, type(uint48).max); vm.prank(mockSTM.owner()); bytes memory _newChainInitData = _createNewChainInitData( isFreezable, @@ -377,13 +668,16 @@ contract ExperimentalBridgeTest is Test { mockSTM.createNewChain.selector, chainId, address(testToken), - address(mockSharedBridge), + sharedBridgeAddress, admin, _newChainInitData ), bytes("") ); + vm.expectEmit(true, true, true, true, address(bridgeHub)); + emit NewChain(chainId, address(mockSTM), admin); + newChainId = bridgeHub.createNewChain({ _chainId: chainId, _stateTransitionManager: address(mockSTM), @@ -586,7 +880,7 @@ contract ExperimentalBridgeTest is Test { vm.clearMockedCalls(); } - function test_requestL2TransactionDirect_ETHCase( + function _prepareETHL2TransactionDirectRequest( uint256 mockChainId, uint256 mockMintValue, address mockL2Contract, @@ -595,14 +889,13 @@ contract ExperimentalBridgeTest is Test { uint256 mockL2GasLimit, uint256 mockL2GasPerPubdataByteLimit, bytes[] memory mockFactoryDeps, - address mockRefundRecipient, - bytes[] memory mockRefundRecipientBH - ) public { + address randomCaller + ) internal returns (L2TransactionRequestDirect memory l2TxnReqDirect) { if (mockFactoryDeps.length > MAX_NEW_FACTORY_DEPS) { mockFactoryDeps = _restrictArraySize(mockFactoryDeps, MAX_NEW_FACTORY_DEPS); } - L2TransactionRequestDirect memory l2TxnReqDirect = _createMockL2TransactionRequestDirect({ + l2TxnReqDirect = _createMockL2TransactionRequestDirect({ mockChainId: mockChainId, mockMintValue: mockMintValue, mockL2Contract: mockL2Contract, @@ -611,24 +904,20 @@ contract ExperimentalBridgeTest is Test { mockL2GasLimit: mockL2GasLimit, mockL2GasPerPubdataByteLimit: mockL2GasPerPubdataByteLimit, mockFactoryDeps: mockFactoryDeps, - mockRefundRecipient: mockRefundRecipient + mockRefundRecipient: address(0) }); l2TxnReqDirect.chainId = _setUpHyperchainForChainId(l2TxnReqDirect.chainId); assertTrue(!(bridgeHub.baseToken(l2TxnReqDirect.chainId) == ETH_TOKEN_ADDRESS)); - _setUpBaseTokenForChainId(l2TxnReqDirect.chainId, true); + _setUpBaseTokenForChainId(l2TxnReqDirect.chainId, true, address(0)); assertTrue(bridgeHub.baseToken(l2TxnReqDirect.chainId) == ETH_TOKEN_ADDRESS); _setUpSharedBridge(); - - address randomCaller = makeAddr("RANDOM_CALLER"); - vm.deal(randomCaller, l2TxnReqDirect.mintValue); + _setUpSharedBridgeL2(mockChainId); assertTrue(bridgeHub.getHyperchain(l2TxnReqDirect.chainId) == address(mockChainContract)); bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); - //BridgehubL2TransactionRequest memory bhL2TxnRequest = - _createBhL2TxnRequest(mockRefundRecipientBH); vm.mockCall( address(mockChainContract), @@ -640,10 +929,71 @@ contract ExperimentalBridgeTest is Test { mockChainContract.setBaseTokenGasMultiplierPrice(uint128(1), uint128(1)); mockChainContract.setBridgeHubAddress(address(bridgeHub)); assertTrue(mockChainContract.getBridgeHubAddress() == address(bridgeHub)); + } - vm.txGasPrice(0.05 ether); + function test_requestL2TransactionDirect_RevertWhen_incorrectETHParams( + uint256 mockChainId, + uint256 mockMintValue, + address mockL2Contract, + uint256 mockL2Value, + uint256 msgValue, + bytes memory mockL2Calldata, + uint256 mockL2GasLimit, + uint256 mockL2GasPerPubdataByteLimit, + bytes[] memory mockFactoryDeps + ) public { + address randomCaller = makeAddr("RANDOM_CALLER"); + vm.assume(msgValue != mockMintValue); + L2TransactionRequestDirect memory l2TxnReqDirect = _prepareETHL2TransactionDirectRequest({ + mockChainId: mockChainId, + mockMintValue: mockMintValue, + mockL2Contract: mockL2Contract, + mockL2Value: mockL2Value, + mockL2Calldata: mockL2Calldata, + mockL2GasLimit: mockL2GasLimit, + mockL2GasPerPubdataByteLimit: mockL2GasPerPubdataByteLimit, + mockFactoryDeps: mockFactoryDeps, + randomCaller: randomCaller + }); + + vm.deal(randomCaller, msgValue); + vm.expectRevert("Bridgehub: msg.value mismatch 1"); vm.prank(randomCaller); + bridgeHub.requestL2TransactionDirect{value: msgValue}(l2TxnReqDirect); + } + + function test_requestL2TransactionDirect_ETHCase( + uint256 mockChainId, + uint256 mockMintValue, + address mockL2Contract, + uint256 mockL2Value, + bytes memory mockL2Calldata, + uint256 mockL2GasLimit, + uint256 mockL2GasPerPubdataByteLimit, + bytes[] memory mockFactoryDeps, + uint256 gasPrice + ) public { + address randomCaller = makeAddr("RANDOM_CALLER"); + mockChainId = bound(mockChainId, 1, type(uint48).max); + + L2TransactionRequestDirect memory l2TxnReqDirect = _prepareETHL2TransactionDirectRequest({ + mockChainId: mockChainId, + mockMintValue: mockMintValue, + mockL2Contract: mockL2Contract, + mockL2Value: mockL2Value, + mockL2Calldata: mockL2Calldata, + mockL2GasLimit: mockL2GasLimit, + mockL2GasPerPubdataByteLimit: mockL2GasPerPubdataByteLimit, + mockFactoryDeps: mockFactoryDeps, + randomCaller: randomCaller + }); + + vm.deal(randomCaller, l2TxnReqDirect.mintValue); + gasPrice = bound(gasPrice, 1_000, 50_000_000); + vm.txGasPrice(gasPrice * 1 gwei); + vm.prank(randomCaller); + bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); bytes32 resultantHash = bridgeHub.requestL2TransactionDirect{value: randomCaller.balance}(l2TxnReqDirect); assertTrue(resultantHash == canonicalHash); @@ -658,8 +1008,12 @@ contract ExperimentalBridgeTest is Test { uint256 mockL2GasLimit, uint256 mockL2GasPerPubdataByteLimit, bytes[] memory mockFactoryDeps, - address mockRefundRecipient - ) public { + uint256 gasPrice, + uint256 randomValue + ) public useRandomToken(randomValue) { + address randomCaller = makeAddr("RANDOM_CALLER"); + mockChainId = bound(mockChainId, 1, type(uint48).max); + if (mockFactoryDeps.length > MAX_NEW_FACTORY_DEPS) { mockFactoryDeps = _restrictArraySize(mockFactoryDeps, MAX_NEW_FACTORY_DEPS); } @@ -673,13 +1027,14 @@ contract ExperimentalBridgeTest is Test { mockL2GasLimit: mockL2GasLimit, mockL2GasPerPubdataByteLimit: mockL2GasPerPubdataByteLimit, mockFactoryDeps: mockFactoryDeps, - mockRefundRecipient: mockRefundRecipient + mockRefundRecipient: address(0) }); l2TxnReqDirect.chainId = _setUpHyperchainForChainId(l2TxnReqDirect.chainId); - _setUpBaseTokenForChainId(l2TxnReqDirect.chainId, false); + _setUpBaseTokenForChainId(l2TxnReqDirect.chainId, false, address(testToken)); _setUpSharedBridge(); + _setUpSharedBridgeL2(mockChainId); assertTrue(bridgeHub.getHyperchain(l2TxnReqDirect.chainId) == address(mockChainContract)); bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); @@ -695,11 +1050,10 @@ contract ExperimentalBridgeTest is Test { mockChainContract.setBridgeHubAddress(address(bridgeHub)); assertTrue(mockChainContract.getBridgeHubAddress() == address(bridgeHub)); - vm.txGasPrice(0.05 ether); + gasPrice = bound(gasPrice, 1_000, 50_000_000); + vm.txGasPrice(gasPrice * 1 gwei); - address randomCaller = makeAddr("RANDOM_CALLER"); vm.deal(randomCaller, 1 ether); - vm.prank(randomCaller); vm.expectRevert("Bridgehub: non-eth bridge with msg.value"); bytes32 resultantHash = bridgeHub.requestL2TransactionDirect{value: randomCaller.balance}(l2TxnReqDirect); @@ -711,23 +1065,86 @@ contract ExperimentalBridgeTest is Test { vm.prank(randomCaller); testToken.transfer(address(this), l2TxnReqDirect.mintValue); assertEq(testToken.balanceOf(address(this)), l2TxnReqDirect.mintValue); - testToken.approve(address(mockSharedBridge), l2TxnReqDirect.mintValue); + testToken.approve(sharedBridgeAddress, l2TxnReqDirect.mintValue); resultantHash = bridgeHub.requestL2TransactionDirect(l2TxnReqDirect); assertEq(canonicalHash, resultantHash); } - function test_requestL2TransactionTwoBridges_ETHCase( + function test_requestTransactionTwoBridgesChecksMagicValue( + uint256 chainId, + uint256 mintValue, + uint256 l2Value, + uint256 l2GasLimit, + uint256 l2GasPerPubdataByteLimit, + address refundRecipient, + uint256 secondBridgeValue, + bytes memory secondBridgeCalldata, + bytes32 magicValue + ) public { + chainId = bound(chainId, 1, type(uint48).max); + + L2TransactionRequestTwoBridgesOuter memory l2TxnReq2BridgeOut = _createMockL2TransactionRequestTwoBridgesOuter({ + chainId: chainId, + mintValue: mintValue, + l2Value: l2Value, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: l2GasPerPubdataByteLimit, + refundRecipient: refundRecipient, + secondBridgeValue: secondBridgeValue, + secondBridgeCalldata: secondBridgeCalldata + }); + + l2TxnReq2BridgeOut.chainId = _setUpHyperchainForChainId(l2TxnReq2BridgeOut.chainId); + + _setUpBaseTokenForChainId(l2TxnReq2BridgeOut.chainId, true, address(0)); + assertTrue(bridgeHub.baseToken(l2TxnReq2BridgeOut.chainId) == ETH_TOKEN_ADDRESS); + + _setUpSharedBridge(); + _setUpSharedBridgeL2(chainId); + + assertTrue(bridgeHub.getHyperchain(l2TxnReq2BridgeOut.chainId) == address(mockChainContract)); + + uint256 callerMsgValue = l2TxnReq2BridgeOut.mintValue + l2TxnReq2BridgeOut.secondBridgeValue; + address randomCaller = makeAddr("RANDOM_CALLER"); + vm.deal(randomCaller, callerMsgValue); + + if (magicValue != TWO_BRIDGES_MAGIC_VALUE) { + L2TransactionRequestTwoBridgesInner memory request = L2TransactionRequestTwoBridgesInner({ + magicValue: magicValue, + l2Contract: makeAddr("L2_CONTRACT"), + l2Calldata: new bytes(0), + factoryDeps: new bytes[](0), + txDataHash: bytes32(0) + }); + + vm.mockCall( + secondBridgeAddress, + abi.encodeWithSelector(IL1SharedBridge.bridgehubDeposit.selector), + abi.encode(request) + ); + + vm.expectRevert("Bridgehub: magic value mismatch"); + vm.prank(randomCaller); + bridgeHub.requestL2TransactionTwoBridges{value: randomCaller.balance}(l2TxnReq2BridgeOut); + } + } + + function test_requestL2TransactionTwoBridgesWrongBridgeAddress( uint256 chainId, uint256 mintValue, + uint256 msgValue, uint256 l2Value, uint256 l2GasLimit, uint256 l2GasPerPubdataByteLimit, address refundRecipient, uint256 secondBridgeValue, + uint160 secondBridgeAddressValue, bytes memory secondBridgeCalldata ) public { + chainId = bound(chainId, 1, type(uint48).max); + L2TransactionRequestTwoBridgesOuter memory l2TxnReq2BridgeOut = _createMockL2TransactionRequestTwoBridgesOuter({ chainId: chainId, mintValue: mintValue, @@ -741,10 +1158,12 @@ contract ExperimentalBridgeTest is Test { l2TxnReq2BridgeOut.chainId = _setUpHyperchainForChainId(l2TxnReq2BridgeOut.chainId); - _setUpBaseTokenForChainId(l2TxnReq2BridgeOut.chainId, true); + _setUpBaseTokenForChainId(l2TxnReq2BridgeOut.chainId, true, address(0)); assertTrue(bridgeHub.baseToken(l2TxnReq2BridgeOut.chainId) == ETH_TOKEN_ADDRESS); _setUpSharedBridge(); + _setUpSharedBridgeL2(chainId); + assertTrue(bridgeHub.getHyperchain(l2TxnReq2BridgeOut.chainId) == address(mockChainContract)); uint256 callerMsgValue = l2TxnReq2BridgeOut.mintValue + l2TxnReq2BridgeOut.secondBridgeValue; @@ -761,11 +1180,170 @@ contract ExperimentalBridgeTest is Test { abi.encode(canonicalHash) ); + L2TransactionRequestTwoBridgesInner memory outputRequest = L2TransactionRequestTwoBridgesInner({ + magicValue: TWO_BRIDGES_MAGIC_VALUE, + l2Contract: address(0), + l2Calldata: abi.encode(""), + factoryDeps: new bytes[](0), + txDataHash: bytes32("") + }); + secondBridgeAddressValue = uint160(bound(uint256(secondBridgeAddressValue), 0, uint256(type(uint16).max))); + address secondBridgeAddress = address(secondBridgeAddressValue); + + vm.mockCall( + address(secondBridgeAddressValue), + l2TxnReq2BridgeOut.secondBridgeValue, + abi.encodeWithSelector( + IL1SharedBridge.bridgehubDeposit.selector, + l2TxnReq2BridgeOut.chainId, + randomCaller, + l2TxnReq2BridgeOut.l2Value, + l2TxnReq2BridgeOut.secondBridgeCalldata + ), + abi.encode(outputRequest) + ); + + l2TxnReq2BridgeOut.secondBridgeAddress = address(secondBridgeAddressValue); + vm.expectRevert("Bridgehub: second bridge address too low"); vm.prank(randomCaller); - //bytes32 resultantHash = bridgeHub.requestL2TransactionTwoBridges{value: randomCaller.balance}(l2TxnReq2BridgeOut); + } + + function test_requestL2TransactionTwoBridges_ERC20ToNonBase( + uint256 chainId, + uint256 mintValue, + uint256 l2Value, + uint256 l2GasLimit, + uint256 l2GasPerPubdataByteLimit, + address l2Receiver, + uint256 randomValue + ) public useRandomToken(randomValue) { + // create another token, to avoid base token + TestnetERC20Token erc20Token = new TestnetERC20Token("ZKESTT", "ZkSync ERC Test Token", 18); + address erc20TokenAddress = address(erc20Token); + l2Value = bound(l2Value, 1, type(uint256).max); + bytes memory secondBridgeCalldata = abi.encode(erc20TokenAddress, l2Value, l2Receiver); + + chainId = _setUpHyperchainForChainId(chainId); + + L2TransactionRequestTwoBridgesOuter memory l2TxnReq2BridgeOut = _createMockL2TransactionRequestTwoBridgesOuter({ + chainId: chainId, + mintValue: mintValue, + l2Value: 0, // not used + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: l2GasPerPubdataByteLimit, + refundRecipient: address(0), + secondBridgeValue: 0, // not used cause we are using ERC20 + secondBridgeCalldata: secondBridgeCalldata + }); + + address randomCaller = makeAddr("RANDOM_CALLER"); + bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); + + _setUpBaseTokenForChainId(l2TxnReq2BridgeOut.chainId, false, address(testToken)); + assertTrue(bridgeHub.baseToken(l2TxnReq2BridgeOut.chainId) == address(testToken)); + _setUpSharedBridge(); + + _setUpSharedBridgeL2(chainId); + assertTrue(bridgeHub.getHyperchain(l2TxnReq2BridgeOut.chainId) == address(mockChainContract)); + mockChainContract.setBridgeHubAddress(address(bridgeHub)); + + vm.mockCall( + address(mockChainContract), + abi.encodeWithSelector(mockChainContract.bridgehubRequestL2Transaction.selector), + abi.encode(canonicalHash) + ); + + testToken.mint(randomCaller, l2TxnReq2BridgeOut.mintValue); + erc20Token.mint(randomCaller, l2Value); + + assertEq(testToken.balanceOf(randomCaller), l2TxnReq2BridgeOut.mintValue); + assertEq(erc20Token.balanceOf(randomCaller), l2Value); + + vm.startPrank(randomCaller); + testToken.approve(sharedBridgeAddress, l2TxnReq2BridgeOut.mintValue); + erc20Token.approve(secondBridgeAddress, l2Value); + vm.stopPrank(); + vm.prank(randomCaller); + bytes32 resultHash = bridgeHub.requestL2TransactionTwoBridges(l2TxnReq2BridgeOut); + assertEq(resultHash, canonicalHash); + + assert(erc20Token.balanceOf(randomCaller) == 0); + assert(testToken.balanceOf(randomCaller) == 0); + assert(erc20Token.balanceOf(secondBridgeAddress) == l2Value); + assert(testToken.balanceOf(sharedBridgeAddress) == l2TxnReq2BridgeOut.mintValue); + + l2TxnReq2BridgeOut.secondBridgeValue = 1; + testToken.mint(randomCaller, l2TxnReq2BridgeOut.mintValue); + vm.startPrank(randomCaller); + testToken.approve(sharedBridgeAddress, l2TxnReq2BridgeOut.mintValue); + vm.expectRevert("Bridgehub: msg.value mismatch 3"); + bridgeHub.requestL2TransactionTwoBridges(l2TxnReq2BridgeOut); + vm.stopPrank(); + } + + function test_requestL2TransactionTwoBridges_ETHToNonBase( + uint256 chainId, + uint256 mintValue, + uint256 msgValue, + uint256 l2Value, + uint256 l2GasLimit, + uint256 l2GasPerPubdataByteLimit, + address refundRecipient, + uint256 secondBridgeValue, + address l2Receiver, + uint256 randomValue + ) public useRandomToken(randomValue) { + secondBridgeValue = bound(secondBridgeValue, 1, type(uint256).max); + bytes memory secondBridgeCalldata = abi.encode(ETH_TOKEN_ADDRESS, 0, l2Receiver); + + chainId = _setUpHyperchainForChainId(chainId); + + L2TransactionRequestTwoBridgesOuter memory l2TxnReq2BridgeOut = _createMockL2TransactionRequestTwoBridgesOuter({ + chainId: chainId, + mintValue: mintValue, + l2Value: l2Value, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: l2GasPerPubdataByteLimit, + refundRecipient: refundRecipient, + secondBridgeValue: secondBridgeValue, + secondBridgeCalldata: secondBridgeCalldata + }); + + _setUpBaseTokenForChainId(l2TxnReq2BridgeOut.chainId, false, address(testToken)); + assertTrue(bridgeHub.baseToken(l2TxnReq2BridgeOut.chainId) == address(testToken)); + + _setUpSharedBridge(); + _setUpSharedBridgeL2(chainId); + assertTrue(bridgeHub.getHyperchain(l2TxnReq2BridgeOut.chainId) == address(mockChainContract)); + + address randomCaller = makeAddr("RANDOM_CALLER"); + + mockChainContract.setBridgeHubAddress(address(bridgeHub)); - assertTrue(true); + bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); + + vm.mockCall( + address(mockChainContract), + abi.encodeWithSelector(mockChainContract.bridgehubRequestL2Transaction.selector), + abi.encode(canonicalHash) + ); + + if (msgValue != secondBridgeValue) { + vm.deal(randomCaller, msgValue); + vm.expectRevert("Bridgehub: msg.value mismatch 3"); + vm.prank(randomCaller); + bridgeHub.requestL2TransactionTwoBridges{value: msgValue}(l2TxnReq2BridgeOut); + } + + testToken.mint(randomCaller, l2TxnReq2BridgeOut.mintValue); + assertEq(testToken.balanceOf(randomCaller), l2TxnReq2BridgeOut.mintValue); + vm.prank(randomCaller); + testToken.approve(sharedBridgeAddress, l2TxnReq2BridgeOut.mintValue); + + vm.deal(randomCaller, l2TxnReq2BridgeOut.secondBridgeValue); + vm.prank(randomCaller); + bridgeHub.requestL2TransactionTwoBridges{value: randomCaller.balance}(l2TxnReq2BridgeOut); } ///////////////////////////////////////////////////////// @@ -785,8 +1363,9 @@ contract ExperimentalBridgeTest is Test { L2TransactionRequestTwoBridgesOuter memory l2Req; // Don't let the mintValue + secondBridgeValue go beyond type(uint256).max since that calculation is required to be done by our test: test_requestL2TransactionTwoBridges_ETHCase - mintValue = bound(mintValue, 1, (type(uint256).max) / 2); - secondBridgeValue = bound(secondBridgeValue, 1, (type(uint256).max) / 2); + + mintValue = bound(mintValue, 0, (type(uint256).max) / 2); + secondBridgeValue = bound(secondBridgeValue, 0, (type(uint256).max) / 2); l2Req.chainId = chainId; l2Req.mintValue = mintValue; @@ -794,7 +1373,7 @@ contract ExperimentalBridgeTest is Test { l2Req.l2GasLimit = l2GasLimit; l2Req.l2GasPerPubdataByteLimit = l2GasPerPubdataByteLimit; l2Req.refundRecipient = refundRecipient; - l2Req.secondBridgeAddress = address(mockSecondSharedBridge); + l2Req.secondBridgeAddress = secondBridgeAddress; l2Req.secondBridgeValue = secondBridgeValue; l2Req.secondBridgeCalldata = secondBridgeCalldata; @@ -877,7 +1456,7 @@ contract ExperimentalBridgeTest is Test { } function _setUpHyperchainForChainId(uint256 mockChainId) internal returns (uint256 mockChainIdInRange) { - mockChainId = bound(mockChainId, 2, type(uint48).max); + mockChainId = bound(mockChainId, 1, type(uint48).max); mockChainIdInRange = mockChainId; vm.prank(bridgeOwner); bridgeHub.addStateTransitionManager(address(mockSTM)); @@ -895,15 +1474,29 @@ contract ExperimentalBridgeTest is Test { mockSTM.setHyperchain(mockChainId, address(mockChainContract)); } - function _setUpBaseTokenForChainId(uint256 mockChainId, bool tokenIsETH) internal { - address baseToken = tokenIsETH ? ETH_TOKEN_ADDRESS : address(testToken); + function _setUpBaseTokenForChainId(uint256 mockChainId, bool tokenIsETH, address token) internal { + address baseToken = tokenIsETH ? ETH_TOKEN_ADDRESS : token; stdstore.target(address(bridgeHub)).sig("baseToken(uint256)").with_key(mockChainId).checked_write(baseToken); } function _setUpSharedBridge() internal { vm.prank(bridgeOwner); - bridgeHub.setSharedBridge(address(mockSharedBridge)); + bridgeHub.setSharedBridge(sharedBridgeAddress); + } + + function _setUpSharedBridgeL2(uint256 _chainId) internal { + _chainId = bound(_chainId, 1, type(uint48).max); + + vm.prank(bridgeOwner); + sharedBridge.initializeChainGovernance(_chainId, mockL2Contract); + + assertEq(sharedBridge.l2BridgeAddress(_chainId), mockL2Contract); + + vm.prank(bridgeOwner); + secondBridge.initializeChainGovernance(_chainId, mockL2Contract); + + assertEq(secondBridge.l2BridgeAddress(_chainId), mockL2Contract); } function _createMockL2TransactionRequestDirect( diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol index 89a20d90d..0ab45bdbc 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; import {StdStorage, stdStorage} from "forge-std/Test.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; contract ClaimFailedDepositTest is L1Erc20BridgeTest { using stdStorage for StdStorage; @@ -17,7 +18,7 @@ contract ClaimFailedDepositTest is L1Erc20BridgeTest { bridge.claimFailedDeposit({ _depositSender: randomSigner, _l1Token: address(token), - _l2TxHash: dummyL2DepositTxHash, + _l2TxHash: bytes32(""), _l2BatchNumber: 0, _l2MessageIndex: 0, _l2TxNumberInBatch: 0, @@ -26,37 +27,56 @@ contract ClaimFailedDepositTest is L1Erc20BridgeTest { } function test_claimFailedDepositSuccessfully() public { - uint256 depositedAmountBefore = bridge.depositAmount(alice, address(token), dummyL2DepositTxHash); + uint256 amount = 16; + bytes32 l2DepositTxHash = keccak256("l2tx"); + bytes32[] memory merkleProof; + + uint256 depositedAmountBefore = bridge.depositAmount(alice, address(token), l2DepositTxHash); assertEq(depositedAmountBefore, 0); - uint256 amount = 16; stdstore .target(address(bridge)) .sig("depositAmount(address,address,bytes32)") .with_key(alice) .with_key(address(token)) - .with_key(dummyL2DepositTxHash) + .with_key(l2DepositTxHash) .checked_write(amount); - uint256 depositedAmountAfterDeposit = bridge.depositAmount(alice, address(token), dummyL2DepositTxHash); + uint256 depositedAmountAfterDeposit = bridge.depositAmount(alice, address(token), l2DepositTxHash); assertEq(depositedAmountAfterDeposit, amount); + vm.mockCall( + sharedBridgeAddress, + abi.encodeWithSelector( + IL1SharedBridge.claimFailedDepositLegacyErc20Bridge.selector, + alice, + address(token), + amount, + l2DepositTxHash, + 0, + 0, + 0, + merkleProof + ), + abi.encode("") + ); + vm.prank(alice); // solhint-disable-next-line func-named-parameters vm.expectEmit(true, true, true, true, address(bridge)); emit ClaimedFailedDeposit(alice, address(token), amount); - bytes32[] memory merkleProof; + bridge.claimFailedDeposit({ _depositSender: alice, _l1Token: address(token), - _l2TxHash: dummyL2DepositTxHash, + _l2TxHash: l2DepositTxHash, _l2BatchNumber: 0, _l2MessageIndex: 0, _l2TxNumberInBatch: 0, _merkleProof: merkleProof }); - uint256 depositedAmountAfterWithdrawal = bridge.depositAmount(alice, address(token), dummyL2DepositTxHash); + uint256 depositedAmountAfterWithdrawal = bridge.depositAmount(alice, address(token), l2DepositTxHash); assertEq(depositedAmountAfterWithdrawal, 0); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol index 67f16aab8..df43e652f 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; contract DepositTest is L1Erc20BridgeTest { event DepositInitiated( @@ -112,13 +113,30 @@ contract DepositTest is L1Erc20BridgeTest { function test_depositSuccessfully() public { uint256 amount = 8; + bytes32 l2TxHash = keccak256("txHash"); + + vm.mockCall( + sharedBridgeAddress, + abi.encodeWithSelector( + IL1SharedBridge.depositLegacyErc20Bridge.selector, + alice, + randomSigner, + address(token), + amount, + 0, + 0, + address(0) + ), + abi.encode(l2TxHash) + ); + vm.prank(alice); token.approve(address(bridge), amount); vm.prank(alice); // solhint-disable-next-line func-named-parameters vm.expectEmit(true, true, true, true, address(bridge)); // solhint-disable-next-line func-named-parameters - emit DepositInitiated(dummyL2DepositTxHash, alice, randomSigner, address(token), amount); + emit DepositInitiated(l2TxHash, alice, randomSigner, address(token), amount); bytes32 txHash = bridge.deposit({ _l2Receiver: randomSigner, _l1Token: address(token), @@ -127,24 +145,41 @@ contract DepositTest is L1Erc20BridgeTest { _l2TxGasPerPubdataByte: 0, _refundRecipient: address(0) }); - assertEq(txHash, dummyL2DepositTxHash); + assertEq(txHash, l2TxHash); - uint256 depositedAmount = bridge.depositAmount(alice, address(token), dummyL2DepositTxHash); + uint256 depositedAmount = bridge.depositAmount(alice, address(token), l2TxHash); assertEq(amount, depositedAmount); } function test_legacyDepositSuccessfully() public { - uint256 depositedAmountBefore = bridge.depositAmount(alice, address(token), dummyL2DepositTxHash); + uint256 amount = 8; + bytes32 l2TxHash = keccak256("txHash"); + + uint256 depositedAmountBefore = bridge.depositAmount(alice, address(token), l2TxHash); assertEq(depositedAmountBefore, 0); - uint256 amount = 8; + vm.mockCall( + sharedBridgeAddress, + abi.encodeWithSelector( + IL1SharedBridge.depositLegacyErc20Bridge.selector, + alice, + randomSigner, + address(token), + amount, + 0, + 0, + address(0) + ), + abi.encode(l2TxHash) + ); + vm.prank(alice); token.approve(address(bridge), amount); vm.prank(alice); // solhint-disable-next-line func-named-parameters vm.expectEmit(true, true, true, true, address(bridge)); // solhint-disable-next-line func-named-parameters - emit DepositInitiated(dummyL2DepositTxHash, alice, randomSigner, address(token), amount); + emit DepositInitiated(l2TxHash, alice, randomSigner, address(token), amount); bytes32 txHash = bridge.deposit({ _l2Receiver: randomSigner, _l1Token: address(token), @@ -152,9 +187,9 @@ contract DepositTest is L1Erc20BridgeTest { _l2TxGasLimit: 0, _l2TxGasPerPubdataByte: 0 }); - assertEq(txHash, dummyL2DepositTxHash); + assertEq(txHash, l2TxHash); - uint256 depositedAmount = bridge.depositAmount(alice, address(token), dummyL2DepositTxHash); + uint256 depositedAmount = bridge.depositAmount(alice, address(token), l2TxHash); assertEq(amount, depositedAmount); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol index 830c77953..5f39fe240 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; +import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; import {StdStorage, stdStorage} from "forge-std/Test.sol"; contract FinalizeWithdrawalTest is L1Erc20BridgeTest { @@ -36,17 +37,30 @@ contract FinalizeWithdrawalTest is L1Erc20BridgeTest { function test_finalizeWithdrawalSuccessfully() public { uint256 l2BatchNumber = 3; uint256 l2MessageIndex = 4; + uint256 txNumberInBatch = 0; + bytes32[] memory merkleProof; uint256 amount = 999; assertFalse(bridge.isWithdrawalFinalized(l2BatchNumber, l2MessageIndex)); - dummySharedBridge.setDataToBeReturnedInFinalizeWithdrawal(alice, address(token), amount); + vm.mockCall( + sharedBridgeAddress, + abi.encodeWithSelector( + IL1SharedBridge.finalizeWithdrawalLegacyErc20Bridge.selector, + l2BatchNumber, + l2MessageIndex, + txNumberInBatch, + "", + merkleProof + ), + abi.encode(alice, address(token), amount) + ); vm.prank(alice); // solhint-disable-next-line func-named-parameters vm.expectEmit(true, true, true, true, address(bridge)); emit WithdrawalFinalized(alice, address(token), amount); - bytes32[] memory merkleProof; + bridge.finalizeWithdrawal({ _l2BatchNumber: l2BatchNumber, _l2MessageIndex: l2MessageIndex, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol index 7a6183f93..cf182cac8 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol @@ -49,7 +49,7 @@ contract ReentrancyTest is L1Erc20BridgeTest { .sig("depositAmount(address,address,bytes32)") .with_key(alice) .with_key(address(token)) - .with_key(dummyL2DepositTxHash) + .with_key(bytes32("")) .checked_write(amount); vm.prank(alice); @@ -58,7 +58,7 @@ contract ReentrancyTest is L1Erc20BridgeTest { bridgeReenterItself.claimFailedDeposit({ _depositSender: alice, _l1Token: address(token), - _l2TxHash: dummyL2DepositTxHash, + _l2TxHash: bytes32(""), _l2BatchNumber: 0, _l2MessageIndex: 0, _l2TxNumberInBatch: 0, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol index 6add8395e..753e9ab79 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol @@ -8,13 +8,11 @@ import {L1ERC20Bridge} from "contracts/bridge/L1ERC20Bridge.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; import {TestnetERC20Token} from "contracts/dev-contracts/TestnetERC20Token.sol"; import {FeeOnTransferToken} from "contracts/dev-contracts/FeeOnTransferToken.sol"; -import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; import {ReenterL1ERC20Bridge} from "contracts/dev-contracts/test/ReenterL1ERC20Bridge.sol"; import {Utils} from "../../Utils/Utils.sol"; contract L1Erc20BridgeTest is Test { L1ERC20Bridge internal bridge; - DummySharedBridge internal dummySharedBridge; ReenterL1ERC20Bridge internal reenterL1ERC20Bridge; L1ERC20Bridge internal bridgeReenterItself; @@ -23,15 +21,14 @@ contract L1Erc20BridgeTest is Test { TestnetERC20Token internal feeOnTransferToken; address internal randomSigner; address internal alice; - bytes32 internal dummyL2DepositTxHash; + address sharedBridgeAddress; constructor() { randomSigner = makeAddr("randomSigner"); - dummyL2DepositTxHash = Utils.randomBytes32("dummyL2DepositTxHash"); alice = makeAddr("alice"); - dummySharedBridge = new DummySharedBridge(dummyL2DepositTxHash); - bridge = new L1ERC20Bridge(IL1SharedBridge(address(dummySharedBridge))); + sharedBridgeAddress = makeAddr("shared bridge"); + bridge = new L1ERC20Bridge(IL1SharedBridge(sharedBridgeAddress)); reenterL1ERC20Bridge = new ReenterL1ERC20Bridge(); bridgeReenterItself = new L1ERC20Bridge(IL1SharedBridge(address(reenterL1ERC20Bridge))); From 7f4f460bbaa26f7d3f2df762120a4dba71c5c908 Mon Sep 17 00:00:00 2001 From: Danil Date: Fri, 16 Aug 2024 16:10:10 +0200 Subject: [PATCH 24/42] feat(foundry): use foundry zksync (dev) (#551) Signed-off-by: Danil Co-authored-by: vladbochok Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Co-authored-by: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Co-authored-by: perekopskiy --- .github/workflows/l1-contracts-ci.yaml | 2 +- .../workflows/l1-contracts-foundry-ci.yaml | 117 ------------------ .gitmodules | 18 +-- .markdownlintignore | 6 +- .prettierignore | 4 + .solhintignore | 4 + l1-contracts/deploy-scripts/AcceptAdmin.s.sol | 1 + .../deploy-scripts/DeployL2Contracts.sol | 24 ++-- .../deploy-scripts/DeployPaymaster.s.sol | 4 +- l1-contracts/deploy-scripts/Utils.sol | 4 +- l1-contracts/foundry.toml | 3 + l1-contracts/lib/forge-std | 2 +- l1-contracts/lib/murky | 2 +- l1-contracts/lib/openzeppelin-contracts | 2 +- .../lib/openzeppelin-contracts-upgradeable | 2 +- l2-contracts/.gitignore | 15 +++ l2-contracts/foundry.toml | 12 ++ l2-contracts/lib/forge-std | 1 + l2-contracts/lib/openzeppelin-contracts | 1 + .../lib/openzeppelin-contracts-upgradeable | 1 + lib/forge-std | 1 + lib/murky | 1 + lib/openzeppelin-contracts | 1 + lib/openzeppelin-contracts-upgradeable | 1 + system-contracts/.gitignore | 15 +++ system-contracts/foundry.toml | 11 ++ system-contracts/lib/forge-std | 1 + system-contracts/lib/openzeppelin-contracts | 1 + .../lib/openzeppelin-contracts-upgradeable | 1 + .../scripts/preprocess-bootloader.ts | 23 +++- yarn.lock | 16 +-- 31 files changed, 133 insertions(+), 164 deletions(-) delete mode 100644 .github/workflows/l1-contracts-foundry-ci.yaml mode change 160000 => 120000 l1-contracts/lib/forge-std mode change 160000 => 120000 l1-contracts/lib/murky mode change 160000 => 120000 l1-contracts/lib/openzeppelin-contracts mode change 160000 => 120000 l1-contracts/lib/openzeppelin-contracts-upgradeable create mode 100644 l2-contracts/.gitignore create mode 100644 l2-contracts/foundry.toml create mode 120000 l2-contracts/lib/forge-std create mode 120000 l2-contracts/lib/openzeppelin-contracts create mode 120000 l2-contracts/lib/openzeppelin-contracts-upgradeable create mode 160000 lib/forge-std create mode 160000 lib/murky create mode 160000 lib/openzeppelin-contracts create mode 160000 lib/openzeppelin-contracts-upgradeable create mode 100644 system-contracts/.gitignore create mode 100644 system-contracts/foundry.toml create mode 120000 system-contracts/lib/forge-std create mode 120000 system-contracts/lib/openzeppelin-contracts create mode 120000 system-contracts/lib/openzeppelin-contracts-upgradeable diff --git a/.github/workflows/l1-contracts-ci.yaml b/.github/workflows/l1-contracts-ci.yaml index e876be9f2..fbf3cc770 100644 --- a/.github/workflows/l1-contracts-ci.yaml +++ b/.github/workflows/l1-contracts-ci.yaml @@ -199,7 +199,7 @@ jobs: - name: Filter directories run: | sudo apt update && sudo apt install -y lcov - lcov --remove lcov.info 'test/*' 'contracts/dev-contracts/*' 'lib/*' --output-file lcov.info --rc lcov_branch_coverage=1 + lcov --remove lcov.info 'test/*' 'contracts/dev-contracts/*' '../lib/forge-std/*' '../lib/murky/*' 'lib/*' '../lib/*' 'lib/' --output-file lcov.info --rc lcov_branch_coverage=1 # This step posts a detailed coverage report as a comment and deletes previous comments on # each push. The below step is used to fail coverage if the specified coverage threshold is diff --git a/.github/workflows/l1-contracts-foundry-ci.yaml b/.github/workflows/l1-contracts-foundry-ci.yaml deleted file mode 100644 index 02c551d63..000000000 --- a/.github/workflows/l1-contracts-foundry-ci.yaml +++ /dev/null @@ -1,117 +0,0 @@ -name: L1 contracts foundry CI - -env: - ANVIL_PRIVATE_KEY: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ANVIL_RPC_URL: "http://127.0.0.1:8545" - -on: - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - with: - submodules: true - - - name: Use Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: 18.18.0 - cache: yarn - - - name: Install dependencies - run: yarn - - - name: Build artifacts - working-directory: ./l1-contracts - run: forge build - - - name: Build system-contract artifacts - run: yarn sc build - - - name: Create cache - uses: actions/cache/save@v3 - with: - key: artifacts-l1-contracts-foudry-${{ github.sha }} - path: | - l1-contracts/cache - l1-contracts/out - system-contracts/artifacts-zk - system-contracts/bootloader/build - system-contracts/cache-zk - system-contracts/contracts-preprocessed - system-contracts/typechain - - scripts: - runs-on: ubuntu-latest - needs: build - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - with: - submodules: true - - - name: Restore artifacts cache - uses: actions/cache/restore@v3 - with: - fail-on-cache-miss: true - key: artifacts-l1-contracts-foudry-${{ github.sha }} - path: | - l1-contracts/cache - l1-contracts/out - system-contracts/artifacts-zk - system-contracts/bootloader/build - system-contracts/cache-zk - system-contracts/contracts-preprocessed - system-contracts/typechain - - - name: Use Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Copy configs from template - working-directory: ./l1-contracts - run: cp -r deploy-script-config-template script-config - - - name: Run anvil - run: | - anvil --silent & - - ANVIL_READY=0 - for i in {1..10}; do - if curl -s -o /dev/null $ANVIL_RPC_URL -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_chainId","id":1}'; then - echo "Anvil is ready" - ANVIL_READY=1 - break - else - echo "Waiting for Anvil to become ready..." - sleep 1 - fi - done - - if [ $ANVIL_READY -ne 1 ]; then - echo "Anvil failed to become ready after 10 attempts." - exit 1 - fi - - - name: Run DeployL1 script - working-directory: ./l1-contracts - run: forge script ./deploy-scripts/DeployL1.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY - - - name: Run DeployErc20 script - working-directory: ./l1-contracts - run: forge script ./deploy-scripts/DeployErc20.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY -# TODO restore scripts verification -# - name: Run RegisterHyperchain script -# working-directory: ./l1-contracts -# run: | -# cat ./script-out/output-deploy-l1.toml >> ./script-config/register-hyperchain.toml -# forge script ./deploy-scripts/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY -# - name: Run InitializeL2WethToken script -# working-directory: ./l1-contracts-foundry -# run: forge script ./deploy-scripts/InitializeL2WethToken.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY diff --git a/.gitmodules b/.gitmodules index 5cbc631ba..13db155a9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,14 +1,14 @@ -[submodule "l1-contracts/lib/forge-std"] - path = l1-contracts/lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "l1-contracts/lib/murky"] - path = l1-contracts/lib/murky +[submodule "lib/murky"] + path = lib/murky url = https://github.com/dmfxyz/murky -[submodule "l1-contracts/lib/openzeppelin-contracts-upgradeable"] - path = l1-contracts/lib/openzeppelin-contracts-upgradeable +[submodule "lib/openzeppelin-contracts-upgradeable"] + path = lib/openzeppelin-contracts-upgradeable url = https://github.com/Openzeppelin/openzeppelin-contracts-upgradeable branch = release-v4.9 -[submodule "l1-contracts/lib/openzeppelin-contracts"] - path = l1-contracts/lib/openzeppelin-contracts +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts url = https://github.com/Openzeppelin/openzeppelin-contracts branch = release-v4.9 +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/.markdownlintignore b/.markdownlintignore index 5abdcbeb3..cffb39f9c 100644 --- a/.markdownlintignore +++ b/.markdownlintignore @@ -2,7 +2,6 @@ node_modules # l1-contracts -l1-contracts/lib l1-contracts/node_modules # l1-contracts-foundry @@ -14,3 +13,8 @@ l2-contracts/node_modules # system-contracts system-contracts/node_modules system-contracts/bootloader/test_infra/target + +l1-contracts/lib +lib/ +l2-contracts/lib +system-contracts/lib diff --git a/.prettierignore b/.prettierignore index 5bc4f9aa7..0c2a4c4dc 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,7 @@ tools/data l1-contracts/lib l1-contracts-foundry/lib +lib system-contracts/contracts/openzeppelin system-contracts/contracts/Constants.sol system-contracts/artifacts-zk @@ -10,3 +11,6 @@ l1-contracts/cache l1-contracts/cache-forge l1-contracts/artifacts l1-contracts/artifacts-forge +l1-contracts/zkout +l2-contracts/zkout +system-contracts/zkout diff --git a/.solhintignore b/.solhintignore index 8e9f84ade..ab2fcf7e1 100644 --- a/.solhintignore +++ b/.solhintignore @@ -25,3 +25,7 @@ system-contracts/contracts-preprocessed # gas-bound-caller gas-bound-caller/contracts/test-contracts + +lib/* +l2-contracts/lib +system-contracts/lib diff --git a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol index c7c9c64f1..b201204c5 100644 --- a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol +++ b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol @@ -8,6 +8,7 @@ import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZk import {ChainAdmin} from "contracts/governance/ChainAdmin.sol"; import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; import {Utils} from "./Utils.sol"; +import {stdToml} from "forge-std/StdToml.sol"; contract AcceptAdmin is Script { using stdToml for string; diff --git a/l1-contracts/deploy-scripts/DeployL2Contracts.sol b/l1-contracts/deploy-scripts/DeployL2Contracts.sol index fa7893f8d..e3de2d82d 100644 --- a/l1-contracts/deploy-scripts/DeployL2Contracts.sol +++ b/l1-contracts/deploy-scripts/DeployL2Contracts.sol @@ -72,25 +72,23 @@ contract DeployL2Script is Script { function loadContracts() internal { //HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat - contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" + contracts.l2StandardErc20FactoryBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/UpgradeableBeacon.sol/UpgradeableBeacon.json" ); - contracts.beaconProxy = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json" - ); - contracts.l2StandardErc20Bytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" + contracts.beaconProxy = Utils.readFoundryBytecode("/../l2-contracts/zkout/BeaconProxy.sol/BeaconProxy.json"); + contracts.l2StandardErc20Bytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/L2StandardERC20.sol/L2StandardERC20.json" ); - contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json" + contracts.l2SharedBridgeBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/L2SharedBridge.sol/L2SharedBridge.json" ); - contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" + contracts.l2SharedBridgeProxyBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" ); - contracts.forceDeployUpgrader = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" + contracts.forceDeployUpgrader = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" ); } diff --git a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol index f7115a479..d6d854363 100644 --- a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol +++ b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol @@ -43,8 +43,8 @@ contract DeployPaymaster is Script { } function deploy() internal { - bytes memory testnetPaymasterBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/TestnetPaymaster.sol/TestnetPaymaster.json" + bytes memory testnetPaymasterBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/TestnetPaymaster.sol/TestnetPaymaster.json" ); config.paymaster = Utils.deployThroughL1({ diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 318be6da3..4b74035c0 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -287,11 +287,11 @@ library Utils { /** * @dev Read hardhat bytecodes */ - function readHardhatBytecode(string memory artifactPath) internal view returns (bytes memory) { + function readFoundryBytecode(string memory artifactPath) internal view returns (bytes memory) { string memory root = vm.projectRoot(); string memory path = string.concat(root, artifactPath); string memory json = vm.readFile(path); - bytes memory bytecode = vm.parseJsonBytes(json, ".bytecode"); + bytes memory bytecode = vm.parseJsonBytes(json, ".bytecode.object"); return bytecode; } diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index 6f29a31cc..b0bd14e79 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -5,6 +5,7 @@ libs = ['node_modules', 'lib'] remappings = [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", + "murky=lib/murky/src/", "l2-contracts/=../l2-contracts/contracts/" ] allow_paths = ["../l2-contracts/contracts"] @@ -12,6 +13,8 @@ fs_permissions = [ { access = "read", path = "../system-contracts/bootloader/build/artifacts" }, { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed" }, { access = "read", path = "../l2-contracts/artifacts-zk/" }, + { access = "read", path = "../l2-contracts/zkout/" }, + { access = "read", path = "../system-contracts/zkout/" }, { access = "read", path = "./script-config" }, { access = "read-write", path = "./script-out" }, { access = "read", path = "./out" } diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std deleted file mode 160000 index 52715a217..000000000 --- a/l1-contracts/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std new file mode 120000 index 000000000..edce15694 --- /dev/null +++ b/l1-contracts/lib/forge-std @@ -0,0 +1 @@ +../../lib/forge-std \ No newline at end of file diff --git a/l1-contracts/lib/murky b/l1-contracts/lib/murky deleted file mode 160000 index 40de6e801..000000000 --- a/l1-contracts/lib/murky +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 40de6e80117f39cda69d71b07b7c824adac91b29 diff --git a/l1-contracts/lib/murky b/l1-contracts/lib/murky new file mode 120000 index 000000000..a556a15e5 --- /dev/null +++ b/l1-contracts/lib/murky @@ -0,0 +1 @@ +../../lib/murky \ No newline at end of file diff --git a/l1-contracts/lib/openzeppelin-contracts b/l1-contracts/lib/openzeppelin-contracts deleted file mode 160000 index dc44c9f1a..000000000 --- a/l1-contracts/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dc44c9f1a4c3b10af99492eed84f83ed244203f6 diff --git a/l1-contracts/lib/openzeppelin-contracts b/l1-contracts/lib/openzeppelin-contracts new file mode 120000 index 000000000..99aa45507 --- /dev/null +++ b/l1-contracts/lib/openzeppelin-contracts @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts \ No newline at end of file diff --git a/l1-contracts/lib/openzeppelin-contracts-upgradeable b/l1-contracts/lib/openzeppelin-contracts-upgradeable deleted file mode 160000 index 2d081f24c..000000000 --- a/l1-contracts/lib/openzeppelin-contracts-upgradeable +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2d081f24cac1a867f6f73d512f2022e1fa987854 diff --git a/l1-contracts/lib/openzeppelin-contracts-upgradeable b/l1-contracts/lib/openzeppelin-contracts-upgradeable new file mode 120000 index 000000000..f1fc7a76a --- /dev/null +++ b/l1-contracts/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-upgradeable \ No newline at end of file diff --git a/l2-contracts/.gitignore b/l2-contracts/.gitignore new file mode 100644 index 000000000..16d545bb0 --- /dev/null +++ b/l2-contracts/.gitignore @@ -0,0 +1,15 @@ +# Compiler files +cache/ +out/ +zkout/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/l2-contracts/foundry.toml b/l2-contracts/foundry.toml new file mode 100644 index 000000000..fcf297c30 --- /dev/null +++ b/l2-contracts/foundry.toml @@ -0,0 +1,12 @@ +[profile.default] +src = "contracts" +out = "out" +libs = ["lib"] +remappings = [ + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", +] +evm_version = "paris" + +[profile.default.zksync] +zksolc = "1.5.0" diff --git a/l2-contracts/lib/forge-std b/l2-contracts/lib/forge-std new file mode 120000 index 000000000..edce15694 --- /dev/null +++ b/l2-contracts/lib/forge-std @@ -0,0 +1 @@ +../../lib/forge-std \ No newline at end of file diff --git a/l2-contracts/lib/openzeppelin-contracts b/l2-contracts/lib/openzeppelin-contracts new file mode 120000 index 000000000..99aa45507 --- /dev/null +++ b/l2-contracts/lib/openzeppelin-contracts @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts \ No newline at end of file diff --git a/l2-contracts/lib/openzeppelin-contracts-upgradeable b/l2-contracts/lib/openzeppelin-contracts-upgradeable new file mode 120000 index 000000000..f1fc7a76a --- /dev/null +++ b/l2-contracts/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-upgradeable \ No newline at end of file diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 000000000..52715a217 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 diff --git a/lib/murky b/lib/murky new file mode 160000 index 000000000..40de6e801 --- /dev/null +++ b/lib/murky @@ -0,0 +1 @@ +Subproject commit 40de6e80117f39cda69d71b07b7c824adac91b29 diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 000000000..dc44c9f1a --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit dc44c9f1a4c3b10af99492eed84f83ed244203f6 diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 000000000..2d081f24c --- /dev/null +++ b/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit 2d081f24cac1a867f6f73d512f2022e1fa987854 diff --git a/system-contracts/.gitignore b/system-contracts/.gitignore new file mode 100644 index 000000000..16d545bb0 --- /dev/null +++ b/system-contracts/.gitignore @@ -0,0 +1,15 @@ +# Compiler files +cache/ +out/ +zkout/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/system-contracts/foundry.toml b/system-contracts/foundry.toml new file mode 100644 index 000000000..0ab0a20d7 --- /dev/null +++ b/system-contracts/foundry.toml @@ -0,0 +1,11 @@ +[profile.default] +src = "contracts-preprocessed" +out = "out" +libs = ["lib"] +evm_version = 'paris' +remappings = [ + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", +] +[profile.default.zksync] +zksolc = "1.5.0" diff --git a/system-contracts/lib/forge-std b/system-contracts/lib/forge-std new file mode 120000 index 000000000..edce15694 --- /dev/null +++ b/system-contracts/lib/forge-std @@ -0,0 +1 @@ +../../lib/forge-std \ No newline at end of file diff --git a/system-contracts/lib/openzeppelin-contracts b/system-contracts/lib/openzeppelin-contracts new file mode 120000 index 000000000..99aa45507 --- /dev/null +++ b/system-contracts/lib/openzeppelin-contracts @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts \ No newline at end of file diff --git a/system-contracts/lib/openzeppelin-contracts-upgradeable b/system-contracts/lib/openzeppelin-contracts-upgradeable new file mode 120000 index 000000000..f1fc7a76a --- /dev/null +++ b/system-contracts/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-upgradeable \ No newline at end of file diff --git a/system-contracts/scripts/preprocess-bootloader.ts b/system-contracts/scripts/preprocess-bootloader.ts index 4dbf145da..952181455 100644 --- a/system-contracts/scripts/preprocess-bootloader.ts +++ b/system-contracts/scripts/preprocess-bootloader.ts @@ -6,6 +6,7 @@ import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs"; import { render, renderFile } from "template-file"; import { utils } from "zksync-ethers"; import { getRevertSelector, getTransactionUtils } from "./constants"; +import * as fs from "node:fs"; /* eslint-disable @typescript-eslint/no-var-requires */ const preprocess = require("preprocess"); @@ -17,9 +18,16 @@ const OUTPUT_DIR = "bootloader/build"; const PREPROCCESING_MODES = ["proved_batch", "playground_batch"]; function getSelector(contractName: string, method: string): string { - const artifact = hre.artifacts.readArtifactSync(contractName); - const contractInterface = new ethers.utils.Interface(artifact.abi); - + let contractInterface; + try { + const artifact = hre.artifacts.readArtifactSync(contractName); + contractInterface = new ethers.utils.Interface(artifact.abi); + } catch (e) { + const artifact = JSON.parse( + fs.readFileSync(`zkout/${contractName}.sol/${contractName}.json`, { encoding: "utf-8" }) + ); + contractInterface = new ethers.utils.Interface(artifact.abi); + } return contractInterface.getSighash(method); } @@ -33,6 +41,7 @@ function padZeroRight(hexData: string, length: number): string { } const PADDED_SELECTOR_LENGTH = 32 * 2 + 2; + function getPaddedSelector(contractName: string, method: string): string { const result = getSelector(contractName, method); @@ -40,7 +49,13 @@ function getPaddedSelector(contractName: string, method: string): string { } function getSystemContextCodeHash() { - const bytecode = hre.artifacts.readArtifactSync("SystemContext").bytecode; + let bytecode; + try { + const artifact = JSON.parse(fs.readFileSync("zkout/SystemContext.sol/SystemContext.json", { encoding: "utf-8" })); + bytecode = "0x" + artifact.bytecode.object; + } catch (e) { + bytecode = hre.artifacts.readArtifactSync("SystemContext").bytecode; + } return ethers.utils.hexlify(utils.hashBytecode(bytecode)); } diff --git a/yarn.lock b/yarn.lock index cf48539c2..728d64dae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -792,10 +792,10 @@ sinon-chai "^3.7.0" zksync-ethers "^5.0.0" -"@matterlabs/hardhat-zksync-verify@^0.2.0": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.2.2.tgz#daa34bc4404096ed0f44461ee366c1cb0e5a4f2f" - integrity sha512-WgcItoZGY702oJ708uCP5uLvmwzDLBfhMqq2D0Kh1U/3fCTlPza9zMGUFHxKMQYsITKTeQ5zKOjKoi8MXOeUdQ== +"@matterlabs/hardhat-zksync-verify@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.4.0.tgz#f812c19950022fc36728f3796f6bdae5633e2fcd" + integrity sha512-GPZmAumFl3ZMPKbECX7Qw8CriwZKWd1DlCRhoG/6YYc6mFy4+MXkF1XsHLMs5r34N+GDOfbVZVMeftIlJC96Kg== dependencies: "@matterlabs/hardhat-zksync-solc" "^1.0.5" "@nomicfoundation/hardhat-verify" "^1.0.2" @@ -4490,7 +4490,7 @@ hardhat@^2.14.0: uuid "^8.3.2" ws "^7.4.6" -hardhat@^2.18.3, hardhat@^2.19.4: +hardhat@^2.19.4: version "2.22.5" resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.5.tgz#7e1a4311fa9e34a1cfe337784eae06706f6469a5" integrity sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw== @@ -7925,12 +7925,6 @@ zksync-ethers@^5.0.0: dependencies: ethers "~5.7.0" -"zksync-ethers@https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub": - version "5.1.0" - resolved "https://github.com/zksync-sdk/zksync-ethers#28ccbe7d67b170c202b17475e06a82002e6e3acc" - dependencies: - ethers "~5.7.0" - zksync-ethers@^5.9.0: version "5.9.0" resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.9.0.tgz#96dc29e4eaaf0aa70d927886fd6e1e4c545786e3" From 80e8234c42f89ed9cb4ec05abdaf5c580778507c Mon Sep 17 00:00:00 2001 From: Moshe Shababo <17073733+moshababo@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:30:04 +0300 Subject: [PATCH 25/42] feat(consensus): add L2 registry contract (BFT-434) (#555) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Akosh Farkash Co-authored-by: Bruno França Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Co-authored-by: Roman Brodetski Co-authored-by: vladbochok --- l2-contracts/contracts/ConsensusRegistry.sol | 486 +++++++++++++++++ .../interfaces/IConsensusRegistry.sol | 161 ++++++ l2-contracts/package.json | 3 +- l2-contracts/src/deploy-consensus-registry.ts | 90 ++++ l2-contracts/src/utils.ts | 21 + l2-contracts/test/consensusRegistry.test.ts | 499 ++++++++++++++++++ 6 files changed, 1259 insertions(+), 1 deletion(-) create mode 100644 l2-contracts/contracts/ConsensusRegistry.sol create mode 100644 l2-contracts/contracts/interfaces/IConsensusRegistry.sol create mode 100644 l2-contracts/src/deploy-consensus-registry.ts create mode 100644 l2-contracts/test/consensusRegistry.test.ts diff --git a/l2-contracts/contracts/ConsensusRegistry.sol b/l2-contracts/contracts/ConsensusRegistry.sol new file mode 100644 index 000000000..514a4f205 --- /dev/null +++ b/l2-contracts/contracts/ConsensusRegistry.sol @@ -0,0 +1,486 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {IConsensusRegistry} from "./interfaces/IConsensusRegistry.sol"; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +/// @title ConsensusRegistry +/// @dev Manages consensus nodes and committees for the L2 consensus protocol, +/// owned by Matter Labs Multisig. Nodes act as both validators and attesters, +/// each playing a distinct role in the consensus process. This contract facilitates +/// the rotation of validator and attester committees, which represent a subset of nodes +/// expected to actively participate in the consensus process during a specific time window. +/// @dev Designed for use with a proxy for upgradability. +contract ConsensusRegistry is IConsensusRegistry, Initializable, Ownable2StepUpgradeable { + /// @dev An array to keep track of node owners. + address[] public nodeOwners; + /// @dev A mapping of node owners => nodes. + mapping(address => Node) public nodes; + /// @dev A mapping for enabling efficient lookups when checking whether a given attester public key exists. + mapping(bytes32 => bool) public attesterPubKeyHashes; + /// @dev A mapping for enabling efficient lookups when checking whether a given validator public key exists. + mapping(bytes32 => bool) public validatorPubKeyHashes; + /// @dev Counter that increments with each new commit to the attester committee. + uint32 public attestersCommit; + /// @dev Counter that increments with each new commit to the validator committee. + uint32 public validatorsCommit; + + modifier onlyOwnerOrNodeOwner(address _nodeOwner) { + if (owner() != msg.sender && _nodeOwner != msg.sender) { + revert UnauthorizedOnlyOwnerOrNodeOwner(); + } + _; + } + + function initialize(address _initialOwner) external initializer { + if (_initialOwner == address(0)) { + revert InvalidInputNodeOwnerAddress(); + } + _transferOwnership(_initialOwner); + } + + /// @notice Adds a new node to the registry. + /// @dev Fails if node owner already exists. + /// @dev Fails if a validator/attester with the same public key already exists. + /// @param _nodeOwner The address of the new node's owner. + /// @param _validatorWeight The voting weight of the validator. + /// @param _validatorPubKey The BLS12-381 public key of the validator. + /// @param _validatorPoP The proof-of-possession (PoP) of the validator's public key. + /// @param _attesterWeight The voting weight of the attester. + /// @param _attesterPubKey The ECDSA public key of the attester. + function add( + address _nodeOwner, + uint32 _validatorWeight, + BLS12_381PublicKey calldata _validatorPubKey, + BLS12_381Signature calldata _validatorPoP, + uint32 _attesterWeight, + Secp256k1PublicKey calldata _attesterPubKey + ) external onlyOwner { + // Verify input. + _verifyInputAddress(_nodeOwner); + _verifyInputBLS12_381PublicKey(_validatorPubKey); + _verifyInputBLS12_381Signature(_validatorPoP); + _verifyInputSecp256k1PublicKey(_attesterPubKey); + + // Verify storage. + _verifyNodeOwnerDoesNotExist(_nodeOwner); + bytes32 attesterPubKeyHash = _hashAttesterPubKey(_attesterPubKey); + _verifyAttesterPubKeyDoesNotExist(attesterPubKeyHash); + bytes32 validatorPubKeyHash = _hashValidatorPubKey(_validatorPubKey); + _verifyValidatorPubKeyDoesNotExist(validatorPubKeyHash); + + uint32 nodeOwnerIdx = uint32(nodeOwners.length); + nodeOwners.push(_nodeOwner); + nodes[_nodeOwner] = Node({ + attesterLatest: AttesterAttr({ + active: true, + removed: false, + weight: _attesterWeight, + pubKey: _attesterPubKey + }), + attesterSnapshot: AttesterAttr({ + active: false, + removed: false, + weight: 0, + pubKey: Secp256k1PublicKey({tag: bytes1(0), x: bytes32(0)}) + }), + attesterLastUpdateCommit: attestersCommit, + validatorLatest: ValidatorAttr({ + active: true, + removed: false, + weight: _validatorWeight, + pubKey: _validatorPubKey, + proofOfPossession: _validatorPoP + }), + validatorSnapshot: ValidatorAttr({ + active: false, + removed: false, + weight: 0, + pubKey: BLS12_381PublicKey({a: bytes32(0), b: bytes32(0), c: bytes32(0)}), + proofOfPossession: BLS12_381Signature({a: bytes32(0), b: bytes16(0)}) + }), + validatorLastUpdateCommit: validatorsCommit, + nodeOwnerIdx: nodeOwnerIdx + }); + attesterPubKeyHashes[attesterPubKeyHash] = true; + validatorPubKeyHashes[validatorPubKeyHash] = true; + + emit NodeAdded({ + nodeOwner: _nodeOwner, + validatorWeight: _validatorWeight, + validatorPubKey: _validatorPubKey, + validatorPoP: _validatorPoP, + attesterWeight: _attesterWeight, + attesterPubKey: _attesterPubKey + }); + } + + /// @notice Deactivates a node, preventing it from participating in committees. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner to be inactivated. + function deactivate(address _nodeOwner) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.active = false; + _ensureValidatorSnapshot(node); + node.validatorLatest.active = false; + + emit NodeDeactivated(_nodeOwner); + } + + /// @notice Activates a previously inactive node, allowing it to participate in committees. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner to be activated. + function activate(address _nodeOwner) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.active = true; + _ensureValidatorSnapshot(node); + node.validatorLatest.active = true; + + emit NodeActivated(_nodeOwner); + } + + /// @notice Removes a node from the registry. + /// @dev Only callable by the contract owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner to be removed. + function remove(address _nodeOwner) external onlyOwner { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.removed = true; + _ensureValidatorSnapshot(node); + node.validatorLatest.removed = true; + + emit NodeRemoved(_nodeOwner); + } + + /// @notice Changes the validator weight of a node in the registry. + /// @dev Only callable by the contract owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose validator weight will be changed. + /// @param _weight The new validator weight to assign to the node. + function changeValidatorWeight(address _nodeOwner, uint32 _weight) external onlyOwner { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureValidatorSnapshot(node); + node.validatorLatest.weight = _weight; + + emit NodeValidatorWeightChanged(_nodeOwner, _weight); + } + + /// @notice Changes the attester weight of a node in the registry. + /// @dev Only callable by the contract owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose attester weight will be changed. + /// @param _weight The new attester weight to assign to the node. + function changeAttesterWeight(address _nodeOwner, uint32 _weight) external onlyOwner { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.weight = _weight; + + emit NodeAttesterWeightChanged(_nodeOwner, _weight); + } + + /// @notice Changes the validator's public key and proof-of-possession in the registry. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose validator key and PoP will be changed. + /// @param _pubKey The new BLS12-381 public key to assign to the node's validator. + /// @param _pop The new proof-of-possession (PoP) to assign to the node's validator. + function changeValidatorKey( + address _nodeOwner, + BLS12_381PublicKey calldata _pubKey, + BLS12_381Signature calldata _pop + ) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyInputBLS12_381PublicKey(_pubKey); + _verifyInputBLS12_381Signature(_pop); + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + bytes32 prevHash = _hashValidatorPubKey(node.validatorLatest.pubKey); + delete validatorPubKeyHashes[prevHash]; + bytes32 newHash = _hashValidatorPubKey(_pubKey); + _verifyValidatorPubKeyDoesNotExist(newHash); + validatorPubKeyHashes[newHash] = true; + _ensureValidatorSnapshot(node); + node.validatorLatest.pubKey = _pubKey; + node.validatorLatest.proofOfPossession = _pop; + + emit NodeValidatorKeyChanged(_nodeOwner, _pubKey, _pop); + } + + /// @notice Changes the attester's public key of a node in the registry. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose attester public key will be changed. + /// @param _pubKey The new ECDSA public key to assign to the node's attester. + function changeAttesterKey( + address _nodeOwner, + Secp256k1PublicKey calldata _pubKey + ) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyInputSecp256k1PublicKey(_pubKey); + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + bytes32 prevHash = _hashAttesterPubKey(node.attesterLatest.pubKey); + delete attesterPubKeyHashes[prevHash]; + bytes32 newHash = _hashAttesterPubKey(_pubKey); + _verifyAttesterPubKeyDoesNotExist(newHash); + attesterPubKeyHashes[newHash] = true; + + _ensureAttesterSnapshot(node); + node.attesterLatest.pubKey = _pubKey; + + emit NodeAttesterKeyChanged(_nodeOwner, _pubKey); + } + + /// @notice Adds a new commit to the attester committee. + /// @dev Implicitly updates the attester committee by affecting readers based on the current state of a node's attester attributes: + /// - If "attestersCommit" > "node.attesterLastUpdateCommit", read "node.attesterLatest". + /// - If "attestersCommit" == "node.attesterLastUpdateCommit", read "node.attesterSnapshot". + /// @dev Only callable by the contract owner. + function commitAttesterCommittee() external onlyOwner { + ++attestersCommit; + + emit AttestersCommitted(attestersCommit); + } + + /// @notice Adds a new commit to the validator committee. + /// @dev Implicitly updates the validator committee by affecting readers based on the current state of a node's validator attributes: + /// - If "validatorsCommit" > "node.validatorLastUpdateCommit", read "node.validatorLatest". + /// - If "validatorsCommit" == "node.validatorLastUpdateCommit", read "node.validatorSnapshot". + /// @dev Only callable by the contract owner. + function commitValidatorCommittee() external onlyOwner { + ++validatorsCommit; + + emit ValidatorsCommitted(validatorsCommit); + } + + /// @notice Returns an array of `AttesterAttr` structs representing the current attester committee. + /// @dev Collects active and non-removed attesters based on the latest commit to the committee. + function getAttesterCommittee() public view returns (CommitteeAttester[] memory) { + uint256 len = nodeOwners.length; + CommitteeAttester[] memory committee = new CommitteeAttester[](len); + uint256 count = 0; + + for (uint256 i = 0; i < len; ++i) { + Node storage node = nodes[nodeOwners[i]]; + AttesterAttr memory attester = attestersCommit > node.attesterLastUpdateCommit + ? node.attesterLatest + : node.attesterSnapshot; + if (attester.active && !attester.removed) { + committee[count] = CommitteeAttester({weight: attester.weight, pubKey: attester.pubKey}); + ++count; + } + } + + // Resize the array. + assembly { + mstore(committee, count) + } + return committee; + } + + /// @notice Returns an array of `ValidatorAttr` structs representing the current attester committee. + /// @dev Collects active and non-removed validators based on the latest commit to the committee. + function getValidatorCommittee() public view returns (CommitteeValidator[] memory) { + uint256 len = nodeOwners.length; + CommitteeValidator[] memory committee = new CommitteeValidator[](len); + uint256 count = 0; + + for (uint256 i = 0; i < len; ++i) { + Node storage node = nodes[nodeOwners[i]]; + ValidatorAttr memory validator = validatorsCommit > node.validatorLastUpdateCommit + ? node.validatorLatest + : node.validatorSnapshot; + if (validator.active && !validator.removed) { + committee[count] = CommitteeValidator({ + weight: validator.weight, + pubKey: validator.pubKey, + proofOfPossession: validator.proofOfPossession + }); + ++count; + } + } + + // Resize the array. + assembly { + mstore(committee, count) + } + return committee; + } + + function numNodes() public view returns (uint256) { + return nodeOwners.length; + } + + function _getNodeAndDeleteIfRequired(address _nodeOwner) private returns (Node storage, bool) { + Node storage node = nodes[_nodeOwner]; + bool pendingDeletion = _isNodePendingDeletion(node); + if (pendingDeletion) { + _deleteNode(_nodeOwner, node); + } + return (node, pendingDeletion); + } + + function _isNodePendingDeletion(Node storage _node) private returns (bool) { + bool attesterRemoved = (attestersCommit > _node.attesterLastUpdateCommit) + ? _node.attesterLatest.removed + : _node.attesterSnapshot.removed; + bool validatorRemoved = (validatorsCommit > _node.validatorLastUpdateCommit) + ? _node.validatorLatest.removed + : _node.validatorSnapshot.removed; + return attesterRemoved && validatorRemoved; + } + + function _deleteNode(address _nodeOwner, Node storage _node) private { + // Delete from array by swapping the last node owner (gas-efficient, not preserving order). + address lastNodeOwner = nodeOwners[nodeOwners.length - 1]; + nodeOwners[_node.nodeOwnerIdx] = lastNodeOwner; + nodeOwners.pop(); + // Update the node owned by the last node owner. + nodes[lastNodeOwner].nodeOwnerIdx = _node.nodeOwnerIdx; + + // Delete from the remaining mapping. + delete attesterPubKeyHashes[_hashAttesterPubKey(_node.attesterLatest.pubKey)]; + delete validatorPubKeyHashes[_hashValidatorPubKey(_node.validatorLatest.pubKey)]; + delete nodes[_nodeOwner]; + + emit NodeDeleted(_nodeOwner); + } + + function _ensureAttesterSnapshot(Node storage _node) private { + if (_node.attesterLastUpdateCommit < attestersCommit) { + _node.attesterSnapshot = _node.attesterLatest; + _node.attesterLastUpdateCommit = attestersCommit; + } + } + + function _ensureValidatorSnapshot(Node storage _node) private { + if (_node.validatorLastUpdateCommit < validatorsCommit) { + _node.validatorSnapshot = _node.validatorLatest; + _node.validatorLastUpdateCommit = validatorsCommit; + } + } + + function _isNodeOwnerExists(address _nodeOwner) private view returns (bool) { + BLS12_381PublicKey storage pubKey = nodes[_nodeOwner].validatorLatest.pubKey; + if (pubKey.a == bytes32(0) && pubKey.b == bytes32(0) && pubKey.c == bytes32(0)) { + return false; + } + return true; + } + + function _verifyNodeOwnerExists(address _nodeOwner) private view { + if (!_isNodeOwnerExists(_nodeOwner)) { + revert NodeOwnerDoesNotExist(); + } + } + + function _verifyNodeOwnerDoesNotExist(address _nodeOwner) private view { + if (_isNodeOwnerExists(_nodeOwner)) { + revert NodeOwnerExists(); + } + } + + function _hashAttesterPubKey(Secp256k1PublicKey storage _pubKey) private view returns (bytes32) { + return keccak256(abi.encode(_pubKey.tag, _pubKey.x)); + } + + function _hashAttesterPubKey(Secp256k1PublicKey calldata _pubKey) private pure returns (bytes32) { + return keccak256(abi.encode(_pubKey.tag, _pubKey.x)); + } + + function _hashValidatorPubKey(BLS12_381PublicKey storage _pubKey) private view returns (bytes32) { + return keccak256(abi.encode(_pubKey.a, _pubKey.b, _pubKey.c)); + } + + function _hashValidatorPubKey(BLS12_381PublicKey calldata _pubKey) private pure returns (bytes32) { + return keccak256(abi.encode(_pubKey.a, _pubKey.b, _pubKey.c)); + } + + function _verifyInputAddress(address _nodeOwner) private pure { + if (_nodeOwner == address(0)) { + revert InvalidInputNodeOwnerAddress(); + } + } + + function _verifyAttesterPubKeyDoesNotExist(bytes32 _hash) private view { + if (attesterPubKeyHashes[_hash]) { + revert AttesterPubKeyExists(); + } + } + + function _verifyValidatorPubKeyDoesNotExist(bytes32 _hash) private { + if (validatorPubKeyHashes[_hash]) { + revert ValidatorPubKeyExists(); + } + } + + function _verifyInputBLS12_381PublicKey(BLS12_381PublicKey calldata _pubKey) private pure { + if (_isEmptyBLS12_381PublicKey(_pubKey)) { + revert InvalidInputBLS12_381PublicKey(); + } + } + + function _verifyInputBLS12_381Signature(BLS12_381Signature calldata _pop) private pure { + if (_isEmptyBLS12_381Signature(_pop)) { + revert InvalidInputBLS12_381Signature(); + } + } + + function _verifyInputSecp256k1PublicKey(Secp256k1PublicKey calldata _pubKey) private pure { + if (_isEmptySecp256k1PublicKey(_pubKey)) { + revert InvalidInputSecp256k1PublicKey(); + } + } + + function _isEmptyBLS12_381PublicKey(BLS12_381PublicKey calldata _pubKey) private pure returns (bool) { + return _pubKey.a == bytes32(0) && _pubKey.b == bytes32(0) && _pubKey.c == bytes32(0); + } + + function _isEmptyBLS12_381Signature(BLS12_381Signature calldata _pop) private pure returns (bool) { + return _pop.a == bytes32(0) && _pop.b == bytes16(0); + } + + function _isEmptySecp256k1PublicKey(Secp256k1PublicKey calldata _pubKey) private pure returns (bool) { + return _pubKey.tag == bytes1(0) && _pubKey.x == bytes32(0); + } +} diff --git a/l2-contracts/contracts/interfaces/IConsensusRegistry.sol b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol new file mode 100644 index 000000000..e3ddd118a --- /dev/null +++ b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +/// @title ConsensusRegistry contract interface +interface IConsensusRegistry { + /// @dev Represents a consensus node. + /// @param attesterLastUpdateCommit The latest `attestersCommit` where the node's attester attributes were updated. + /// @param attesterLatest Attester attributes to read if `node.attesterLastUpdateCommit` < `attestersCommit`. + /// @param attesterSnapshot Attester attributes to read if `node.attesterLastUpdateCommit` == `attestersCommit`. + /// @param validatorLastUpdateCommit The latest `validatorsCommit` where the node's validator attributes were updated. + /// @param validatorLatest Validator attributes to read if `node.validatorLastUpdateCommit` < `validatorsCommit`. + /// @param validatorSnapshot Validator attributes to read if `node.validatorLastUpdateCommit` == `validatorsCommit`. + /// @param nodeOwnerIdx Index of the node owner within the array of node owners. + struct Node { + uint32 attesterLastUpdateCommit; + uint32 validatorLastUpdateCommit; + uint32 nodeOwnerIdx; + AttesterAttr attesterLatest; + AttesterAttr attesterSnapshot; + ValidatorAttr validatorLatest; + ValidatorAttr validatorSnapshot; + } + + /// @dev Represents the attester attributes of a consensus node. + /// @param active A flag stating if the attester is active. + /// @param removed A flag stating if the attester has been removed (and is pending a deletion). + /// @param weight Attester's voting weight. + /// @param pubKey Attester's Secp256k1 public key. + struct AttesterAttr { + bool active; + bool removed; + uint32 weight; + Secp256k1PublicKey pubKey; + } + + /// @dev Represents an attester within a committee. + /// @param weight Attester's voting weight. + /// @param pubKey Attester's Secp256k1 public key. + struct CommitteeAttester { + uint32 weight; + Secp256k1PublicKey pubKey; + } + + /// @dev Represents the validator attributes of a consensus node. + /// @param active A flag stating if the validator is active. + /// @param removed A flag stating if the validator has been removed (and is pending a deletion). + /// @param weight Validator's voting weight. + /// @param pubKey Validator's BLS12-381 public key. + /// @param proofOfPossession Validator's Proof-of-possession (a signature over the public key). + struct ValidatorAttr { + bool active; + bool removed; + uint32 weight; + BLS12_381PublicKey pubKey; + BLS12_381Signature proofOfPossession; + } + + /// @dev Represents a validator within a committee. + /// @param weight Validator's voting weight. + /// @param pubKey Validator's BLS12-381 public key. + /// @param proofOfPossession Validator's Proof-of-possession (a signature over the public key). + struct CommitteeValidator { + uint32 weight; + BLS12_381PublicKey pubKey; + BLS12_381Signature proofOfPossession; + } + + /// @dev Represents BLS12_381 public key. + /// @param a First component of the BLS12-381 public key. + /// @param b Second component of the BLS12-381 public key. + /// @param c Third component of the BLS12-381 public key. + struct BLS12_381PublicKey { + bytes32 a; + bytes32 b; + bytes32 c; + } + + /// @dev Represents BLS12_381 signature. + /// @param a First component of the BLS12-381 signature. + /// @param b Second component of the BLS12-381 signature. + struct BLS12_381Signature { + bytes32 a; + bytes16 b; + } + + /// @dev Represents Secp256k1 public key. + /// @param tag Y-coordinate's even/odd indicator of the Secp256k1 public key. + /// @param x X-coordinate component of the Secp256k1 public key. + struct Secp256k1PublicKey { + bytes1 tag; + bytes32 x; + } + + error UnauthorizedOnlyOwnerOrNodeOwner(); + error NodeOwnerExists(); + error NodeOwnerDoesNotExist(); + error NodeOwnerNotFound(); + error ValidatorPubKeyExists(); + error AttesterPubKeyExists(); + error InvalidInputNodeOwnerAddress(); + error InvalidInputBLS12_381PublicKey(); + error InvalidInputBLS12_381Signature(); + error InvalidInputSecp256k1PublicKey(); + + event NodeAdded( + address indexed nodeOwner, + uint32 validatorWeight, + BLS12_381PublicKey validatorPubKey, + BLS12_381Signature validatorPoP, + uint32 attesterWeight, + Secp256k1PublicKey attesterPubKey + ); + event NodeDeactivated(address indexed nodeOwner); + event NodeActivated(address indexed nodeOwner); + event NodeRemoved(address indexed nodeOwner); + event NodeDeleted(address indexed nodeOwner); + event NodeValidatorWeightChanged(address indexed nodeOwner, uint32 newWeight); + event NodeAttesterWeightChanged(address indexed nodeOwner, uint32 newWeight); + event NodeValidatorKeyChanged(address indexed nodeOwner, BLS12_381PublicKey newPubKey, BLS12_381Signature newPoP); + event NodeAttesterKeyChanged(address indexed nodeOwner, Secp256k1PublicKey newPubKey); + event ValidatorsCommitted(uint32 commit); + event AttestersCommitted(uint32 commit); + + function add( + address _nodeOwner, + uint32 _validatorWeight, + BLS12_381PublicKey calldata _validatorPubKey, + BLS12_381Signature calldata _validatorPoP, + uint32 _attesterWeight, + Secp256k1PublicKey calldata _attesterPubKey + ) external; + + function deactivate(address _nodeOwner) external; + + function activate(address _nodeOwner) external; + + function remove(address _nodeOwner) external; + + function changeValidatorWeight(address _nodeOwner, uint32 _weight) external; + + function changeAttesterWeight(address _nodeOwner, uint32 _weight) external; + + function changeValidatorKey( + address _nodeOwner, + BLS12_381PublicKey calldata _pubKey, + BLS12_381Signature calldata _pop + ) external; + + function changeAttesterKey(address _nodeOwner, Secp256k1PublicKey calldata _pubKey) external; + + function commitAttesterCommittee() external; + + function commitValidatorCommittee() external; + + function getAttesterCommittee() external view returns (CommitteeAttester[] memory); + + function getValidatorCommittee() external view returns (CommitteeValidator[] memory); +} diff --git a/l2-contracts/package.json b/l2-contracts/package.json index a9dfc2779..00dd00457 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -42,7 +42,8 @@ "deploy-l2-weth": "ts-node src/deploy-l2-weth.ts", "upgrade-bridge-contracts": "ts-node src/upgrade-bridge-impl.ts", "update-l2-erc20-metadata": "ts-node src/update-l2-erc20-metadata.ts", - "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts" + "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts", + "deploy-consensus-registry": "ts-node src/deploy-consensus-registry.ts" }, "dependencies": { "dotenv": "^16.0.3" diff --git a/l2-contracts/src/deploy-consensus-registry.ts b/l2-contracts/src/deploy-consensus-registry.ts new file mode 100644 index 000000000..ffbf903f9 --- /dev/null +++ b/l2-contracts/src/deploy-consensus-registry.ts @@ -0,0 +1,90 @@ +import { Command } from "commander"; +import { ethers } from "ethers"; +import { computeL2Create2Address, create2DeployFromL2 } from "./utils"; +import { Interface } from "ethers/lib/utils"; +import { ethTestConfig } from "./deploy-utils"; + +import * as hre from "hardhat"; +import { Provider, Wallet } from "zksync-ethers"; + +const I_TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT = hre.artifacts.readArtifactSync("ITransparentUpgradeableProxy"); +const TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT = hre.artifacts.readArtifactSync("TransparentUpgradeableProxy"); +const CONSENSUS_REGISTRY_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); +const PROXY_ADMIN_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); + +const CONSENSUS_REGISTRY_INTERFACE = new Interface(CONSENSUS_REGISTRY_ARTIFACT.abi); +const I_TRANSPARENT_UPGRADEABLE_PROXY_INTERFACE = new Interface(I_TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.abi); + +// Script to deploy the consensus registry contract and output its address. +// Note, that this script expects that the L2 contracts have been compiled PRIOR +// to running this script. +async function main() { + const program = new Command(); + + program + .version("0.1.0") + .name("deploy-consensus-registry") + .description("Deploys the consensus registry contract to L2"); + + program.option("--private-key ").action(async (cmd) => { + const zksProvider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + const deployWallet = cmd.privateKey + ? new Wallet(cmd.privateKey, zksProvider) + : Wallet.fromMnemonic( + process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, + "m/44'/60'/0'/0/1" + ).connect(zksProvider); + console.log(`Using deployer wallet: ${deployWallet.address}`); + + // Deploy Consensus Registry contract + const consensusRegistryImplementation = await computeL2Create2Address( + deployWallet, + CONSENSUS_REGISTRY_ARTIFACT.bytecode, + "0x", + ethers.constants.HashZero + ); + await create2DeployFromL2(deployWallet, CONSENSUS_REGISTRY_ARTIFACT.bytecode, "0x", ethers.constants.HashZero); + + // Deploy Proxy Admin contract + const proxyAdminContract = await computeL2Create2Address( + deployWallet, + PROXY_ADMIN_ARTIFACT.bytecode, + "0x", + ethers.constants.HashZero + ); + await create2DeployFromL2(deployWallet, PROXY_ADMIN_ARTIFACT.bytecode, "0x", ethers.constants.HashZero); + + const proxyInitializationParams = CONSENSUS_REGISTRY_INTERFACE.encodeFunctionData("initialize", [ + deployWallet.address, + ]); + const proxyConstructor = I_TRANSPARENT_UPGRADEABLE_PROXY_INTERFACE.encodeDeploy([ + consensusRegistryImplementation, + proxyAdminContract, + proxyInitializationParams, + ]); + + await create2DeployFromL2( + deployWallet, + TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.bytecode, + proxyConstructor, + ethers.constants.HashZero + ); + + const address = computeL2Create2Address( + deployWallet, + TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.bytecode, + proxyConstructor, + ethers.constants.HashZero + ); + console.log(`CONTRACTS_L2_CONSENSUS_REGISTRY_ADDR=${address}`); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); diff --git a/l2-contracts/src/utils.ts b/l2-contracts/src/utils.ts index c77817a0b..0a479a540 100644 --- a/l2-contracts/src/utils.ts +++ b/l2-contracts/src/utils.ts @@ -143,6 +143,27 @@ export async function create2DeployFromL1( ); } +export async function create2DeployFromL2( + wallet: ethers.Wallet, + bytecode: ethers.BytesLike, + constructor: ethers.BytesLike, + create2Salt: ethers.BytesLike, + extraFactoryDeps?: ethers.BytesLike[] +) { + const deployerSystemContracts = new Interface(artifacts.readArtifactSync("IContractDeployer").abi); + const bytecodeHash = hashL2Bytecode(bytecode); + const calldata = deployerSystemContracts.encodeFunctionData("create2", [create2Salt, bytecodeHash, constructor]); + + const factoryDeps = extraFactoryDeps ? [bytecode, ...extraFactoryDeps] : [bytecode]; + return await wallet.call({ + to: DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + data: calldata, + customData: { + factoryDeps, + }, + }); +} + export async function publishBytecodeFromL1( chainId: ethers.BigNumberish, wallet: ethers.Wallet, diff --git a/l2-contracts/test/consensusRegistry.test.ts b/l2-contracts/test/consensusRegistry.test.ts new file mode 100644 index 000000000..66c0309bd --- /dev/null +++ b/l2-contracts/test/consensusRegistry.test.ts @@ -0,0 +1,499 @@ +import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; +import * as hre from "hardhat"; +import { Provider, Wallet } from "zksync-ethers"; +import type { ConsensusRegistry } from "../typechain"; +import { ConsensusRegistryFactory } from "../typechain"; +import { expect } from "chai"; +import { ethers } from "ethers"; +import { Interface } from "ethers/lib/utils"; + +const richAccount = { + address: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + privateKey: "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110", +}; + +const gasLimit = 100_000_000; + +const CONSENSUS_REGISTRY_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); +const CONSENSUS_REGISTRY_INTERFACE = new Interface(CONSENSUS_REGISTRY_ARTIFACT.abi); + +describe("ConsensusRegistry", function () { + const provider = new Provider(hre.config.networks.localhost.url); + const owner = new Wallet(richAccount.privateKey, provider); + const nonOwner = new Wallet(Wallet.createRandom().privateKey, provider); + const nodes = []; + const nodeEntries = []; + let registry: ConsensusRegistry; + + before("Initialize", async function () { + // Deploy. + const deployer = new Deployer(hre, owner); + const registryInstance = await deployer.deploy(await deployer.loadArtifact("ConsensusRegistry"), []); + const proxyAdmin = await deployer.deploy(await deployer.loadArtifact("ProxyAdmin"), []); + const proxyInitializationParams = CONSENSUS_REGISTRY_INTERFACE.encodeFunctionData("initialize", [owner.address]); + const proxyInstance = await deployer.deploy(await deployer.loadArtifact("TransparentUpgradeableProxy"), [ + registryInstance.address, + proxyAdmin.address, + proxyInitializationParams, + ]); + registry = ConsensusRegistryFactory.connect(proxyInstance.address, owner); + + // Fund nonOwner. + await ( + await owner.sendTransaction({ + to: nonOwner.address, + value: ethers.utils.parseEther("100"), + }) + ).wait(); + + // Prepare the node list. + const numNodes = 10; + for (let i = 0; i < numNodes; i++) { + const node = makeRandomNode(provider); + const nodeEntry = makeRandomNodeEntry(node, i); + nodes.push(node); + nodeEntries.push(nodeEntry); + } + + // Fund the first node owner. + await ( + await owner.sendTransaction({ + to: nodes[0].ownerKey.address, + value: ethers.utils.parseEther("100"), + }) + ).wait(); + }); + + it("Should set the owner as provided in constructor", async function () { + expect(await registry.owner()).to.equal(owner.address); + }); + + it("Should add nodes to both registries", async function () { + for (let i = 0; i < nodes.length; i++) { + await ( + await registry.add( + nodeEntries[i].ownerAddr, + nodeEntries[i].validatorWeight, + nodeEntries[i].validatorPubKey, + nodeEntries[i].validatorPoP, + nodeEntries[i].attesterWeight, + nodeEntries[i].attesterPubKey + ) + ).wait(); + } + + expect(await registry.numNodes()).to.equal(nodes.length); + + for (let i = 0; i < nodes.length; i++) { + const nodeOwner = await registry.nodeOwners(i); + expect(nodeOwner).to.equal(nodeEntries[i].ownerAddr); + const node = await registry.nodes(nodeOwner); + expect(node.attesterLastUpdateCommit).to.equal(0); + expect(node.validatorLastUpdateCommit).to.equal(0); + + // 'Latest' is expected to match the added node's attributes. + expect(node.attesterLatest.active).to.equal(true); + expect(node.attesterLatest.removed).to.equal(false); + expect(node.attesterLatest.weight).to.equal(nodeEntries[i].attesterWeight); + expect(node.attesterLatest.pubKey.tag).to.equal(nodeEntries[i].attesterPubKey.tag); + expect(node.attesterLatest.pubKey.x).to.equal(nodeEntries[i].attesterPubKey.x); + expect(node.validatorLastUpdateCommit).to.equal(0); + expect(node.validatorLatest.active).to.equal(true); + expect(node.validatorLatest.removed).to.equal(false); + expect(node.validatorLatest.weight).to.equal(nodeEntries[i].attesterWeight); + expect(node.validatorLatest.pubKey.a).to.equal(nodeEntries[i].validatorPubKey.a); + expect(node.validatorLatest.pubKey.b).to.equal(nodeEntries[i].validatorPubKey.b); + expect(node.validatorLatest.pubKey.c).to.equal(nodeEntries[i].validatorPubKey.c); + expect(node.validatorLatest.proofOfPossession.a).to.equal(nodeEntries[i].validatorPoP.a); + expect(node.validatorLatest.proofOfPossession.b).to.equal(nodeEntries[i].validatorPoP.b); + + // 'Snapshot' is expected to have zero values. + expect(node.attesterSnapshot.active).to.equal(false); + expect(node.attesterSnapshot.removed).to.equal(false); + expect(node.attesterSnapshot.weight).to.equal(0); + expect(ethers.utils.arrayify(node.attesterSnapshot.pubKey.tag)).to.deep.equal(new Uint8Array(1)); + expect(ethers.utils.arrayify(node.attesterSnapshot.pubKey.x)).to.deep.equal(new Uint8Array(32)); + expect(node.validatorSnapshot.active).to.equal(false); + expect(node.validatorSnapshot.removed).to.equal(false); + expect(node.validatorSnapshot.weight).to.equal(0); + expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.a)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.b)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.c)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.proofOfPossession.a)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.proofOfPossession.b)).to.deep.equal(new Uint8Array(16)); + } + }); + + it("Should not allow nonOwner to add", async function () { + await expect( + registry + .connect(nonOwner) + .add( + ethers.Wallet.createRandom().address, + 0, + { a: new Uint8Array(32), b: new Uint8Array(32), c: new Uint8Array(32) }, + { a: new Uint8Array(32), b: new Uint8Array(16) }, + 0, + { tag: new Uint8Array(1), x: new Uint8Array(32) }, + { gasLimit } + ) + ).to.be.reverted; + }); + + it("Should allow owner to deactivate", async function () { + const nodeOwner = nodeEntries[0].ownerAddr; + expect((await registry.nodes(nodeOwner)).validatorLatest.active).to.equal(true); + + await (await registry.connect(owner).deactivate(nodeOwner, { gasLimit })).wait(); + expect((await registry.nodes(nodeOwner)).validatorLatest.active).to.equal(false); + + // Restore state. + await (await registry.connect(owner).activate(nodeOwner, { gasLimit })).wait(); + }); + + it("Should not allow nonOwner, nonNodeOwner to deactivate", async function () { + const nodeOwner = nodeEntries[0].ownerAddr; + await expect(registry.connect(nonOwner).deactivate(nodeOwner, { gasLimit })).to.be.reverted; + }); + + it("Should change validator weight", async function () { + const entry = nodeEntries[0]; + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(entry.validatorWeight); + + const baseWeight = entry.validatorWeight; + const newWeight = getRandomNumber(100, 1000); + await (await registry.changeValidatorWeight(entry.ownerAddr, newWeight, { gasLimit })).wait(); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(newWeight); + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(entry.attesterWeight); + + // Restore state. + await (await registry.changeValidatorWeight(entry.ownerAddr, baseWeight, { gasLimit })).wait(); + }); + + it("Should not allow nodeOwner to change validator weight", async function () { + const node = nodes[0]; + await expect(registry.connect(node.ownerKey).changeValidatorWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should not allow nonOwner to change validator weight", async function () { + const node = nodes[0]; + await expect(registry.connect(nonOwner).changeValidatorWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should change attester weight", async function () { + const entry = nodeEntries[0]; + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(entry.attesterWeight); + + const baseWeight = entry.attesterWeight; + const newWeight = getRandomNumber(100, 1000); + await (await registry.changeAttesterWeight(entry.ownerAddr, newWeight, { gasLimit })).wait(); + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(newWeight); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(entry.validatorWeight); + + // Restore state. + await (await registry.changeAttesterWeight(entry.ownerAddr, baseWeight, { gasLimit })).wait(); + }); + + it("Should not allow nodeOwner to change attester weight", async function () { + const node = nodes[0]; + await expect(registry.connect(node.ownerKey).changeAttesterWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should not allow nonOwner to change attester weight", async function () { + const node = nodes[0]; + await expect(registry.connect(nonOwner).changeAttesterWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should not allow to add a node with a validator public key which already exist", async function () { + const newEntry = makeRandomNodeEntry(makeRandomNode(), 0); + await expect( + registry.add( + newEntry.ownerAddr, + newEntry.validatorWeight, + nodeEntries[0].validatorPubKey, + newEntry.validatorPoP, + newEntry.attesterWeight, + newEntry.attesterPubKey, + { gasLimit } + ) + ).to.be.reverted; + }); + + it("Should not allow to add a node with an attester public key which already exist", async function () { + const newEntry = makeRandomNodeEntry(makeRandomNode(), 0); + await expect( + registry.add( + newEntry.ownerAddr, + newEntry.validatorWeight, + newEntry.validatorPubKey, + newEntry.validatorPoP, + newEntry.attesterWeight, + nodeEntries[0].attesterPubKey, + { gasLimit } + ) + ).to.be.reverted; + }); + + it("Should return attester committee once committed to", async function () { + // Verify that committee was not committed to. + expect((await registry.getAttesterCommittee()).length).to.equal(0); + + // Commit. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + + // Read committee. + const attesterCommittee = await registry.getAttesterCommittee(); + expect(attesterCommittee.length).to.equal(nodes.length); + for (let i = 0; i < attesterCommittee.length; i++) { + const entry = nodeEntries[i]; + const attester = attesterCommittee[i]; + expect(attester.weight).to.equal(entry.attesterWeight); + expect(attester.pubKey.tag).to.equal(entry.attesterPubKey.tag); + expect(attester.pubKey.x).to.equal(entry.attesterPubKey.x); + } + }); + + it("Should return validator committee once committed to", async function () { + // Verify that committee was not committed to. + expect((await registry.getValidatorCommittee()).length).to.equal(0); + + // Commit. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + + // Read committee. + const validatorCommittee = await registry.getValidatorCommittee(); + expect(validatorCommittee.length).to.equal(nodes.length); + for (let i = 0; i < validatorCommittee.length; i++) { + const entry = nodeEntries[i]; + const validator = validatorCommittee[i]; + expect(validator.weight).to.equal(entry.validatorWeight); + expect(validator.pubKey.a).to.equal(entry.validatorPubKey.a); + expect(validator.pubKey.b).to.equal(entry.validatorPubKey.b); + expect(validator.pubKey.c).to.equal(entry.validatorPubKey.c); + expect(validator.proofOfPossession.a).to.equal(entry.validatorPoP.a); + expect(validator.proofOfPossession.b).to.equal(entry.validatorPoP.b); + } + }); + + it("Should not include inactive nodes in attester and validator committees when committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Deactivate attribute. + await (await registry.deactivate(entry.ownerAddr, { gasLimit })).wait(); + + // Verify no change. + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit attester committee and verify. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit validator committee and verify. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length - 1); + + // Restore state. + await (await registry.activate(entry.ownerAddr, { gasLimit })).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + it("Should not include removed nodes in attester and validator committees when committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Remove node. + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + + // Verify no change. + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit attester committee and verify. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit validator committee and verify. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length - 1); + + // Restore state. + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + await ( + await registry.add( + entry.ownerAddr, + entry.validatorWeight, + entry.validatorPubKey, + entry.validatorPoP, + entry.attesterWeight, + entry.attesterPubKey + ) + ).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + it("Should not include node attribute change in attester committee before committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Change attribute. + await (await registry.changeAttesterWeight(entry.ownerAddr, entry.attesterWeight + 1, { gasLimit })).wait(); + + // Verify no change. + const attester = (await registry.getAttesterCommittee())[idx]; + expect(attester.weight).to.equal(entry.attesterWeight); + + // Commit. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + + // Verify change. + const committedAttester = (await registry.getAttesterCommittee())[idx]; + expect(committedAttester.weight).to.equal(entry.attesterWeight + 1); + + // Restore state. + await (await registry.changeAttesterWeight(entry.ownerAddr, entry.attesterWeight, { gasLimit })).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + }); + + it("Should not include node attribute change in validator committee before committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Change attribute. + await (await registry.changeValidatorWeight(entry.ownerAddr, entry.attesterWeight + 1, { gasLimit })).wait(); + + // Verify no change. + const validator = (await registry.getValidatorCommittee())[idx]; + expect(validator.weight).to.equal(entry.validatorWeight); + + // Commit. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + + // Verify change. + const committedValidator = (await registry.getValidatorCommittee())[idx]; + expect(committedValidator.weight).to.equal(entry.validatorWeight + 1); + + // Restore state. + await (await registry.changeValidatorWeight(entry.ownerAddr, entry.validatorWeight, { gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + it("Should finalize node removal by fully deleting it from storage", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Remove. + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.removed).to.equal(false); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.removed).to.equal(false); + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.removed).to.equal(true); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.removed).to.equal(true); + + // Commit committees. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + + // Verify node was not yet deleted. + expect(await registry.numNodes()).to.equal(nodes.length); + const attesterPubKeyHash = hashAttesterPubKey(entry.attesterPubKey); + expect(await registry.attesterPubKeyHashes(attesterPubKeyHash)).to.be.equal(true); + const validatorPubKeyHash = hashValidatorPubKey(entry.validatorPubKey); + expect(await registry.validatorPubKeyHashes(validatorPubKeyHash)).to.be.equal(true); + + // Trigger node deletion. + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + + // Verify the deletion. + expect(await registry.numNodes()).to.equal(nodes.length - 1); + expect(await registry.attesterPubKeyHashes(attesterPubKeyHash)).to.be.equal(false); + expect(await registry.validatorPubKeyHashes(attesterPubKeyHash)).to.be.equal(false); + const node = await registry.nodes(entry.ownerAddr, { gasLimit }); + expect(ethers.utils.arrayify(node.attesterLatest.pubKey.tag)).to.deep.equal(new Uint8Array(1)); + expect(ethers.utils.arrayify(node.attesterLatest.pubKey.x)).to.deep.equal(new Uint8Array(32)); + + // Restore state. + await ( + await registry.add( + entry.ownerAddr, + entry.validatorWeight, + entry.validatorPubKey, + entry.validatorPoP, + entry.attesterWeight, + entry.attesterPubKey + ) + ).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + function makeRandomNode() { + return { + ownerKey: new Wallet(Wallet.createRandom().privateKey, provider), + validatorKey: Wallet.createRandom(), + attesterKey: Wallet.createRandom(), + }; + } + + function makeRandomNodeEntry(node, weight: number) { + return { + ownerAddr: node.ownerKey.address, + validatorWeight: weight, + validatorPubKey: getRandomValidatorPubKey(), + validatorPoP: getRandomValidatorPoP(), + attesterWeight: weight, + attesterPubKey: getRandomAttesterPubKey(), + }; + } +}); + +function getRandomNumber(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function getRandomValidatorPubKey() { + return { + a: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + b: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + c: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + }; +} + +function getRandomValidatorPoP() { + return { + a: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + b: ethers.utils.hexlify(ethers.utils.randomBytes(16)), + }; +} + +function getRandomAttesterPubKey() { + return { + tag: ethers.utils.hexlify(ethers.utils.randomBytes(1)), + x: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + }; +} + +function hashAttesterPubKey(attesterPubKey) { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode(["bytes1", "bytes32"], [attesterPubKey.tag, attesterPubKey.x]) + ); +} + +function hashValidatorPubKey(validatorPubKey) { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["bytes32", "bytes32", "bytes32"], + [validatorPubKey.a, validatorPubKey.b, validatorPubKey.c] + ) + ); +} From 2c8a5fa32249e711ca0bfb3deaca0d60311eb325 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Tue, 20 Aug 2024 11:58:11 +0200 Subject: [PATCH 26/42] Revert: "feat(consensus): add L2 registry contract (BFT-434)" (#717) --- l2-contracts/contracts/ConsensusRegistry.sol | 486 ----------------- .../interfaces/IConsensusRegistry.sol | 161 ------ l2-contracts/package.json | 3 +- l2-contracts/src/deploy-consensus-registry.ts | 90 ---- l2-contracts/src/utils.ts | 21 - l2-contracts/test/consensusRegistry.test.ts | 499 ------------------ 6 files changed, 1 insertion(+), 1259 deletions(-) delete mode 100644 l2-contracts/contracts/ConsensusRegistry.sol delete mode 100644 l2-contracts/contracts/interfaces/IConsensusRegistry.sol delete mode 100644 l2-contracts/src/deploy-consensus-registry.ts delete mode 100644 l2-contracts/test/consensusRegistry.test.ts diff --git a/l2-contracts/contracts/ConsensusRegistry.sol b/l2-contracts/contracts/ConsensusRegistry.sol deleted file mode 100644 index 514a4f205..000000000 --- a/l2-contracts/contracts/ConsensusRegistry.sol +++ /dev/null @@ -1,486 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {IConsensusRegistry} from "./interfaces/IConsensusRegistry.sol"; - -/// @author Matter Labs -/// @custom:security-contact security@matterlabs.dev -/// @title ConsensusRegistry -/// @dev Manages consensus nodes and committees for the L2 consensus protocol, -/// owned by Matter Labs Multisig. Nodes act as both validators and attesters, -/// each playing a distinct role in the consensus process. This contract facilitates -/// the rotation of validator and attester committees, which represent a subset of nodes -/// expected to actively participate in the consensus process during a specific time window. -/// @dev Designed for use with a proxy for upgradability. -contract ConsensusRegistry is IConsensusRegistry, Initializable, Ownable2StepUpgradeable { - /// @dev An array to keep track of node owners. - address[] public nodeOwners; - /// @dev A mapping of node owners => nodes. - mapping(address => Node) public nodes; - /// @dev A mapping for enabling efficient lookups when checking whether a given attester public key exists. - mapping(bytes32 => bool) public attesterPubKeyHashes; - /// @dev A mapping for enabling efficient lookups when checking whether a given validator public key exists. - mapping(bytes32 => bool) public validatorPubKeyHashes; - /// @dev Counter that increments with each new commit to the attester committee. - uint32 public attestersCommit; - /// @dev Counter that increments with each new commit to the validator committee. - uint32 public validatorsCommit; - - modifier onlyOwnerOrNodeOwner(address _nodeOwner) { - if (owner() != msg.sender && _nodeOwner != msg.sender) { - revert UnauthorizedOnlyOwnerOrNodeOwner(); - } - _; - } - - function initialize(address _initialOwner) external initializer { - if (_initialOwner == address(0)) { - revert InvalidInputNodeOwnerAddress(); - } - _transferOwnership(_initialOwner); - } - - /// @notice Adds a new node to the registry. - /// @dev Fails if node owner already exists. - /// @dev Fails if a validator/attester with the same public key already exists. - /// @param _nodeOwner The address of the new node's owner. - /// @param _validatorWeight The voting weight of the validator. - /// @param _validatorPubKey The BLS12-381 public key of the validator. - /// @param _validatorPoP The proof-of-possession (PoP) of the validator's public key. - /// @param _attesterWeight The voting weight of the attester. - /// @param _attesterPubKey The ECDSA public key of the attester. - function add( - address _nodeOwner, - uint32 _validatorWeight, - BLS12_381PublicKey calldata _validatorPubKey, - BLS12_381Signature calldata _validatorPoP, - uint32 _attesterWeight, - Secp256k1PublicKey calldata _attesterPubKey - ) external onlyOwner { - // Verify input. - _verifyInputAddress(_nodeOwner); - _verifyInputBLS12_381PublicKey(_validatorPubKey); - _verifyInputBLS12_381Signature(_validatorPoP); - _verifyInputSecp256k1PublicKey(_attesterPubKey); - - // Verify storage. - _verifyNodeOwnerDoesNotExist(_nodeOwner); - bytes32 attesterPubKeyHash = _hashAttesterPubKey(_attesterPubKey); - _verifyAttesterPubKeyDoesNotExist(attesterPubKeyHash); - bytes32 validatorPubKeyHash = _hashValidatorPubKey(_validatorPubKey); - _verifyValidatorPubKeyDoesNotExist(validatorPubKeyHash); - - uint32 nodeOwnerIdx = uint32(nodeOwners.length); - nodeOwners.push(_nodeOwner); - nodes[_nodeOwner] = Node({ - attesterLatest: AttesterAttr({ - active: true, - removed: false, - weight: _attesterWeight, - pubKey: _attesterPubKey - }), - attesterSnapshot: AttesterAttr({ - active: false, - removed: false, - weight: 0, - pubKey: Secp256k1PublicKey({tag: bytes1(0), x: bytes32(0)}) - }), - attesterLastUpdateCommit: attestersCommit, - validatorLatest: ValidatorAttr({ - active: true, - removed: false, - weight: _validatorWeight, - pubKey: _validatorPubKey, - proofOfPossession: _validatorPoP - }), - validatorSnapshot: ValidatorAttr({ - active: false, - removed: false, - weight: 0, - pubKey: BLS12_381PublicKey({a: bytes32(0), b: bytes32(0), c: bytes32(0)}), - proofOfPossession: BLS12_381Signature({a: bytes32(0), b: bytes16(0)}) - }), - validatorLastUpdateCommit: validatorsCommit, - nodeOwnerIdx: nodeOwnerIdx - }); - attesterPubKeyHashes[attesterPubKeyHash] = true; - validatorPubKeyHashes[validatorPubKeyHash] = true; - - emit NodeAdded({ - nodeOwner: _nodeOwner, - validatorWeight: _validatorWeight, - validatorPubKey: _validatorPubKey, - validatorPoP: _validatorPoP, - attesterWeight: _attesterWeight, - attesterPubKey: _attesterPubKey - }); - } - - /// @notice Deactivates a node, preventing it from participating in committees. - /// @dev Only callable by the contract owner or the node owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner to be inactivated. - function deactivate(address _nodeOwner) external onlyOwnerOrNodeOwner(_nodeOwner) { - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - _ensureAttesterSnapshot(node); - node.attesterLatest.active = false; - _ensureValidatorSnapshot(node); - node.validatorLatest.active = false; - - emit NodeDeactivated(_nodeOwner); - } - - /// @notice Activates a previously inactive node, allowing it to participate in committees. - /// @dev Only callable by the contract owner or the node owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner to be activated. - function activate(address _nodeOwner) external onlyOwnerOrNodeOwner(_nodeOwner) { - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - _ensureAttesterSnapshot(node); - node.attesterLatest.active = true; - _ensureValidatorSnapshot(node); - node.validatorLatest.active = true; - - emit NodeActivated(_nodeOwner); - } - - /// @notice Removes a node from the registry. - /// @dev Only callable by the contract owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner to be removed. - function remove(address _nodeOwner) external onlyOwner { - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - _ensureAttesterSnapshot(node); - node.attesterLatest.removed = true; - _ensureValidatorSnapshot(node); - node.validatorLatest.removed = true; - - emit NodeRemoved(_nodeOwner); - } - - /// @notice Changes the validator weight of a node in the registry. - /// @dev Only callable by the contract owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner whose validator weight will be changed. - /// @param _weight The new validator weight to assign to the node. - function changeValidatorWeight(address _nodeOwner, uint32 _weight) external onlyOwner { - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - _ensureValidatorSnapshot(node); - node.validatorLatest.weight = _weight; - - emit NodeValidatorWeightChanged(_nodeOwner, _weight); - } - - /// @notice Changes the attester weight of a node in the registry. - /// @dev Only callable by the contract owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner whose attester weight will be changed. - /// @param _weight The new attester weight to assign to the node. - function changeAttesterWeight(address _nodeOwner, uint32 _weight) external onlyOwner { - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - _ensureAttesterSnapshot(node); - node.attesterLatest.weight = _weight; - - emit NodeAttesterWeightChanged(_nodeOwner, _weight); - } - - /// @notice Changes the validator's public key and proof-of-possession in the registry. - /// @dev Only callable by the contract owner or the node owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner whose validator key and PoP will be changed. - /// @param _pubKey The new BLS12-381 public key to assign to the node's validator. - /// @param _pop The new proof-of-possession (PoP) to assign to the node's validator. - function changeValidatorKey( - address _nodeOwner, - BLS12_381PublicKey calldata _pubKey, - BLS12_381Signature calldata _pop - ) external onlyOwnerOrNodeOwner(_nodeOwner) { - _verifyInputBLS12_381PublicKey(_pubKey); - _verifyInputBLS12_381Signature(_pop); - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - bytes32 prevHash = _hashValidatorPubKey(node.validatorLatest.pubKey); - delete validatorPubKeyHashes[prevHash]; - bytes32 newHash = _hashValidatorPubKey(_pubKey); - _verifyValidatorPubKeyDoesNotExist(newHash); - validatorPubKeyHashes[newHash] = true; - _ensureValidatorSnapshot(node); - node.validatorLatest.pubKey = _pubKey; - node.validatorLatest.proofOfPossession = _pop; - - emit NodeValidatorKeyChanged(_nodeOwner, _pubKey, _pop); - } - - /// @notice Changes the attester's public key of a node in the registry. - /// @dev Only callable by the contract owner or the node owner. - /// @dev Verifies that the node owner exists in the registry. - /// @param _nodeOwner The address of the node's owner whose attester public key will be changed. - /// @param _pubKey The new ECDSA public key to assign to the node's attester. - function changeAttesterKey( - address _nodeOwner, - Secp256k1PublicKey calldata _pubKey - ) external onlyOwnerOrNodeOwner(_nodeOwner) { - _verifyInputSecp256k1PublicKey(_pubKey); - _verifyNodeOwnerExists(_nodeOwner); - (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); - if (deleted) { - return; - } - - bytes32 prevHash = _hashAttesterPubKey(node.attesterLatest.pubKey); - delete attesterPubKeyHashes[prevHash]; - bytes32 newHash = _hashAttesterPubKey(_pubKey); - _verifyAttesterPubKeyDoesNotExist(newHash); - attesterPubKeyHashes[newHash] = true; - - _ensureAttesterSnapshot(node); - node.attesterLatest.pubKey = _pubKey; - - emit NodeAttesterKeyChanged(_nodeOwner, _pubKey); - } - - /// @notice Adds a new commit to the attester committee. - /// @dev Implicitly updates the attester committee by affecting readers based on the current state of a node's attester attributes: - /// - If "attestersCommit" > "node.attesterLastUpdateCommit", read "node.attesterLatest". - /// - If "attestersCommit" == "node.attesterLastUpdateCommit", read "node.attesterSnapshot". - /// @dev Only callable by the contract owner. - function commitAttesterCommittee() external onlyOwner { - ++attestersCommit; - - emit AttestersCommitted(attestersCommit); - } - - /// @notice Adds a new commit to the validator committee. - /// @dev Implicitly updates the validator committee by affecting readers based on the current state of a node's validator attributes: - /// - If "validatorsCommit" > "node.validatorLastUpdateCommit", read "node.validatorLatest". - /// - If "validatorsCommit" == "node.validatorLastUpdateCommit", read "node.validatorSnapshot". - /// @dev Only callable by the contract owner. - function commitValidatorCommittee() external onlyOwner { - ++validatorsCommit; - - emit ValidatorsCommitted(validatorsCommit); - } - - /// @notice Returns an array of `AttesterAttr` structs representing the current attester committee. - /// @dev Collects active and non-removed attesters based on the latest commit to the committee. - function getAttesterCommittee() public view returns (CommitteeAttester[] memory) { - uint256 len = nodeOwners.length; - CommitteeAttester[] memory committee = new CommitteeAttester[](len); - uint256 count = 0; - - for (uint256 i = 0; i < len; ++i) { - Node storage node = nodes[nodeOwners[i]]; - AttesterAttr memory attester = attestersCommit > node.attesterLastUpdateCommit - ? node.attesterLatest - : node.attesterSnapshot; - if (attester.active && !attester.removed) { - committee[count] = CommitteeAttester({weight: attester.weight, pubKey: attester.pubKey}); - ++count; - } - } - - // Resize the array. - assembly { - mstore(committee, count) - } - return committee; - } - - /// @notice Returns an array of `ValidatorAttr` structs representing the current attester committee. - /// @dev Collects active and non-removed validators based on the latest commit to the committee. - function getValidatorCommittee() public view returns (CommitteeValidator[] memory) { - uint256 len = nodeOwners.length; - CommitteeValidator[] memory committee = new CommitteeValidator[](len); - uint256 count = 0; - - for (uint256 i = 0; i < len; ++i) { - Node storage node = nodes[nodeOwners[i]]; - ValidatorAttr memory validator = validatorsCommit > node.validatorLastUpdateCommit - ? node.validatorLatest - : node.validatorSnapshot; - if (validator.active && !validator.removed) { - committee[count] = CommitteeValidator({ - weight: validator.weight, - pubKey: validator.pubKey, - proofOfPossession: validator.proofOfPossession - }); - ++count; - } - } - - // Resize the array. - assembly { - mstore(committee, count) - } - return committee; - } - - function numNodes() public view returns (uint256) { - return nodeOwners.length; - } - - function _getNodeAndDeleteIfRequired(address _nodeOwner) private returns (Node storage, bool) { - Node storage node = nodes[_nodeOwner]; - bool pendingDeletion = _isNodePendingDeletion(node); - if (pendingDeletion) { - _deleteNode(_nodeOwner, node); - } - return (node, pendingDeletion); - } - - function _isNodePendingDeletion(Node storage _node) private returns (bool) { - bool attesterRemoved = (attestersCommit > _node.attesterLastUpdateCommit) - ? _node.attesterLatest.removed - : _node.attesterSnapshot.removed; - bool validatorRemoved = (validatorsCommit > _node.validatorLastUpdateCommit) - ? _node.validatorLatest.removed - : _node.validatorSnapshot.removed; - return attesterRemoved && validatorRemoved; - } - - function _deleteNode(address _nodeOwner, Node storage _node) private { - // Delete from array by swapping the last node owner (gas-efficient, not preserving order). - address lastNodeOwner = nodeOwners[nodeOwners.length - 1]; - nodeOwners[_node.nodeOwnerIdx] = lastNodeOwner; - nodeOwners.pop(); - // Update the node owned by the last node owner. - nodes[lastNodeOwner].nodeOwnerIdx = _node.nodeOwnerIdx; - - // Delete from the remaining mapping. - delete attesterPubKeyHashes[_hashAttesterPubKey(_node.attesterLatest.pubKey)]; - delete validatorPubKeyHashes[_hashValidatorPubKey(_node.validatorLatest.pubKey)]; - delete nodes[_nodeOwner]; - - emit NodeDeleted(_nodeOwner); - } - - function _ensureAttesterSnapshot(Node storage _node) private { - if (_node.attesterLastUpdateCommit < attestersCommit) { - _node.attesterSnapshot = _node.attesterLatest; - _node.attesterLastUpdateCommit = attestersCommit; - } - } - - function _ensureValidatorSnapshot(Node storage _node) private { - if (_node.validatorLastUpdateCommit < validatorsCommit) { - _node.validatorSnapshot = _node.validatorLatest; - _node.validatorLastUpdateCommit = validatorsCommit; - } - } - - function _isNodeOwnerExists(address _nodeOwner) private view returns (bool) { - BLS12_381PublicKey storage pubKey = nodes[_nodeOwner].validatorLatest.pubKey; - if (pubKey.a == bytes32(0) && pubKey.b == bytes32(0) && pubKey.c == bytes32(0)) { - return false; - } - return true; - } - - function _verifyNodeOwnerExists(address _nodeOwner) private view { - if (!_isNodeOwnerExists(_nodeOwner)) { - revert NodeOwnerDoesNotExist(); - } - } - - function _verifyNodeOwnerDoesNotExist(address _nodeOwner) private view { - if (_isNodeOwnerExists(_nodeOwner)) { - revert NodeOwnerExists(); - } - } - - function _hashAttesterPubKey(Secp256k1PublicKey storage _pubKey) private view returns (bytes32) { - return keccak256(abi.encode(_pubKey.tag, _pubKey.x)); - } - - function _hashAttesterPubKey(Secp256k1PublicKey calldata _pubKey) private pure returns (bytes32) { - return keccak256(abi.encode(_pubKey.tag, _pubKey.x)); - } - - function _hashValidatorPubKey(BLS12_381PublicKey storage _pubKey) private view returns (bytes32) { - return keccak256(abi.encode(_pubKey.a, _pubKey.b, _pubKey.c)); - } - - function _hashValidatorPubKey(BLS12_381PublicKey calldata _pubKey) private pure returns (bytes32) { - return keccak256(abi.encode(_pubKey.a, _pubKey.b, _pubKey.c)); - } - - function _verifyInputAddress(address _nodeOwner) private pure { - if (_nodeOwner == address(0)) { - revert InvalidInputNodeOwnerAddress(); - } - } - - function _verifyAttesterPubKeyDoesNotExist(bytes32 _hash) private view { - if (attesterPubKeyHashes[_hash]) { - revert AttesterPubKeyExists(); - } - } - - function _verifyValidatorPubKeyDoesNotExist(bytes32 _hash) private { - if (validatorPubKeyHashes[_hash]) { - revert ValidatorPubKeyExists(); - } - } - - function _verifyInputBLS12_381PublicKey(BLS12_381PublicKey calldata _pubKey) private pure { - if (_isEmptyBLS12_381PublicKey(_pubKey)) { - revert InvalidInputBLS12_381PublicKey(); - } - } - - function _verifyInputBLS12_381Signature(BLS12_381Signature calldata _pop) private pure { - if (_isEmptyBLS12_381Signature(_pop)) { - revert InvalidInputBLS12_381Signature(); - } - } - - function _verifyInputSecp256k1PublicKey(Secp256k1PublicKey calldata _pubKey) private pure { - if (_isEmptySecp256k1PublicKey(_pubKey)) { - revert InvalidInputSecp256k1PublicKey(); - } - } - - function _isEmptyBLS12_381PublicKey(BLS12_381PublicKey calldata _pubKey) private pure returns (bool) { - return _pubKey.a == bytes32(0) && _pubKey.b == bytes32(0) && _pubKey.c == bytes32(0); - } - - function _isEmptyBLS12_381Signature(BLS12_381Signature calldata _pop) private pure returns (bool) { - return _pop.a == bytes32(0) && _pop.b == bytes16(0); - } - - function _isEmptySecp256k1PublicKey(Secp256k1PublicKey calldata _pubKey) private pure returns (bool) { - return _pubKey.tag == bytes1(0) && _pubKey.x == bytes32(0); - } -} diff --git a/l2-contracts/contracts/interfaces/IConsensusRegistry.sol b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol deleted file mode 100644 index e3ddd118a..000000000 --- a/l2-contracts/contracts/interfaces/IConsensusRegistry.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; - -/// @author Matter Labs -/// @custom:security-contact security@matterlabs.dev -/// @title ConsensusRegistry contract interface -interface IConsensusRegistry { - /// @dev Represents a consensus node. - /// @param attesterLastUpdateCommit The latest `attestersCommit` where the node's attester attributes were updated. - /// @param attesterLatest Attester attributes to read if `node.attesterLastUpdateCommit` < `attestersCommit`. - /// @param attesterSnapshot Attester attributes to read if `node.attesterLastUpdateCommit` == `attestersCommit`. - /// @param validatorLastUpdateCommit The latest `validatorsCommit` where the node's validator attributes were updated. - /// @param validatorLatest Validator attributes to read if `node.validatorLastUpdateCommit` < `validatorsCommit`. - /// @param validatorSnapshot Validator attributes to read if `node.validatorLastUpdateCommit` == `validatorsCommit`. - /// @param nodeOwnerIdx Index of the node owner within the array of node owners. - struct Node { - uint32 attesterLastUpdateCommit; - uint32 validatorLastUpdateCommit; - uint32 nodeOwnerIdx; - AttesterAttr attesterLatest; - AttesterAttr attesterSnapshot; - ValidatorAttr validatorLatest; - ValidatorAttr validatorSnapshot; - } - - /// @dev Represents the attester attributes of a consensus node. - /// @param active A flag stating if the attester is active. - /// @param removed A flag stating if the attester has been removed (and is pending a deletion). - /// @param weight Attester's voting weight. - /// @param pubKey Attester's Secp256k1 public key. - struct AttesterAttr { - bool active; - bool removed; - uint32 weight; - Secp256k1PublicKey pubKey; - } - - /// @dev Represents an attester within a committee. - /// @param weight Attester's voting weight. - /// @param pubKey Attester's Secp256k1 public key. - struct CommitteeAttester { - uint32 weight; - Secp256k1PublicKey pubKey; - } - - /// @dev Represents the validator attributes of a consensus node. - /// @param active A flag stating if the validator is active. - /// @param removed A flag stating if the validator has been removed (and is pending a deletion). - /// @param weight Validator's voting weight. - /// @param pubKey Validator's BLS12-381 public key. - /// @param proofOfPossession Validator's Proof-of-possession (a signature over the public key). - struct ValidatorAttr { - bool active; - bool removed; - uint32 weight; - BLS12_381PublicKey pubKey; - BLS12_381Signature proofOfPossession; - } - - /// @dev Represents a validator within a committee. - /// @param weight Validator's voting weight. - /// @param pubKey Validator's BLS12-381 public key. - /// @param proofOfPossession Validator's Proof-of-possession (a signature over the public key). - struct CommitteeValidator { - uint32 weight; - BLS12_381PublicKey pubKey; - BLS12_381Signature proofOfPossession; - } - - /// @dev Represents BLS12_381 public key. - /// @param a First component of the BLS12-381 public key. - /// @param b Second component of the BLS12-381 public key. - /// @param c Third component of the BLS12-381 public key. - struct BLS12_381PublicKey { - bytes32 a; - bytes32 b; - bytes32 c; - } - - /// @dev Represents BLS12_381 signature. - /// @param a First component of the BLS12-381 signature. - /// @param b Second component of the BLS12-381 signature. - struct BLS12_381Signature { - bytes32 a; - bytes16 b; - } - - /// @dev Represents Secp256k1 public key. - /// @param tag Y-coordinate's even/odd indicator of the Secp256k1 public key. - /// @param x X-coordinate component of the Secp256k1 public key. - struct Secp256k1PublicKey { - bytes1 tag; - bytes32 x; - } - - error UnauthorizedOnlyOwnerOrNodeOwner(); - error NodeOwnerExists(); - error NodeOwnerDoesNotExist(); - error NodeOwnerNotFound(); - error ValidatorPubKeyExists(); - error AttesterPubKeyExists(); - error InvalidInputNodeOwnerAddress(); - error InvalidInputBLS12_381PublicKey(); - error InvalidInputBLS12_381Signature(); - error InvalidInputSecp256k1PublicKey(); - - event NodeAdded( - address indexed nodeOwner, - uint32 validatorWeight, - BLS12_381PublicKey validatorPubKey, - BLS12_381Signature validatorPoP, - uint32 attesterWeight, - Secp256k1PublicKey attesterPubKey - ); - event NodeDeactivated(address indexed nodeOwner); - event NodeActivated(address indexed nodeOwner); - event NodeRemoved(address indexed nodeOwner); - event NodeDeleted(address indexed nodeOwner); - event NodeValidatorWeightChanged(address indexed nodeOwner, uint32 newWeight); - event NodeAttesterWeightChanged(address indexed nodeOwner, uint32 newWeight); - event NodeValidatorKeyChanged(address indexed nodeOwner, BLS12_381PublicKey newPubKey, BLS12_381Signature newPoP); - event NodeAttesterKeyChanged(address indexed nodeOwner, Secp256k1PublicKey newPubKey); - event ValidatorsCommitted(uint32 commit); - event AttestersCommitted(uint32 commit); - - function add( - address _nodeOwner, - uint32 _validatorWeight, - BLS12_381PublicKey calldata _validatorPubKey, - BLS12_381Signature calldata _validatorPoP, - uint32 _attesterWeight, - Secp256k1PublicKey calldata _attesterPubKey - ) external; - - function deactivate(address _nodeOwner) external; - - function activate(address _nodeOwner) external; - - function remove(address _nodeOwner) external; - - function changeValidatorWeight(address _nodeOwner, uint32 _weight) external; - - function changeAttesterWeight(address _nodeOwner, uint32 _weight) external; - - function changeValidatorKey( - address _nodeOwner, - BLS12_381PublicKey calldata _pubKey, - BLS12_381Signature calldata _pop - ) external; - - function changeAttesterKey(address _nodeOwner, Secp256k1PublicKey calldata _pubKey) external; - - function commitAttesterCommittee() external; - - function commitValidatorCommittee() external; - - function getAttesterCommittee() external view returns (CommitteeAttester[] memory); - - function getValidatorCommittee() external view returns (CommitteeValidator[] memory); -} diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 00dd00457..a9dfc2779 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -42,8 +42,7 @@ "deploy-l2-weth": "ts-node src/deploy-l2-weth.ts", "upgrade-bridge-contracts": "ts-node src/upgrade-bridge-impl.ts", "update-l2-erc20-metadata": "ts-node src/update-l2-erc20-metadata.ts", - "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts", - "deploy-consensus-registry": "ts-node src/deploy-consensus-registry.ts" + "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts" }, "dependencies": { "dotenv": "^16.0.3" diff --git a/l2-contracts/src/deploy-consensus-registry.ts b/l2-contracts/src/deploy-consensus-registry.ts deleted file mode 100644 index ffbf903f9..000000000 --- a/l2-contracts/src/deploy-consensus-registry.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Command } from "commander"; -import { ethers } from "ethers"; -import { computeL2Create2Address, create2DeployFromL2 } from "./utils"; -import { Interface } from "ethers/lib/utils"; -import { ethTestConfig } from "./deploy-utils"; - -import * as hre from "hardhat"; -import { Provider, Wallet } from "zksync-ethers"; - -const I_TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT = hre.artifacts.readArtifactSync("ITransparentUpgradeableProxy"); -const TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT = hre.artifacts.readArtifactSync("TransparentUpgradeableProxy"); -const CONSENSUS_REGISTRY_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); -const PROXY_ADMIN_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); - -const CONSENSUS_REGISTRY_INTERFACE = new Interface(CONSENSUS_REGISTRY_ARTIFACT.abi); -const I_TRANSPARENT_UPGRADEABLE_PROXY_INTERFACE = new Interface(I_TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.abi); - -// Script to deploy the consensus registry contract and output its address. -// Note, that this script expects that the L2 contracts have been compiled PRIOR -// to running this script. -async function main() { - const program = new Command(); - - program - .version("0.1.0") - .name("deploy-consensus-registry") - .description("Deploys the consensus registry contract to L2"); - - program.option("--private-key ").action(async (cmd) => { - const zksProvider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, zksProvider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(zksProvider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - // Deploy Consensus Registry contract - const consensusRegistryImplementation = await computeL2Create2Address( - deployWallet, - CONSENSUS_REGISTRY_ARTIFACT.bytecode, - "0x", - ethers.constants.HashZero - ); - await create2DeployFromL2(deployWallet, CONSENSUS_REGISTRY_ARTIFACT.bytecode, "0x", ethers.constants.HashZero); - - // Deploy Proxy Admin contract - const proxyAdminContract = await computeL2Create2Address( - deployWallet, - PROXY_ADMIN_ARTIFACT.bytecode, - "0x", - ethers.constants.HashZero - ); - await create2DeployFromL2(deployWallet, PROXY_ADMIN_ARTIFACT.bytecode, "0x", ethers.constants.HashZero); - - const proxyInitializationParams = CONSENSUS_REGISTRY_INTERFACE.encodeFunctionData("initialize", [ - deployWallet.address, - ]); - const proxyConstructor = I_TRANSPARENT_UPGRADEABLE_PROXY_INTERFACE.encodeDeploy([ - consensusRegistryImplementation, - proxyAdminContract, - proxyInitializationParams, - ]); - - await create2DeployFromL2( - deployWallet, - TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.bytecode, - proxyConstructor, - ethers.constants.HashZero - ); - - const address = computeL2Create2Address( - deployWallet, - TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.bytecode, - proxyConstructor, - ethers.constants.HashZero - ); - console.log(`CONTRACTS_L2_CONSENSUS_REGISTRY_ADDR=${address}`); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/l2-contracts/src/utils.ts b/l2-contracts/src/utils.ts index 0a479a540..c77817a0b 100644 --- a/l2-contracts/src/utils.ts +++ b/l2-contracts/src/utils.ts @@ -143,27 +143,6 @@ export async function create2DeployFromL1( ); } -export async function create2DeployFromL2( - wallet: ethers.Wallet, - bytecode: ethers.BytesLike, - constructor: ethers.BytesLike, - create2Salt: ethers.BytesLike, - extraFactoryDeps?: ethers.BytesLike[] -) { - const deployerSystemContracts = new Interface(artifacts.readArtifactSync("IContractDeployer").abi); - const bytecodeHash = hashL2Bytecode(bytecode); - const calldata = deployerSystemContracts.encodeFunctionData("create2", [create2Salt, bytecodeHash, constructor]); - - const factoryDeps = extraFactoryDeps ? [bytecode, ...extraFactoryDeps] : [bytecode]; - return await wallet.call({ - to: DEPLOYER_SYSTEM_CONTRACT_ADDRESS, - data: calldata, - customData: { - factoryDeps, - }, - }); -} - export async function publishBytecodeFromL1( chainId: ethers.BigNumberish, wallet: ethers.Wallet, diff --git a/l2-contracts/test/consensusRegistry.test.ts b/l2-contracts/test/consensusRegistry.test.ts deleted file mode 100644 index 66c0309bd..000000000 --- a/l2-contracts/test/consensusRegistry.test.ts +++ /dev/null @@ -1,499 +0,0 @@ -import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; -import * as hre from "hardhat"; -import { Provider, Wallet } from "zksync-ethers"; -import type { ConsensusRegistry } from "../typechain"; -import { ConsensusRegistryFactory } from "../typechain"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import { Interface } from "ethers/lib/utils"; - -const richAccount = { - address: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", - privateKey: "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110", -}; - -const gasLimit = 100_000_000; - -const CONSENSUS_REGISTRY_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); -const CONSENSUS_REGISTRY_INTERFACE = new Interface(CONSENSUS_REGISTRY_ARTIFACT.abi); - -describe("ConsensusRegistry", function () { - const provider = new Provider(hre.config.networks.localhost.url); - const owner = new Wallet(richAccount.privateKey, provider); - const nonOwner = new Wallet(Wallet.createRandom().privateKey, provider); - const nodes = []; - const nodeEntries = []; - let registry: ConsensusRegistry; - - before("Initialize", async function () { - // Deploy. - const deployer = new Deployer(hre, owner); - const registryInstance = await deployer.deploy(await deployer.loadArtifact("ConsensusRegistry"), []); - const proxyAdmin = await deployer.deploy(await deployer.loadArtifact("ProxyAdmin"), []); - const proxyInitializationParams = CONSENSUS_REGISTRY_INTERFACE.encodeFunctionData("initialize", [owner.address]); - const proxyInstance = await deployer.deploy(await deployer.loadArtifact("TransparentUpgradeableProxy"), [ - registryInstance.address, - proxyAdmin.address, - proxyInitializationParams, - ]); - registry = ConsensusRegistryFactory.connect(proxyInstance.address, owner); - - // Fund nonOwner. - await ( - await owner.sendTransaction({ - to: nonOwner.address, - value: ethers.utils.parseEther("100"), - }) - ).wait(); - - // Prepare the node list. - const numNodes = 10; - for (let i = 0; i < numNodes; i++) { - const node = makeRandomNode(provider); - const nodeEntry = makeRandomNodeEntry(node, i); - nodes.push(node); - nodeEntries.push(nodeEntry); - } - - // Fund the first node owner. - await ( - await owner.sendTransaction({ - to: nodes[0].ownerKey.address, - value: ethers.utils.parseEther("100"), - }) - ).wait(); - }); - - it("Should set the owner as provided in constructor", async function () { - expect(await registry.owner()).to.equal(owner.address); - }); - - it("Should add nodes to both registries", async function () { - for (let i = 0; i < nodes.length; i++) { - await ( - await registry.add( - nodeEntries[i].ownerAddr, - nodeEntries[i].validatorWeight, - nodeEntries[i].validatorPubKey, - nodeEntries[i].validatorPoP, - nodeEntries[i].attesterWeight, - nodeEntries[i].attesterPubKey - ) - ).wait(); - } - - expect(await registry.numNodes()).to.equal(nodes.length); - - for (let i = 0; i < nodes.length; i++) { - const nodeOwner = await registry.nodeOwners(i); - expect(nodeOwner).to.equal(nodeEntries[i].ownerAddr); - const node = await registry.nodes(nodeOwner); - expect(node.attesterLastUpdateCommit).to.equal(0); - expect(node.validatorLastUpdateCommit).to.equal(0); - - // 'Latest' is expected to match the added node's attributes. - expect(node.attesterLatest.active).to.equal(true); - expect(node.attesterLatest.removed).to.equal(false); - expect(node.attesterLatest.weight).to.equal(nodeEntries[i].attesterWeight); - expect(node.attesterLatest.pubKey.tag).to.equal(nodeEntries[i].attesterPubKey.tag); - expect(node.attesterLatest.pubKey.x).to.equal(nodeEntries[i].attesterPubKey.x); - expect(node.validatorLastUpdateCommit).to.equal(0); - expect(node.validatorLatest.active).to.equal(true); - expect(node.validatorLatest.removed).to.equal(false); - expect(node.validatorLatest.weight).to.equal(nodeEntries[i].attesterWeight); - expect(node.validatorLatest.pubKey.a).to.equal(nodeEntries[i].validatorPubKey.a); - expect(node.validatorLatest.pubKey.b).to.equal(nodeEntries[i].validatorPubKey.b); - expect(node.validatorLatest.pubKey.c).to.equal(nodeEntries[i].validatorPubKey.c); - expect(node.validatorLatest.proofOfPossession.a).to.equal(nodeEntries[i].validatorPoP.a); - expect(node.validatorLatest.proofOfPossession.b).to.equal(nodeEntries[i].validatorPoP.b); - - // 'Snapshot' is expected to have zero values. - expect(node.attesterSnapshot.active).to.equal(false); - expect(node.attesterSnapshot.removed).to.equal(false); - expect(node.attesterSnapshot.weight).to.equal(0); - expect(ethers.utils.arrayify(node.attesterSnapshot.pubKey.tag)).to.deep.equal(new Uint8Array(1)); - expect(ethers.utils.arrayify(node.attesterSnapshot.pubKey.x)).to.deep.equal(new Uint8Array(32)); - expect(node.validatorSnapshot.active).to.equal(false); - expect(node.validatorSnapshot.removed).to.equal(false); - expect(node.validatorSnapshot.weight).to.equal(0); - expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.a)).to.deep.equal(new Uint8Array(32)); - expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.b)).to.deep.equal(new Uint8Array(32)); - expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.c)).to.deep.equal(new Uint8Array(32)); - expect(ethers.utils.arrayify(node.validatorSnapshot.proofOfPossession.a)).to.deep.equal(new Uint8Array(32)); - expect(ethers.utils.arrayify(node.validatorSnapshot.proofOfPossession.b)).to.deep.equal(new Uint8Array(16)); - } - }); - - it("Should not allow nonOwner to add", async function () { - await expect( - registry - .connect(nonOwner) - .add( - ethers.Wallet.createRandom().address, - 0, - { a: new Uint8Array(32), b: new Uint8Array(32), c: new Uint8Array(32) }, - { a: new Uint8Array(32), b: new Uint8Array(16) }, - 0, - { tag: new Uint8Array(1), x: new Uint8Array(32) }, - { gasLimit } - ) - ).to.be.reverted; - }); - - it("Should allow owner to deactivate", async function () { - const nodeOwner = nodeEntries[0].ownerAddr; - expect((await registry.nodes(nodeOwner)).validatorLatest.active).to.equal(true); - - await (await registry.connect(owner).deactivate(nodeOwner, { gasLimit })).wait(); - expect((await registry.nodes(nodeOwner)).validatorLatest.active).to.equal(false); - - // Restore state. - await (await registry.connect(owner).activate(nodeOwner, { gasLimit })).wait(); - }); - - it("Should not allow nonOwner, nonNodeOwner to deactivate", async function () { - const nodeOwner = nodeEntries[0].ownerAddr; - await expect(registry.connect(nonOwner).deactivate(nodeOwner, { gasLimit })).to.be.reverted; - }); - - it("Should change validator weight", async function () { - const entry = nodeEntries[0]; - expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(entry.validatorWeight); - - const baseWeight = entry.validatorWeight; - const newWeight = getRandomNumber(100, 1000); - await (await registry.changeValidatorWeight(entry.ownerAddr, newWeight, { gasLimit })).wait(); - expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(newWeight); - expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(entry.attesterWeight); - - // Restore state. - await (await registry.changeValidatorWeight(entry.ownerAddr, baseWeight, { gasLimit })).wait(); - }); - - it("Should not allow nodeOwner to change validator weight", async function () { - const node = nodes[0]; - await expect(registry.connect(node.ownerKey).changeValidatorWeight(node.ownerKey.address, 0, { gasLimit })).to.be - .reverted; - }); - - it("Should not allow nonOwner to change validator weight", async function () { - const node = nodes[0]; - await expect(registry.connect(nonOwner).changeValidatorWeight(node.ownerKey.address, 0, { gasLimit })).to.be - .reverted; - }); - - it("Should change attester weight", async function () { - const entry = nodeEntries[0]; - expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(entry.attesterWeight); - - const baseWeight = entry.attesterWeight; - const newWeight = getRandomNumber(100, 1000); - await (await registry.changeAttesterWeight(entry.ownerAddr, newWeight, { gasLimit })).wait(); - expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(newWeight); - expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(entry.validatorWeight); - - // Restore state. - await (await registry.changeAttesterWeight(entry.ownerAddr, baseWeight, { gasLimit })).wait(); - }); - - it("Should not allow nodeOwner to change attester weight", async function () { - const node = nodes[0]; - await expect(registry.connect(node.ownerKey).changeAttesterWeight(node.ownerKey.address, 0, { gasLimit })).to.be - .reverted; - }); - - it("Should not allow nonOwner to change attester weight", async function () { - const node = nodes[0]; - await expect(registry.connect(nonOwner).changeAttesterWeight(node.ownerKey.address, 0, { gasLimit })).to.be - .reverted; - }); - - it("Should not allow to add a node with a validator public key which already exist", async function () { - const newEntry = makeRandomNodeEntry(makeRandomNode(), 0); - await expect( - registry.add( - newEntry.ownerAddr, - newEntry.validatorWeight, - nodeEntries[0].validatorPubKey, - newEntry.validatorPoP, - newEntry.attesterWeight, - newEntry.attesterPubKey, - { gasLimit } - ) - ).to.be.reverted; - }); - - it("Should not allow to add a node with an attester public key which already exist", async function () { - const newEntry = makeRandomNodeEntry(makeRandomNode(), 0); - await expect( - registry.add( - newEntry.ownerAddr, - newEntry.validatorWeight, - newEntry.validatorPubKey, - newEntry.validatorPoP, - newEntry.attesterWeight, - nodeEntries[0].attesterPubKey, - { gasLimit } - ) - ).to.be.reverted; - }); - - it("Should return attester committee once committed to", async function () { - // Verify that committee was not committed to. - expect((await registry.getAttesterCommittee()).length).to.equal(0); - - // Commit. - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - - // Read committee. - const attesterCommittee = await registry.getAttesterCommittee(); - expect(attesterCommittee.length).to.equal(nodes.length); - for (let i = 0; i < attesterCommittee.length; i++) { - const entry = nodeEntries[i]; - const attester = attesterCommittee[i]; - expect(attester.weight).to.equal(entry.attesterWeight); - expect(attester.pubKey.tag).to.equal(entry.attesterPubKey.tag); - expect(attester.pubKey.x).to.equal(entry.attesterPubKey.x); - } - }); - - it("Should return validator committee once committed to", async function () { - // Verify that committee was not committed to. - expect((await registry.getValidatorCommittee()).length).to.equal(0); - - // Commit. - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - - // Read committee. - const validatorCommittee = await registry.getValidatorCommittee(); - expect(validatorCommittee.length).to.equal(nodes.length); - for (let i = 0; i < validatorCommittee.length; i++) { - const entry = nodeEntries[i]; - const validator = validatorCommittee[i]; - expect(validator.weight).to.equal(entry.validatorWeight); - expect(validator.pubKey.a).to.equal(entry.validatorPubKey.a); - expect(validator.pubKey.b).to.equal(entry.validatorPubKey.b); - expect(validator.pubKey.c).to.equal(entry.validatorPubKey.c); - expect(validator.proofOfPossession.a).to.equal(entry.validatorPoP.a); - expect(validator.proofOfPossession.b).to.equal(entry.validatorPoP.b); - } - }); - - it("Should not include inactive nodes in attester and validator committees when committed to", async function () { - const idx = nodeEntries.length - 1; - const entry = nodeEntries[idx]; - - // Deactivate attribute. - await (await registry.deactivate(entry.ownerAddr, { gasLimit })).wait(); - - // Verify no change. - expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length); - expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); - - // Commit attester committee and verify. - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); - expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); - - // Commit validator committee and verify. - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); - expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length - 1); - - // Restore state. - await (await registry.activate(entry.ownerAddr, { gasLimit })).wait(); - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - }); - - it("Should not include removed nodes in attester and validator committees when committed to", async function () { - const idx = nodeEntries.length - 1; - const entry = nodeEntries[idx]; - - // Remove node. - await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); - - // Verify no change. - expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length); - expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); - - // Commit attester committee and verify. - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); - expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); - - // Commit validator committee and verify. - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); - expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length - 1); - - // Restore state. - await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); - await ( - await registry.add( - entry.ownerAddr, - entry.validatorWeight, - entry.validatorPubKey, - entry.validatorPoP, - entry.attesterWeight, - entry.attesterPubKey - ) - ).wait(); - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - }); - - it("Should not include node attribute change in attester committee before committed to", async function () { - const idx = nodeEntries.length - 1; - const entry = nodeEntries[idx]; - - // Change attribute. - await (await registry.changeAttesterWeight(entry.ownerAddr, entry.attesterWeight + 1, { gasLimit })).wait(); - - // Verify no change. - const attester = (await registry.getAttesterCommittee())[idx]; - expect(attester.weight).to.equal(entry.attesterWeight); - - // Commit. - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - - // Verify change. - const committedAttester = (await registry.getAttesterCommittee())[idx]; - expect(committedAttester.weight).to.equal(entry.attesterWeight + 1); - - // Restore state. - await (await registry.changeAttesterWeight(entry.ownerAddr, entry.attesterWeight, { gasLimit })).wait(); - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - }); - - it("Should not include node attribute change in validator committee before committed to", async function () { - const idx = nodeEntries.length - 1; - const entry = nodeEntries[idx]; - - // Change attribute. - await (await registry.changeValidatorWeight(entry.ownerAddr, entry.attesterWeight + 1, { gasLimit })).wait(); - - // Verify no change. - const validator = (await registry.getValidatorCommittee())[idx]; - expect(validator.weight).to.equal(entry.validatorWeight); - - // Commit. - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - - // Verify change. - const committedValidator = (await registry.getValidatorCommittee())[idx]; - expect(committedValidator.weight).to.equal(entry.validatorWeight + 1); - - // Restore state. - await (await registry.changeValidatorWeight(entry.ownerAddr, entry.validatorWeight, { gasLimit })).wait(); - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - }); - - it("Should finalize node removal by fully deleting it from storage", async function () { - const idx = nodeEntries.length - 1; - const entry = nodeEntries[idx]; - - // Remove. - expect((await registry.nodes(entry.ownerAddr)).attesterLatest.removed).to.equal(false); - expect((await registry.nodes(entry.ownerAddr)).validatorLatest.removed).to.equal(false); - await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); - expect((await registry.nodes(entry.ownerAddr)).attesterLatest.removed).to.equal(true); - expect((await registry.nodes(entry.ownerAddr)).validatorLatest.removed).to.equal(true); - - // Commit committees. - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - - // Verify node was not yet deleted. - expect(await registry.numNodes()).to.equal(nodes.length); - const attesterPubKeyHash = hashAttesterPubKey(entry.attesterPubKey); - expect(await registry.attesterPubKeyHashes(attesterPubKeyHash)).to.be.equal(true); - const validatorPubKeyHash = hashValidatorPubKey(entry.validatorPubKey); - expect(await registry.validatorPubKeyHashes(validatorPubKeyHash)).to.be.equal(true); - - // Trigger node deletion. - await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); - - // Verify the deletion. - expect(await registry.numNodes()).to.equal(nodes.length - 1); - expect(await registry.attesterPubKeyHashes(attesterPubKeyHash)).to.be.equal(false); - expect(await registry.validatorPubKeyHashes(attesterPubKeyHash)).to.be.equal(false); - const node = await registry.nodes(entry.ownerAddr, { gasLimit }); - expect(ethers.utils.arrayify(node.attesterLatest.pubKey.tag)).to.deep.equal(new Uint8Array(1)); - expect(ethers.utils.arrayify(node.attesterLatest.pubKey.x)).to.deep.equal(new Uint8Array(32)); - - // Restore state. - await ( - await registry.add( - entry.ownerAddr, - entry.validatorWeight, - entry.validatorPubKey, - entry.validatorPoP, - entry.attesterWeight, - entry.attesterPubKey - ) - ).wait(); - await (await registry.commitAttesterCommittee({ gasLimit })).wait(); - await (await registry.commitValidatorCommittee({ gasLimit })).wait(); - }); - - function makeRandomNode() { - return { - ownerKey: new Wallet(Wallet.createRandom().privateKey, provider), - validatorKey: Wallet.createRandom(), - attesterKey: Wallet.createRandom(), - }; - } - - function makeRandomNodeEntry(node, weight: number) { - return { - ownerAddr: node.ownerKey.address, - validatorWeight: weight, - validatorPubKey: getRandomValidatorPubKey(), - validatorPoP: getRandomValidatorPoP(), - attesterWeight: weight, - attesterPubKey: getRandomAttesterPubKey(), - }; - } -}); - -function getRandomNumber(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -function getRandomValidatorPubKey() { - return { - a: ethers.utils.hexlify(ethers.utils.randomBytes(32)), - b: ethers.utils.hexlify(ethers.utils.randomBytes(32)), - c: ethers.utils.hexlify(ethers.utils.randomBytes(32)), - }; -} - -function getRandomValidatorPoP() { - return { - a: ethers.utils.hexlify(ethers.utils.randomBytes(32)), - b: ethers.utils.hexlify(ethers.utils.randomBytes(16)), - }; -} - -function getRandomAttesterPubKey() { - return { - tag: ethers.utils.hexlify(ethers.utils.randomBytes(1)), - x: ethers.utils.hexlify(ethers.utils.randomBytes(32)), - }; -} - -function hashAttesterPubKey(attesterPubKey) { - return ethers.utils.keccak256( - ethers.utils.defaultAbiCoder.encode(["bytes1", "bytes32"], [attesterPubKey.tag, attesterPubKey.x]) - ); -} - -function hashValidatorPubKey(validatorPubKey) { - return ethers.utils.keccak256( - ethers.utils.defaultAbiCoder.encode( - ["bytes32", "bytes32", "bytes32"], - [validatorPubKey.a, validatorPubKey.b, validatorPubKey.c] - ) - ); -} From 8be87b21127bdb0bc2f0895fcc736d8ce98a9cd9 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Tue, 20 Aug 2024 11:00:06 -0400 Subject: [PATCH 27/42] Merge Protocol Defense Tasks into Dev (#518) Co-authored-by: Bence Haromi --- .gitmodules | 8 +- .solhintignore | 2 +- _typos.toml | 1 + gas-bound-caller/contracts/GasBoundCaller.sol | 17 +- .../contracts/bridge/L1ERC20Bridge.sol | 40 ++- .../contracts/bridge/L1SharedBridge.sol | 208 +++++++---- .../bridge/interfaces/IL1ERC20Bridge.sol | 4 +- .../bridge/interfaces/IL1SharedBridge.sol | 4 +- .../contracts/bridge/interfaces/IL2Bridge.sol | 4 +- .../contracts/bridge/interfaces/IWETH9.sol | 3 +- .../contracts/bridgehub/Bridgehub.sol | 110 ++++-- .../contracts/bridgehub/IBridgehub.sol | 4 +- l1-contracts/contracts/common/Config.sol | 4 +- .../contracts/common/Dependencies.sol | 8 +- .../contracts/common/L1ContractErrors.sol | 337 ++++++++++++++++++ .../contracts/common/L2ContractAddresses.sol | 4 +- l1-contracts/contracts/common/Messaging.sol | 4 +- .../contracts/common/ReentrancyGuard.sol | 19 +- .../common/interfaces/IL2ContractDeployer.sol | 4 +- .../common/libraries/L2ContractHelper.sol | 30 +- .../contracts/common/libraries/SemVer.sol | 4 +- .../common/libraries/UncheckedMath.sol | 4 +- .../common/libraries/UnsafeBytes.sol | 4 +- .../dev-contracts/TestnetERC20Token.sol | 2 +- .../dev-contracts/test/DummySharedBridge.sol | 8 +- .../test/DummyStateTransitionManager.sol | 2 +- ...eTransitionManagerWithBridgeHubAddress.sol | 2 +- .../contracts/governance/ChainAdmin.sol | 16 +- .../contracts/governance/Governance.sol | 68 ++-- .../contracts/governance/IGovernance.sol | 4 +- .../IStateTransitionManager.sol | 6 +- .../StateTransitionManager.sol | 63 ++-- .../state-transition/ValidatorTimelock.sol | 22 +- .../chain-deps/DiamondInit.sol | 39 +- .../chain-deps/facets/Admin.sol | 58 ++- .../chain-deps/facets/Executor.sol | 264 +++++++++----- .../chain-deps/facets/Getters.sol | 8 +- .../chain-deps/facets/Mailbox.sol | 54 ++- .../facets/ZkSyncHyperchainBase.sol | 38 +- .../chain-interfaces/IAdmin.sol | 4 +- .../chain-interfaces/IDiamondInit.sol | 4 +- .../chain-interfaces/IExecutor.sol | 4 +- .../chain-interfaces/IGetters.sol | 4 +- .../chain-interfaces/ILegacyGetters.sol | 4 +- .../chain-interfaces/IMailbox.sol | 4 +- .../chain-interfaces/ITransactionFilterer.sol | 4 +- .../chain-interfaces/IVerifier.sol | 4 +- .../chain-interfaces/IZkSyncHyperchain.sol | 4 +- .../IZkSyncHyperchainBase.sol | 3 +- .../l2-deps/ISystemContext.sol | 3 +- .../state-transition/libraries/Diamond.sol | 64 +++- .../state-transition/libraries/LibMap.sol | 3 +- .../state-transition/libraries/Merkle.sol | 19 +- .../libraries/PriorityQueue.sol | 16 +- .../libraries/TransactionValidator.sol | 83 +++-- .../contracts/upgrades/BaseZkSyncUpgrade.sol | 80 +++-- .../upgrades/BaseZkSyncUpgradeGenesis.sol | 12 +- .../upgrades/ZkSyncUpgradeErrors.sol | 47 ++- .../contracts/vendor/AddressAliasHelper.sol | 5 +- l1-contracts/deploy-scripts/AcceptAdmin.s.sol | 4 +- .../DecentralizeGovernanceUpgradeScript.s.sol | 5 +- l1-contracts/deploy-scripts/DeployErc20.s.sol | 7 +- l1-contracts/deploy-scripts/DeployL1.s.sol | 4 +- .../deploy-scripts/DeployL2Contracts.sol | 18 +- .../deploy-scripts/DeployPaymaster.s.sol | 2 +- .../InitializeL2WethToken.s.sol | 4 +- .../deploy-scripts/RegisterHyperchain.s.sol | 2 +- l1-contracts/deploy-scripts/Utils.sol | 2 +- l1-contracts/foundry.toml | 29 +- l1-contracts/lib/forge-std | 1 - l1-contracts/lib/murky | 1 - l1-contracts/lib/openzeppelin-contracts | 1 - .../lib/openzeppelin-contracts-upgradeable | 1 - l1-contracts/package.json | 4 +- l1-contracts/remappings.txt | 12 +- .../scripts/initialize-l2-weth-token.ts | 4 +- .../scripts/setup-legacy-bridge-era.ts | 6 +- .../scripts/upgrade-consistency-checker.ts | 10 +- l1-contracts/src.ts/deploy.ts | 17 +- .../script-out/output-deploy-l1.toml | 54 +++ .../unit/concrete/Bridgehub/Initialize.t.sol | 2 +- .../Bridgehub/_Bridgehub_Shared.t.sol | 2 +- .../Bridgehub/experimental_bridge.t.sol | 78 ++-- .../L1Erc20Bridge/ClaimFailedDeposit.t.sol | 3 +- .../Bridges/L1Erc20Bridge/Deposit.t.sol | 9 +- .../L1Erc20Bridge/FinalizeWithdrawal.sol | 3 +- .../L1Erc20Bridge/Initialization.t.sol | 3 +- .../Bridges/L1Erc20Bridge/Reentrancy.t.sol | 9 +- .../L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol | 2 +- .../L1SharedBridge/L1SharedBridgeFails.t.sol | 65 ++-- .../_L1SharedBridge_Shared.t.sol | 2 +- .../unit/concrete/DiamondCut/FacetCut.t.sol | 19 +- .../concrete/DiamondCut/Initialization.t.sol | 15 +- .../concrete/DiamondCut/UpgradeLogic.t.sol | 8 +- .../concrete/Executor/Authorization.t.sol | 7 +- .../unit/concrete/Executor/Committing.t.sol | 62 ++-- .../unit/concrete/Executor/Executing.t.sol | 23 +- .../unit/concrete/Executor/Proving.t.sol | 19 +- .../unit/concrete/Executor/Reverting.t.sol | 3 +- .../concrete/Executor/_Executor_Shared.t.sol | 3 +- .../concrete/Governance/Authorization.t.sol | 19 +- .../unit/concrete/Governance/Executing.t.sol | 29 +- .../unit/concrete/Governance/Reentrancy.t.sol | 9 +- .../ValidatorTimelock/ValidatorTimelock.t.sol | 27 +- .../CreateNewChain.t.sol | 16 +- .../StateTransitionManager/FreezeChain.t.sol | 6 +- .../StateTransitionOwnerZero.t.sol | 5 +- .../_StateTransitionManager_Shared.t.sol | 7 +- .../chain-deps/DiamondInit/Initialize.t.sol | 9 +- .../DiamondProxy/DiamondProxy.t.sol | 7 +- .../chain-deps/facets/Admin/AcceptAdmin.t.sol | 4 +- .../facets/Admin/ChangeFeeParams.t.sol | 6 +- .../facets/Admin/ExecuteUpgrade.t.sol | 4 +- .../facets/Admin/FreezeDiamond.t.sol | 4 +- .../facets/Admin/SetPendingGovernor.t.sol | 5 +- .../facets/Admin/SetPorterAvailability.t.sol | 5 +- .../Admin/SetPriorityTxMaxGasLimit.t.sol | 8 +- .../facets/Admin/SetTransactionFilterer.t.sol | 6 +- .../facets/Admin/SetValidator.t.sol | 5 +- .../facets/Admin/UnfreezeDiamond.t.sol | 7 +- .../Admin/UpgradeChainFromVersion.t.sol | 16 +- .../facets/Base/OnlyBridgehub.t.sol | 6 +- .../chain-deps/facets/Base/OnlyGovernor.t.sol | 6 +- ...OnlyGovernorOrStateTransitionManager.t.sol | 9 +- .../Base/OnlyStateTransitionManager.t.sol | 6 +- .../facets/Base/OnlyValidator.t.sol | 6 +- .../facets/Getters/IsFunctionFreezable.t.sol | 4 +- .../Getters/PriorityQueueFrontOperation.t.sol | 3 +- .../facets/Mailbox/BaseMailboxTests.t.sol | 3 +- .../BridgehubRequestL2Transaction.t.sol | 5 +- .../facets/Mailbox/FinalizeWithdrawal.t.sol | 3 +- .../Mailbox/ProvingL2LogsInclusion.t.sol | 5 +- .../facets/Mailbox/RequestL2Transaction.t.sol | 9 +- .../Mailbox/TransferEthToSharedBridge.t.sol | 5 +- .../libraries/Merkle/Merkle.t.sol | 7 +- .../libraries/PriorityQueue/OnEmptyQueue.sol | 5 +- .../libraries/PriorityQueue/PopOperations.sol | 3 +- .../TransactionValidator/ValidateL1L2Tx.t.sol | 9 +- .../ValidateUpgradeTransaction.t.sol | 23 +- .../test/unit_tests/custom_base_token.spec.ts | 6 +- .../test/unit_tests/governance_test.spec.ts | 8 +- .../unit_tests/l1_shared_bridge_test.spec.ts | 18 +- .../test/unit_tests/l2-upgrade.test.spec.ts | 38 +- .../test/unit_tests/legacy_era_test.spec.ts | 22 +- .../test/unit_tests/mailbox_test.spec.ts | 10 +- .../test/unit_tests/proxy_test.spec.ts | 6 +- l1-contracts/test/unit_tests/utils.ts | 18 +- .../validator_timelock_test.spec.ts | 12 +- l2-contracts/contracts/Dependencies.sol | 8 +- l2-contracts/contracts/L2ContractHelper.sol | 4 +- .../contracts/SystemContractsCaller.sol | 6 +- l2-contracts/contracts/TestnetPaymaster.sol | 12 +- .../contracts/bridge/L2SharedBridge.sol | 18 +- .../contracts/bridge/L2StandardERC20.sol | 23 +- .../contracts/bridge/L2WrappedBaseToken.sol | 10 +- .../bridge/interfaces/IL1ERC20Bridge.sol | 4 +- .../bridge/interfaces/IL1SharedBridge.sol | 4 +- .../bridge/interfaces/IL2SharedBridge.sol | 4 +- .../bridge/interfaces/IL2StandardToken.sol | 4 +- .../bridge/interfaces/IL2WrappedBaseToken.sol | 3 +- .../dev-contracts/DevL2SharedBridge.sol | 2 +- .../{ => errors}/L2ContractErrors.sol | 38 +- .../contracts/interfaces/IPaymaster.sol | 4 +- .../contracts/interfaces/IPaymasterFlow.sol | 4 +- .../contracts/vendor/AddressAliasHelper.sol | 4 +- l2-contracts/package.json | 4 +- .../deploy-shared-bridge-on-l2-through-l1.ts | 4 +- l2-contracts/test/erc20.test.ts | 29 +- l2-contracts/test/weth.test.ts | 22 +- lib/forge-std | 2 +- lib/murky | 2 +- ... => openzeppelin-contracts-upgradeable-v4} | 0 ...in-contracts => openzeppelin-contracts-v4} | 0 system-contracts/SystemContractsHashes.json | 70 ++-- system-contracts/bootloader/bootloader.yul | 9 +- .../contracts/AccountCodeStorage.sol | 2 +- system-contracts/contracts/Compressor.sol | 30 +- system-contracts/contracts/Constants.sol | 4 +- .../contracts/ContractDeployer.sol | 8 +- .../contracts/KnownCodesStorage.sol | 4 +- system-contracts/contracts/L1Messenger.sol | 12 +- system-contracts/contracts/L2BaseToken.sol | 4 +- .../contracts/MsgValueSimulator.sol | 8 +- system-contracts/contracts/NonceHolder.sol | 8 +- .../contracts/PubdataChunkPublisher.sol | 4 +- system-contracts/contracts/SystemContext.sol | 4 +- .../contracts/SystemContractErrors.sol | 133 +++++-- .../SystemContractBase.sol} | 6 +- .../contracts/interfaces/IAccount.sol | 4 +- .../interfaces/IAccountCodeStorage.sol | 4 +- .../contracts/interfaces/IBaseToken.sol | 4 +- .../interfaces/IBootloaderUtilities.sol | 4 +- .../contracts/interfaces/IComplexUpgrader.sol | 4 +- .../contracts/interfaces/ICompressor.sol | 4 +- .../interfaces/IContractDeployer.sol | 4 +- .../interfaces/IImmutableSimulator.sol | 4 +- .../interfaces/IKnownCodesStorage.sol | 4 +- .../contracts/interfaces/IL1Messenger.sol | 4 +- .../contracts/interfaces/IL2StandardToken.sol | 4 +- .../contracts/interfaces/IMailbox.sol | 4 +- .../contracts/interfaces/INonceHolder.sol | 4 +- .../contracts/interfaces/IPaymaster.sol | 4 +- .../contracts/interfaces/IPaymasterFlow.sol | 4 +- .../interfaces/IPubdataChunkPublisher.sol | 3 +- .../contracts/interfaces/ISystemContext.sol | 4 +- .../interfaces/ISystemContextDeprecated.sol | 4 +- .../contracts/libraries/EfficientCall.sol | 10 +- .../contracts/libraries/RLPEncoder.sol | 4 +- .../libraries/SystemContractHelper.sol | 4 +- .../libraries/SystemContractsCaller.sol | 6 +- .../contracts/libraries/TransactionHelper.sol | 4 +- .../libraries/UnsafeBytesCalldata.sol | 4 +- .../contracts/libraries/Utils.sol | 3 +- .../openzeppelin/token/ERC20/IERC20.sol | 2 +- .../token/ERC20/extensions/IERC20Permit.sol | 2 +- .../token/ERC20/utils/SafeERC20.sol | 2 +- .../contracts/openzeppelin/utils/Address.sol | 2 +- .../contracts/test-contracts/AlwaysRevert.sol | 2 +- .../test-contracts/CodeOracleTest.sol | 2 +- .../test-contracts/DelegateCaller.sol | 2 +- .../contracts/test-contracts/KeccakTest.sol | 2 +- .../contracts/test-contracts/TransferTest.sol | 2 +- system-contracts/test/Compressor.spec.ts | 26 +- system-contracts/test/NonceHolder.spec.ts | 2 +- yarn.lock | 82 ++--- 225 files changed, 2341 insertions(+), 1250 deletions(-) create mode 100644 l1-contracts/contracts/common/L1ContractErrors.sol delete mode 120000 l1-contracts/lib/forge-std delete mode 120000 l1-contracts/lib/murky delete mode 120000 l1-contracts/lib/openzeppelin-contracts delete mode 120000 l1-contracts/lib/openzeppelin-contracts-upgradeable create mode 100644 l1-contracts/test/foundry/integration/deploy-scripts/script-out/output-deploy-l1.toml rename l2-contracts/contracts/{ => errors}/L2ContractErrors.sol (56%) rename lib/{openzeppelin-contracts-upgradeable => openzeppelin-contracts-upgradeable-v4} (100%) rename lib/{openzeppelin-contracts => openzeppelin-contracts-v4} (100%) rename system-contracts/contracts/{interfaces/ISystemContract.sol => abstract/SystemContractBase.sol} (90%) diff --git a/.gitmodules b/.gitmodules index 13db155a9..3451bd884 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,12 @@ [submodule "lib/murky"] path = lib/murky url = https://github.com/dmfxyz/murky -[submodule "lib/openzeppelin-contracts-upgradeable"] - path = lib/openzeppelin-contracts-upgradeable +[submodule "lib/openzeppelin-contracts-upgradeable-v4"] + path = lib/openzeppelin-contracts-upgradeable-v4 url = https://github.com/Openzeppelin/openzeppelin-contracts-upgradeable branch = release-v4.9 -[submodule "lib/openzeppelin-contracts"] - path = lib/openzeppelin-contracts +[submodule "lib/openzeppelin-contracts-v4"] + path = lib/openzeppelin-contracts-v4 url = https://github.com/Openzeppelin/openzeppelin-contracts branch = release-v4.9 [submodule "lib/forge-std"] diff --git a/.solhintignore b/.solhintignore index ab2fcf7e1..abcb64f98 100644 --- a/.solhintignore +++ b/.solhintignore @@ -24,7 +24,7 @@ system-contracts/contracts/test-contracts system-contracts/contracts-preprocessed # gas-bound-caller -gas-bound-caller/contracts/test-contracts +gas-bound-caller lib/* l2-contracts/lib diff --git a/_typos.toml b/_typos.toml index 54e99fdf1..b2c7c85c8 100644 --- a/_typos.toml +++ b/_typos.toml @@ -5,6 +5,7 @@ extend-exclude = [ "/l1-contracts/out/", "/l1-contracts/node_modules/", "/l1-contracts/artifacts", + "/l1-contracts-foundry/lib/", "/l2-contracts/artifacts-zk", "/l2-contracts/cache-zk", "/l2-contracts/typechain", diff --git a/gas-bound-caller/contracts/GasBoundCaller.sol b/gas-bound-caller/contracts/GasBoundCaller.sol index 78af446ca..c0de7a23a 100644 --- a/gas-bound-caller/contracts/GasBoundCaller.sol +++ b/gas-bound-caller/contracts/GasBoundCaller.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.20; import {EfficientCall} from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/EfficientCall.sol"; import {ISystemContext} from "./ISystemContext.sol"; -import {InsufficientGas} from "./SystemContractErrors.sol"; ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(address(0x800b)); @@ -16,12 +15,12 @@ ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(address(0x800b) * system contracts have and it can relay call to any contract, breaking potential trust in system contracts. */ contract GasBoundCaller { - /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` gas are used for the O(1) operations at the start + /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` ergs are used for the O(1) operations at the start /// of execution of the contract, such as abi decoding the parameters, jumping to the correct function, etc. - uint256 internal constant CALL_ENTRY_OVERHEAD = 800; - /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, + uint256 constant CALL_ENTRY_OVERHEAD = 800; + /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` ergs are used for the O(1) operations at the end of the execution, /// as such relaying the return. - uint256 internal constant CALL_RETURN_OVERHEAD = 400; + uint256 constant CALL_RETURN_OVERHEAD = 400; /// @notice The function that implements limiting of the total gas expenditure of the call. /// @dev On Era, the gas for pubdata is charged at the end of the execution of the entire transaction, meaning @@ -46,9 +45,7 @@ contract GasBoundCaller { // This require is more of a safety protection for the users that call this function with incorrect parameters. // // Ultimately, the entire `gas` sent to this call can be spent on compute regardless of the `_maxTotalGas` parameter. - if (_maxTotalGas < gasleft()) { - revert InsufficientGas(); - } + require(_maxTotalGas >= gasleft(), "Gas limit is too low"); // This is the amount of gas that can be spent *exclusively* on pubdata in addition to the `gas` provided to this function. uint256 pubdataAllowance = _maxTotalGas > expectedForCompute ? _maxTotalGas - expectedForCompute : 0; @@ -93,9 +90,7 @@ contract GasBoundCaller { if (pubdataGas != 0) { // Here we double check that the additional cost is not higher than the maximum allowed. // Note, that the `gasleft()` can be spent on pubdata too. - if (pubdataAllowance + gasleft() < pubdataGas + CALL_RETURN_OVERHEAD) { - revert InsufficientGas(); - } + require(pubdataAllowance + gasleft() >= pubdataGas + CALL_RETURN_OVERHEAD, "Not enough gas for pubdata"); } assembly { diff --git a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol index a19c1b31c..a3b6e1426 100644 --- a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol @@ -2,10 +2,8 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; import {IL1SharedBridge} from "./interfaces/IL1SharedBridge.sol"; @@ -13,6 +11,8 @@ import {IL1SharedBridge} from "./interfaces/IL1SharedBridge.sol"; import {L2ContractHelper} from "../common/libraries/L2ContractHelper.sol"; import {ReentrancyGuard} from "../common/ReentrancyGuard.sol"; +import {Unauthorized, EmptyDeposit, TokensWithFeesNotSupported, WithdrawalAlreadyFinalized} from "../common/L1ContractErrors.sol"; + /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev /// @notice Smart contract that allows depositing ERC20 tokens from Ethereum to hyperchains @@ -67,7 +67,9 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { /// @dev transfer token to shared bridge as part of upgrade function transferTokenToSharedBridge(address _token) external { - require(msg.sender == address(SHARED_BRIDGE), "Not shared bridge"); + if (msg.sender != address(SHARED_BRIDGE)) { + revert Unauthorized(msg.sender); + } uint256 amount = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(address(SHARED_BRIDGE), amount); } @@ -150,9 +152,15 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { uint256 _l2TxGasPerPubdataByte, address _refundRecipient ) public payable nonReentrant returns (bytes32 l2TxHash) { - require(_amount != 0, "0T"); // empty deposit + // empty deposit + if (_amount == 0) { + revert EmptyDeposit(); + } uint256 amount = _depositFundsToSharedBridge(msg.sender, IERC20(_l1Token), _amount); - require(amount == _amount, "3T"); // The token has non-standard transfer logic + // The token has non-standard transfer logic + if (amount != _amount) { + revert TokensWithFeesNotSupported(); + } l2TxHash = SHARED_BRIDGE.depositLegacyErc20Bridge{value: msg.value}({ _msgSender: msg.sender, @@ -164,8 +172,13 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { _refundRecipient: _refundRecipient }); depositAmount[msg.sender][_l1Token][l2TxHash] = _amount; - // solhint-disable-next-line func-named-parameters - emit DepositInitiated(l2TxHash, msg.sender, _l2Receiver, _l1Token, _amount); + emit DepositInitiated({ + l2DepositTxHash: l2TxHash, + from: msg.sender, + to: _l2Receiver, + l1Token: _l1Token, + amount: _amount + }); } /// @dev Transfers tokens from the depositor address to the shared bridge address. @@ -196,7 +209,10 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { bytes32[] calldata _merkleProof ) external nonReentrant { uint256 amount = depositAmount[_depositSender][_l1Token][_l2TxHash]; - require(amount != 0, "2T"); // empty deposit + // empty deposit + if (amount == 0) { + revert EmptyDeposit(); + } delete depositAmount[_depositSender][_l1Token][_l2TxHash]; SHARED_BRIDGE.claimFailedDepositLegacyErc20Bridge({ @@ -225,7 +241,9 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { bytes calldata _message, bytes32[] calldata _merkleProof ) external nonReentrant { - require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "pw"); + if (isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex]) { + revert WithdrawalAlreadyFinalized(); + } // We don't need to set finalizeWithdrawal here, as we set it in the shared bridge (address l1Receiver, address l1Token, uint256 amount) = SHARED_BRIDGE.finalizeWithdrawalLegacyErc20Bridge({ diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index 442f15e8a..2b5a8887a 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -2,14 +2,12 @@ pragma solidity 0.8.24; -// solhint-disable reason-string, gas-custom-errors +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/access/Ownable2StepUpgradeable.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/security/PausableUpgradeable.sol"; -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; - -import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC20Metadata} from "@openzeppelin/contracts-v4/token/ERC20/extensions/IERC20Metadata.sol"; +import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; import {IL1SharedBridge} from "./interfaces/IL1SharedBridge.sol"; @@ -24,6 +22,7 @@ import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE} from "../common/Config.sol"; import {IBridgehub, L2TransactionRequestTwoBridgesInner, L2TransactionRequestDirect} from "../bridgehub/IBridgehub.sol"; import {IGetters} from "../state-transition/chain-interfaces/IGetters.sol"; import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "../common/L2ContractAddresses.sol"; +import {Unauthorized, ZeroAddress, SharedBridgeValueAlreadySet, SharedBridgeKey, NoFundsTransferred, ZeroBalance, ValueMismatch, TokensWithFeesNotSupported, NonEmptyMsgValue, L2BridgeNotSet, TokenNotSupported, DepositIncorrectAmount, EmptyDeposit, DepositExists, AddressAlreadyUsed, InvalidProof, DepositDoesNotExist, InsufficientChainBalance, SharedBridgeValueNotSet, WithdrawalAlreadyFinalized, WithdrawFailed, L2WithdrawalMessageWrongLength, InvalidSelector, SharedBridgeBalanceMismatch, SharedBridgeValueNotSet} from "../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -93,28 +92,33 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @notice Checks that the message sender is the bridgehub. modifier onlyBridgehub() { - require(msg.sender == address(BRIDGE_HUB), "ShB not BH"); + if (msg.sender != address(BRIDGE_HUB)) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks that the message sender is the bridgehub or zkSync Era Diamond Proxy. modifier onlyBridgehubOrEra(uint256 _chainId) { - require( - msg.sender == address(BRIDGE_HUB) || (_chainId == ERA_CHAIN_ID && msg.sender == ERA_DIAMOND_PROXY), - "L1SharedBridge: not bridgehub or era chain" - ); + if (msg.sender != address(BRIDGE_HUB) && (_chainId != ERA_CHAIN_ID || msg.sender != ERA_DIAMOND_PROXY)) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks that the message sender is the legacy bridge. modifier onlyLegacyBridge() { - require(msg.sender == address(legacyBridge), "ShB not legacy bridge"); + if (msg.sender != address(legacyBridge)) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks that the message sender is the shared bridge itself. modifier onlySelf() { - require(msg.sender == address(this), "ShB not shared bridge"); + if (msg.sender != address(this)) { + revert Unauthorized(msg.sender); + } _; } @@ -137,21 +141,27 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @param _owner Address which can change L2 token implementation and upgrade the bridge /// implementation. The owner is the Governor and separate from the ProxyAdmin from now on, so that the Governor can call the bridge. function initialize(address _owner) external reentrancyGuardInitializer initializer { - require(_owner != address(0), "ShB owner 0"); + if (_owner == address(0)) { + revert ZeroAddress(); + } _transferOwnership(_owner); } /// @dev This sets the first post diamond upgrade batch for era, used to check old eth withdrawals /// @param _eraPostDiamondUpgradeFirstBatch The first batch number on the zkSync Era Diamond Proxy that was settled after diamond proxy upgrade. function setEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external onlyOwner { - require(eraPostDiamondUpgradeFirstBatch == 0, "ShB: eFPUB already set"); + if (eraPostDiamondUpgradeFirstBatch != 0) { + revert SharedBridgeValueAlreadySet(SharedBridgeKey.PostUpgradeFirstBatch); + } eraPostDiamondUpgradeFirstBatch = _eraPostDiamondUpgradeFirstBatch; } /// @dev This sets the first post upgrade batch for era, used to check old token withdrawals /// @param _eraPostLegacyBridgeUpgradeFirstBatch The first batch number on the zkSync Era Diamond Proxy that was settled after legacy bridge upgrade. function setEraPostLegacyBridgeUpgradeFirstBatch(uint256 _eraPostLegacyBridgeUpgradeFirstBatch) external onlyOwner { - require(eraPostLegacyBridgeUpgradeFirstBatch == 0, "ShB: eFPUB already set"); + if (eraPostLegacyBridgeUpgradeFirstBatch != 0) { + revert SharedBridgeValueAlreadySet(SharedBridgeKey.LegacyBridgeFirstBatch); + } eraPostLegacyBridgeUpgradeFirstBatch = _eraPostLegacyBridgeUpgradeFirstBatch; } @@ -162,8 +172,12 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _eraLegacyBridgeLastDepositBatch, uint256 _eraLegacyBridgeLastDepositTxNumber ) external onlyOwner { - require(eraLegacyBridgeLastDepositBatch == 0, "ShB: eLOBDB already set"); - require(eraLegacyBridgeLastDepositTxNumber == 0, "ShB: eLOBDTN already set"); + if (eraLegacyBridgeLastDepositBatch != 0) { + revert SharedBridgeValueAlreadySet(SharedBridgeKey.LegacyBridgeLastDepositBatch); + } + if (eraLegacyBridgeLastDepositTxNumber != 0) { + revert SharedBridgeValueAlreadySet(SharedBridgeKey.LegacyBridgeLastDepositTxn); + } eraLegacyBridgeLastDepositBatch = _eraLegacyBridgeLastDepositBatch; eraLegacyBridgeLastDepositTxNumber = _eraLegacyBridgeLastDepositTxNumber; } @@ -177,7 +191,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 balanceBefore = address(this).balance; IMailbox(_target).transferEthToSharedBridge(); uint256 balanceAfter = address(this).balance; - require(balanceAfter > balanceBefore, "ShB: 0 eth transferred"); + if (balanceAfter <= balanceBefore) { + revert NoFundsTransferred(); + } chainBalance[_targetChainId][ETH_TOKEN_ADDRESS] = chainBalance[_targetChainId][ETH_TOKEN_ADDRESS] + balanceAfter - @@ -185,10 +201,14 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } else { uint256 balanceBefore = IERC20(_token).balanceOf(address(this)); uint256 legacyBridgeBalance = IERC20(_token).balanceOf(address(legacyBridge)); - require(legacyBridgeBalance > 0, "ShB: 0 amount to transfer"); + if (legacyBridgeBalance == 0) { + revert ZeroBalance(); + } IL1ERC20Bridge(_target).transferTokenToSharedBridge(_token); uint256 balanceAfter = IERC20(_token).balanceOf(address(this)); - require(balanceAfter - balanceBefore >= legacyBridgeBalance, "ShB: wrong amount transferred"); + if (balanceAfter - balanceBefore < legacyBridgeBalance) { + revert SharedBridgeBalanceMismatch(); + } chainBalance[_targetChainId][_token] = chainBalance[_targetChainId][_token] + legacyBridgeBalance; } } @@ -210,7 +230,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @dev Accepts ether only from the hyperchain associated with the specified chain ID. /// @param _chainId The chain ID corresponding to the hyperchain allowed to send ether. function receiveEth(uint256 _chainId) external payable { - require(BRIDGE_HUB.getHyperchain(_chainId) == msg.sender, "receiveEth not state transition"); + if (BRIDGE_HUB.getHyperchain(_chainId) != msg.sender) { + revert Unauthorized(msg.sender); + } } /// @dev Initializes the l2Bridge address by governance for a specific chain. @@ -231,13 +253,20 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _amount ) external payable virtual onlyBridgehubOrEra(_chainId) whenNotPaused { if (_l1Token == ETH_TOKEN_ADDRESS) { - require(msg.value == _amount, "L1SharedBridge: msg.value not equal to amount"); + if (msg.value != _amount) { + revert ValueMismatch(_amount, msg.value); + } } else { // The Bridgehub also checks this, but we want to be sure - require(msg.value == 0, "ShB m.v > 0 b d.it"); + if (msg.value != 0) { + revert NonEmptyMsgValue(); + } uint256 amount = _depositFunds(_prevMsgSender, IERC20(_l1Token), _amount); // note if _prevMsgSender is this contract, this will return 0. This does not happen. - require(amount == _amount, "3T"); // The token has non-standard transfer logic + // The token has non-standard transfer logic + if (amount != _amount) { + revert TokensWithFeesNotSupported(); + } } if (!hyperbridgingEnabled[_chainId]) { @@ -277,27 +306,43 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade whenNotPaused returns (L2TransactionRequestTwoBridgesInner memory request) { - require(l2BridgeAddress[_chainId] != address(0), "ShB l2 bridge not deployed"); + if (l2BridgeAddress[_chainId] == address(0)) { + revert L2BridgeNotSet(_chainId); + } (address _l1Token, uint256 _depositAmount, address _l2Receiver) = abi.decode( _data, (address, uint256, address) ); - require(_l1Token != L1_WETH_TOKEN, "ShB: WETH deposit not supported"); - require(BRIDGE_HUB.baseToken(_chainId) != _l1Token, "ShB: baseToken deposit not supported"); + if (_l1Token == L1_WETH_TOKEN) { + revert TokenNotSupported(L1_WETH_TOKEN); + } + if (BRIDGE_HUB.baseToken(_chainId) == _l1Token) { + revert TokenNotSupported(_l1Token); + } uint256 amount; if (_l1Token == ETH_TOKEN_ADDRESS) { amount = msg.value; - require(_depositAmount == 0, "ShB wrong withdraw amount"); + if (_depositAmount != 0) { + revert DepositIncorrectAmount(0, _depositAmount); + } } else { - require(msg.value == 0, "ShB m.v > 0 for BH d.it 2"); + if (msg.value != 0) { + revert NonEmptyMsgValue(); + } amount = _depositAmount; - uint256 withdrawAmount = _depositFunds(_prevMsgSender, IERC20(_l1Token), _depositAmount); - require(withdrawAmount == _depositAmount, "5T"); // The token has non-standard transfer logic + uint256 depAmount = _depositFunds(_prevMsgSender, IERC20(_l1Token), _depositAmount); + // The token has non-standard transfer logic + if (depAmount != _depositAmount) { + revert DepositIncorrectAmount(depAmount, _depositAmount); + } + } + // empty deposit amount + if (amount == 0) { + revert EmptyDeposit(); } - require(amount != 0, "6T"); // empty deposit amount bytes32 txDataHash = keccak256(abi.encode(_prevMsgSender, _l1Token, amount)); if (!hyperbridgingEnabled[_chainId]) { @@ -336,15 +381,21 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade bytes32 _txDataHash, bytes32 _txHash ) external override onlyBridgehub whenNotPaused { - require(depositHappened[_chainId][_txHash] == 0x00, "ShB tx hap"); + if (depositHappened[_chainId][_txHash] != 0x00) { + revert DepositExists(); + } depositHappened[_chainId][_txHash] = _txDataHash; emit BridgehubDepositFinalized(_chainId, _txDataHash, _txHash); } /// @dev Sets the L1ERC20Bridge contract address. Should be called only once. function setL1Erc20Bridge(address _legacyBridge) external onlyOwner { - require(address(legacyBridge) == address(0), "ShB: legacy bridge already set"); - require(_legacyBridge != address(0), "ShB: legacy bridge 0"); + if (address(legacyBridge) != address(0)) { + revert AddressAlreadyUsed(address(legacyBridge)); + } + if (_legacyBridge == address(0)) { + revert ZeroAddress(); + } legacyBridge = IL1ERC20Bridge(_legacyBridge); } @@ -431,9 +482,13 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _merkleProof: _merkleProof, _status: TxStatus.Failure }); - require(proofValid, "yn"); + if (!proofValid) { + revert InvalidProof(); + } + } + if (_amount == 0) { + revert NoFundsTransferred(); } - require(_amount > 0, "y1"); { bool notCheckedInLegacyBridgeOrWeCanCheckDeposit; @@ -448,14 +503,18 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade if (notCheckedInLegacyBridgeOrWeCanCheckDeposit) { bytes32 dataHash = depositHappened[_chainId][_l2TxHash]; bytes32 txDataHash = keccak256(abi.encode(_depositSender, _l1Token, _amount)); - require(dataHash == txDataHash, "ShB: d.it not hap"); + if (dataHash != txDataHash) { + revert DepositDoesNotExist(); + } delete depositHappened[_chainId][_l2TxHash]; } } if (!hyperbridgingEnabled[_chainId]) { // check that the chain has sufficient balance - require(chainBalance[_chainId][_l1Token] >= _amount, "ShB n funds"); + if (chainBalance[_chainId][_l1Token] < _amount) { + revert InsufficientChainBalance(); + } chainBalance[_chainId][_l1Token] -= _amount; } @@ -466,7 +525,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade assembly { callSuccess := call(gas(), _depositSender, _amount, 0, 0, 0, 0) } - require(callSuccess, "ShB: claimFailedDeposit failed"); + if (!callSuccess) { + revert WithdrawFailed(); + } } else { IERC20(_l1Token).safeTransfer(_depositSender, _amount); // Note we don't allow weth deposits anymore, but there might be legacy weth deposits. @@ -481,7 +542,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @param _l2BatchNumber The L2 batch number for the withdrawal. /// @return Whether withdrawal was initiated on zkSync Era before diamond proxy upgrade. function _isEraLegacyEthWithdrawal(uint256 _chainId, uint256 _l2BatchNumber) internal view returns (bool) { - require((_chainId != ERA_CHAIN_ID) || eraPostDiamondUpgradeFirstBatch != 0, "ShB: diamondUFB not set for Era"); + if ((_chainId == ERA_CHAIN_ID) && eraPostDiamondUpgradeFirstBatch == 0) { + revert SharedBridgeValueNotSet(SharedBridgeKey.PostUpgradeFirstBatch); + } return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraPostDiamondUpgradeFirstBatch); } @@ -490,10 +553,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @param _l2BatchNumber The L2 batch number for the withdrawal. /// @return Whether withdrawal was initiated on zkSync Era before Legacy Bridge upgrade. function _isEraLegacyTokenWithdrawal(uint256 _chainId, uint256 _l2BatchNumber) internal view returns (bool) { - require( - (_chainId != ERA_CHAIN_ID) || eraPostLegacyBridgeUpgradeFirstBatch != 0, - "ShB: LegacyUFB not set for Era" - ); + if ((_chainId == ERA_CHAIN_ID) && eraPostLegacyBridgeUpgradeFirstBatch == 0) { + revert SharedBridgeValueNotSet(SharedBridgeKey.LegacyBridgeFirstBatch); + } return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraPostLegacyBridgeUpgradeFirstBatch); } @@ -507,10 +569,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _l2BatchNumber, uint256 _l2TxNumberInBatch ) internal view returns (bool) { - require( - (_chainId != ERA_CHAIN_ID) || (eraLegacyBridgeLastDepositBatch != 0), - "ShB: last deposit time not set for Era" - ); + if ((_chainId == ERA_CHAIN_ID) && (eraLegacyBridgeLastDepositBatch == 0)) { + revert SharedBridgeValueNotSet(SharedBridgeKey.LegacyBridgeLastDepositBatch); + } return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraLegacyBridgeLastDepositBatch || @@ -536,7 +597,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade // To avoid rewithdrawing txs that have already happened on the legacy bridge. // Note: new withdraws are all recorded here, so double withdrawing them is not possible. if (_isEraLegacyTokenWithdrawal(_chainId, _l2BatchNumber)) { - require(!legacyBridge.isWithdrawalFinalized(_l2BatchNumber, _l2MessageIndex), "ShB: legacy withdrawal"); + if (legacyBridge.isWithdrawalFinalized(_l2BatchNumber, _l2MessageIndex)) { + revert WithdrawalAlreadyFinalized(); + } } _finalizeWithdrawal({ _chainId: _chainId, @@ -564,7 +627,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade bytes calldata _message, bytes32[] calldata _merkleProof ) internal nonReentrant whenNotPaused returns (address l1Receiver, address l1Token, uint256 amount) { - require(!isWithdrawalFinalized[_chainId][_l2BatchNumber][_l2MessageIndex], "Withdrawal is already finalized"); + if (isWithdrawalFinalized[_chainId][_l2BatchNumber][_l2MessageIndex]) { + revert WithdrawalAlreadyFinalized(); + } isWithdrawalFinalized[_chainId][_l2BatchNumber][_l2MessageIndex] = true; // Handling special case for withdrawal from zkSync Era initiated before Shared Bridge. @@ -574,7 +639,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _l2BatchNumber, _l2MessageIndex ); - require(!alreadyFinalized, "Withdrawal is already finalized 2"); + if (alreadyFinalized) { + revert WithdrawalAlreadyFinalized(); + } } MessageParams memory messageParams = MessageParams({ @@ -586,7 +653,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade if (!hyperbridgingEnabled[_chainId]) { // Check that the chain has sufficient balance - require(chainBalance[_chainId][l1Token] >= amount, "ShB not enough funds 2"); // not enough funds + if (chainBalance[_chainId][l1Token] < amount) { + // not enough funds + revert InsufficientChainBalance(); + } chainBalance[_chainId][l1Token] -= amount; } @@ -596,7 +666,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade assembly { callSuccess := call(gas(), l1Receiver, amount, 0, 0, 0, 0) } - require(callSuccess, "ShB: withdraw failed"); + if (!callSuccess) { + revert WithdrawFailed(); + } } else { // Withdraw funds IERC20(l1Token).safeTransfer(l1Receiver, amount); @@ -631,7 +703,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _message: l2ToL1Message, _proof: _merkleProof }); - require(success, "ShB withd w proof"); // withdrawal wrong proof + // withdrawal wrong proof + if (!success) { + revert InvalidProof(); + } } function _parseL2WithdrawalMessage( @@ -648,7 +723,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade // = 4 + 20 + 32 + 32 + _additionalData.length >= 68 (bytes). // So the data is expected to be at least 56 bytes long. - require(_l2ToL1message.length >= 56, "ShB wrong msg len"); // wrong message length + // wrong message length + if (_l2ToL1message.length < 56) { + revert L2WithdrawalMessageWrongLength(_l2ToL1message.length); + } (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_l2ToL1message, 0); if (bytes4(functionSignature) == IMailbox.finalizeEthWithdrawal.selector) { @@ -664,12 +742,14 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade // Check that the message length is correct. // It should be equal to the length of the function signature + address + address + uint256 = 4 + 20 + 20 + 32 = // 76 (bytes). - require(_l2ToL1message.length == 76, "ShB wrong msg len 2"); + if (_l2ToL1message.length != 76) { + revert L2WithdrawalMessageWrongLength(_l2ToL1message.length); + } (l1Receiver, offset) = UnsafeBytes.readAddress(_l2ToL1message, offset); (l1Token, offset) = UnsafeBytes.readAddress(_l2ToL1message, offset); (amount, offset) = UnsafeBytes.readUint256(_l2ToL1message, offset); } else { - revert("ShB Incorrect message function selector"); + revert InvalidSelector(bytes4(functionSignature)); } } @@ -711,8 +791,12 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _l2TxGasPerPubdataByte, address _refundRecipient ) external payable override onlyLegacyBridge nonReentrant whenNotPaused returns (bytes32 l2TxHash) { - require(l2BridgeAddress[ERA_CHAIN_ID] != address(0), "ShB b. n dep"); - require(_l1Token != L1_WETH_TOKEN, "ShB: WETH deposit not supported 2"); + if (l2BridgeAddress[ERA_CHAIN_ID] == address(0)) { + revert L2BridgeNotSet(ERA_CHAIN_ID); + } + if (_l1Token == L1_WETH_TOKEN) { + revert TokenNotSupported(L1_WETH_TOKEN); + } // Note that funds have been transferred to this contract in the legacy ERC20 bridge. if (!hyperbridgingEnabled[ERA_CHAIN_ID]) { diff --git a/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol index f7dd7b07b..615536de0 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IL1SharedBridge} from "./IL1SharedBridge.sol"; diff --git a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol index 45db2d02a..3a0838312 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; import {IBridgehub} from "../../bridgehub/IBridgehub.sol"; diff --git a/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol index eb21b4f25..87b0c6c9f 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @author Matter Labs interface IL2Bridge { diff --git a/l1-contracts/contracts/bridge/interfaces/IWETH9.sol b/l1-contracts/contracts/bridge/interfaces/IWETH9.sol index d8e99dc7a..2634cc5d5 100644 --- a/l1-contracts/contracts/bridge/interfaces/IWETH9.sol +++ b/l1-contracts/contracts/bridge/interfaces/IWETH9.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; interface IWETH9 { function deposit() external payable; diff --git a/l1-contracts/contracts/bridgehub/Bridgehub.sol b/l1-contracts/contracts/bridgehub/Bridgehub.sol index 51e3af1eb..0f1ccbfab 100644 --- a/l1-contracts/contracts/bridgehub/Bridgehub.sol +++ b/l1-contracts/contracts/bridgehub/Bridgehub.sol @@ -2,10 +2,8 @@ pragma solidity 0.8.24; -// solhint-disable reason-string, gas-custom-errors - -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/access/Ownable2StepUpgradeable.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/security/PausableUpgradeable.sol"; import {L2TransactionRequestDirect, L2TransactionRequestTwoBridgesOuter, L2TransactionRequestTwoBridgesInner} from "./IBridgehub.sol"; import {IBridgehub, IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol"; @@ -15,6 +13,7 @@ import {IZkSyncHyperchain} from "../state-transition/chain-interfaces/IZkSyncHyp import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE, BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS} from "../common/Config.sol"; import {BridgehubL2TransactionRequest, L2Message, L2Log, TxStatus} from "../common/Messaging.sol"; import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; +import {Unauthorized, STMAlreadyRegistered, STMNotRegistered, TokenAlreadyRegistered, TokenNotRegistered, ZeroChainId, ChainIdTooBig, SharedBridgeNotSet, BridgeHubAlreadyRegistered, AddressTooLow, MsgValueMismatch, WrongMagicValue, ZeroAddress} from "../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -51,7 +50,9 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus } modifier onlyOwnerOrAdmin() { - require(msg.sender == admin || msg.sender == owner(), "Bridgehub: not owner or admin"); + if (msg.sender != admin && msg.sender != owner()) { + revert Unauthorized(msg.sender); + } _; } @@ -59,6 +60,9 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus /// @dev Please note, if the owner wants to enforce the admin change it must execute both `setPendingAdmin` and /// `acceptAdmin` atomically. Otherwise `admin` can set different pending admin and so fail to accept the admin rights. function setPendingAdmin(address _newPendingAdmin) external onlyOwnerOrAdmin { + if (_newPendingAdmin == address(0)) { + revert ZeroAddress(); + } // Save previous value into the stack to put it into the event later address oldPendingAdmin = pendingAdmin; // Change pending admin @@ -69,7 +73,10 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus /// @inheritdoc IBridgehub function acceptAdmin() external { address currentPendingAdmin = pendingAdmin; - require(msg.sender == currentPendingAdmin, "n42"); // Only proposed by current admin address can claim the admin rights + // Only proposed by current admin address can claim the admin rights + if (msg.sender != currentPendingAdmin) { + revert Unauthorized(msg.sender); + } address previousAdmin = admin; admin = currentPendingAdmin; @@ -90,32 +97,41 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus /// @notice State Transition can be any contract with the appropriate interface/functionality function addStateTransitionManager(address _stateTransitionManager) external onlyOwner { - require( - !stateTransitionManagerIsRegistered[_stateTransitionManager], - "Bridgehub: state transition already registered" - ); + if (_stateTransitionManager == address(0)) { + revert ZeroAddress(); + } + if (stateTransitionManagerIsRegistered[_stateTransitionManager]) { + revert STMAlreadyRegistered(); + } stateTransitionManagerIsRegistered[_stateTransitionManager] = true; } /// @notice State Transition can be any contract with the appropriate interface/functionality /// @notice this stops new Chains from using the STF, old chains are not affected function removeStateTransitionManager(address _stateTransitionManager) external onlyOwner { - require( - stateTransitionManagerIsRegistered[_stateTransitionManager], - "Bridgehub: state transition not registered yet" - ); + if (_stateTransitionManager == address(0)) { + revert ZeroAddress(); + } + if (!stateTransitionManagerIsRegistered[_stateTransitionManager]) { + revert STMNotRegistered(); + } stateTransitionManagerIsRegistered[_stateTransitionManager] = false; } /// @notice token can be any contract with the appropriate interface/functionality function addToken(address _token) external onlyOwner { - require(!tokenIsRegistered[_token], "Bridgehub: token already registered"); + if (tokenIsRegistered[_token]) { + revert TokenAlreadyRegistered(_token); + } tokenIsRegistered[_token] = true; } /// @notice To set shared bridge, only Owner. Not done in initialize, as /// the order of deployment is Bridgehub, Shared bridge, and then we call this function setSharedBridge(address _sharedBridge) external onlyOwner { + if (_sharedBridge == address(0)) { + revert ZeroAddress(); + } sharedBridge = IL1SharedBridge(_sharedBridge); } @@ -130,17 +146,32 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus address _admin, bytes calldata _initData ) external onlyOwnerOrAdmin nonReentrant whenNotPaused returns (uint256) { - require(_chainId != 0, "Bridgehub: chainId cannot be 0"); - require(_chainId <= type(uint48).max, "Bridgehub: chainId too large"); + if (_chainId == 0) { + revert ZeroChainId(); + } + if (_chainId > type(uint48).max) { + revert ChainIdTooBig(); + } + if (_stateTransitionManager == address(0)) { + revert ZeroAddress(); + } + if (_baseToken == address(0)) { + revert ZeroAddress(); + } - require( - stateTransitionManagerIsRegistered[_stateTransitionManager], - "Bridgehub: state transition not registered" - ); - require(tokenIsRegistered[_baseToken], "Bridgehub: token not registered"); - require(address(sharedBridge) != address(0), "Bridgehub: weth bridge not set"); + if (!stateTransitionManagerIsRegistered[_stateTransitionManager]) { + revert STMNotRegistered(); + } + if (!tokenIsRegistered[_baseToken]) { + revert TokenNotRegistered(_baseToken); + } + if (address(sharedBridge) == address(0)) { + revert SharedBridgeNotSet(); + } - require(stateTransitionManager[_chainId] == address(0), "Bridgehub: chainId already registered"); + if (stateTransitionManager[_chainId] != address(0)) { + revert BridgeHubAlreadyRegistered(); + } stateTransitionManager[_chainId] = _stateTransitionManager; baseToken[_chainId] = _baseToken; @@ -247,9 +278,13 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus { address token = baseToken[_request.chainId]; if (token == ETH_TOKEN_ADDRESS) { - require(msg.value == _request.mintValue, "Bridgehub: msg.value mismatch 1"); + if (msg.value != _request.mintValue) { + revert MsgValueMismatch(_request.mintValue, msg.value); + } } else { - require(msg.value == 0, "Bridgehub: non-eth bridge with msg.value"); + if (msg.value != 0) { + revert MsgValueMismatch(0, msg.value); + } } // slither-disable-next-line arbitrary-send-eth @@ -294,13 +329,14 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus address token = baseToken[_request.chainId]; uint256 baseTokenMsgValue; if (token == ETH_TOKEN_ADDRESS) { - require( - msg.value == _request.mintValue + _request.secondBridgeValue, - "Bridgehub: msg.value mismatch 2" - ); + if (msg.value != _request.mintValue + _request.secondBridgeValue) { + revert MsgValueMismatch(_request.mintValue + _request.secondBridgeValue, msg.value); + } baseTokenMsgValue = _request.mintValue; } else { - require(msg.value == _request.secondBridgeValue, "Bridgehub: msg.value mismatch 3"); + if (msg.value != _request.secondBridgeValue) { + revert MsgValueMismatch(_request.secondBridgeValue, msg.value); + } baseTokenMsgValue = 0; } // slither-disable-next-line arbitrary-send-eth @@ -323,14 +359,16 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus _request.secondBridgeCalldata ); - require(outputRequest.magicValue == TWO_BRIDGES_MAGIC_VALUE, "Bridgehub: magic value mismatch"); + if (outputRequest.magicValue != TWO_BRIDGES_MAGIC_VALUE) { + revert WrongMagicValue(uint256(TWO_BRIDGES_MAGIC_VALUE), uint256(outputRequest.magicValue)); + } address refundRecipient = AddressAliasHelper.actualRefundRecipient(_request.refundRecipient, msg.sender); - require( - _request.secondBridgeAddress > BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS, - "Bridgehub: second bridge address too low" - ); // to avoid calls to precompiles + if (_request.secondBridgeAddress <= BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS) { + revert AddressTooLow(_request.secondBridgeAddress); + } + // to avoid calls to precompiles canonicalTxHash = IZkSyncHyperchain(hyperchain).bridgehubRequestL2Transaction( BridgehubL2TransactionRequest({ sender: _request.secondBridgeAddress, diff --git a/l1-contracts/contracts/bridgehub/IBridgehub.sol b/l1-contracts/contracts/bridgehub/IBridgehub.sol index 1204bc1d4..31c89f289 100644 --- a/l1-contracts/contracts/bridgehub/IBridgehub.sol +++ b/l1-contracts/contracts/bridgehub/IBridgehub.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol"; import {L2Message, L2Log, TxStatus} from "../common/Messaging.sol"; diff --git a/l1-contracts/contracts/common/Config.sol b/l1-contracts/contracts/common/Config.sol index 72ca11aa1..a39d27f97 100644 --- a/l1-contracts/contracts/common/Config.sol +++ b/l1-contracts/contracts/common/Config.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @dev `keccak256("")` bytes32 constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; diff --git a/l1-contracts/contracts/common/Dependencies.sol b/l1-contracts/contracts/common/Dependencies.sol index 6c4d46f2e..017b6177e 100644 --- a/l1-contracts/contracts/common/Dependencies.sol +++ b/l1-contracts/contracts/common/Dependencies.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /* solhint-disable-next-line no-unused-import */ -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; /* solhint-disable-next-line no-unused-import */ -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol"; diff --git a/l1-contracts/contracts/common/L1ContractErrors.sol b/l1-contracts/contracts/common/L1ContractErrors.sol new file mode 100644 index 000000000..73ff72cc9 --- /dev/null +++ b/l1-contracts/contracts/common/L1ContractErrors.sol @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.21; + +// 0x1ff9d522 +error AddressAlreadyUsed(address addr); +// 0x86bb51b8 +error AddressHasNoCode(address); +// 0x1eee5481 +error AddressTooLow(address); +// 0x6afd6c20 +error BadReturnData(); +// 0x6ef9a972 +error BaseTokenGasPriceDenominatorNotSet(); +// 0x55ad3fd3 +error BatchHashMismatch(bytes32 expected, bytes32 actual); +// 0x2078a6a0 +error BatchNotExecuted(uint256 batchNumber); +// 0xbd4455ff +error BatchNumberMismatch(uint256 expectedBatchNumber, uint256 providedBatchNumber); +// 0xafd53e2f +error BlobHashCommitmentError(uint256 index, bool blobHashEmpty, bool blobCommitmentEmpty); +// 0x6cf12312 +error BridgeHubAlreadyRegistered(); +// 0xcf102c5a +error CalldataLengthTooBig(); +// 0xe85392f9 +error CanOnlyProcessOneBatch(); +// 0x00c6ead2 +error CantExecuteUnprovenBatches(); +// 0xe18cb383 +error CantRevertExecutedBatch(); +// 0x78d2ed02 +error ChainAlreadyLive(); +// 0x8f620a06 +error ChainIdTooBig(); +// 0xf7a01e4d +error DelegateCallFailed(bytes returnData); +// 0x0a8ed92c +error DenominatorIsZero(); +// 0xc7c9660f +error DepositDoesNotExist(); +// 0xad2fa98e +error DepositExists(); +// 0x79cacff1 +error DepositFailed(); +// 0xae08e4af +error DepositIncorrectAmount(uint256 expectedAmt, uint256 providedAmt); +// 0x0e7ee319 +error DiamondAlreadyFrozen(); +// 0x682dabb4 +error DiamondFreezeIncorrectState(); +// 0xa7151b9a +error DiamondNotFrozen(); +// 0xfc7ab1d3 +error EmptyBlobVersionHash(uint256 index); +// 0x95b66fe9 +error EmptyDeposit(); +// 0xac4a3f98 +error FacetExists(bytes4 selector, address); +// 0x79e12cc3 +error FacetIsFrozen(bytes4 func); +// 0xc91cf3b1 +error GasPerPubdataMismatch(); +// 0x6d4a7df8 +error GenesisBatchCommitmentZero(); +// 0x7940c83f +error GenesisBatchHashZero(); +// 0xb4fc6835 +error GenesisIndexStorageZero(); +// 0x3a1a8589 +error GenesisUpgradeZero(); +// 0xd356e6ba +error HashedLogIsDefault(); +// 0x0b08d5be +error HashMismatch(bytes32 expected, bytes32 actual); +// 0xb615c2b1 +error HyperchainLimitReached(); +// 0x826fb11e +error InsufficientChainBalance(); +// 0x356680b7 +error InsufficientFunds(); +// 0x7a47c9a2 +error InvalidChainId(); +// 0x4fbe5dba +error InvalidDelay(); +// 0x0af806e0 +error InvalidHash(); +// 0xc1780bd6 +error InvalidLogSender(address sender, uint256 logKey); +// 0xd8e9405c +error InvalidNumberOfBlobs(uint256 expected, uint256 numCommitments, uint256 numHashes); +// 0x09bde339 +error InvalidProof(); +// 0x5428eae7 +error InvalidProtocolVersion(); +// 0x53e6d04d +error InvalidPubdataCommitmentsSize(); +// 0x5513177c +error InvalidPubdataHash(bytes32 expectedHash, bytes32 provided); +// 0x9094af7e +error InvalidPubdataLength(); +// 0xc5d09071 +error InvalidPubdataMode(); +// 0x6f1cf752 +error InvalidPubdataPricingMode(); +// 0x12ba286f +error InvalidSelector(bytes4 func); +// 0x5cb29523 +error InvalidTxType(uint256 txType); +// 0x5f1aa154 +error InvalidUpgradeTxn(UpgradeTxVerifyParam); +// 0xaa7feadc +error InvalidValue(); +// 0xa4f62e33 +error L2BridgeNotDeployed(uint256 chainId); +// 0xff8811ff +error L2BridgeNotSet(uint256 chainId); +// 0xcb5e4247 +error L2BytecodeHashMismatch(bytes32 expected, bytes32 provided); +// 0xfb5c22e6 +error L2TimestampTooBig(); +// 0xd2c011d6 +error L2UpgradeNonceNotEqualToNewProtocolVersion(uint256 nonce, uint256 protocolVersion); +// 0x97e1359e +error L2WithdrawalMessageWrongLength(uint256 messageLen); +// 0x32eb8b2f +error LegacyMethodIsSupportedOnlyForEra(); +// 0xe37d2c02 +error LengthIsNotDivisibleBy32(uint256 length); +// 0x1b6825bb +error LogAlreadyProcessed(uint8); +// 0x43e266b0 +error MalformedBytecode(BytecodeError); +// 0x59170bf0 +error MalformedCalldata(); +// 0x16509b9a +error MalformedMessage(); +// 0x9bb54c35 +error MerkleIndexOutOfBounds(); +// 0x8e23ac1a +error MerklePathEmpty(); +// 0x1c500385 +error MerklePathOutOfBounds(); +// 0xfa44b527 +error MissingSystemLogs(uint256 expected, uint256 actual); +// 0x4a094431 +error MsgValueMismatch(uint256 expectedMsgValue, uint256 providedMsgValue); +// 0xb385a3da +error MsgValueTooLow(uint256 required, uint256 provided); +// 0x72ea85ad +error NewProtocolMajorVersionNotZero(); +// 0x79cc2d22 +error NoCallsProvided(); +// 0xa6fef710 +error NoFunctionsForDiamondCut(); +// 0xcab098d8 +error NoFundsTransferred(); +// 0x92290acc +error NonEmptyBlobVersionHash(uint256 index); +// 0xc21b1ab7 +error NonEmptyCalldata(); +// 0x536ec84b +error NonEmptyMsgValue(); +// 0xd018e08e +error NonIncreasingTimestamp(); +// 0x0105f9c0 +error NonSequentialBatch(); +// 0x4ef79e5a +error NonZeroAddress(address); +// 0xdd629f86 +error NotEnoughGas(); +// 0xdd7e3621 +error NotInitializedReentrancyGuard(); +// 0xf3ed9dfa +error OnlyEraSupported(); +// 0x1a21feed +error OperationExists(); +// 0xeda2fbb1 +error OperationMustBePending(); +// 0xe1c1ff37 +error OperationMustBeReady(); +// 0xd7f50a9d +error PatchCantSetUpgradeTxn(); +// 0x962fd7d0 +error PatchUpgradeCantSetBootloader(); +// 0x559cc34e +error PatchUpgradeCantSetDefaultAccount(); +// 0x8d5851de +error PointEvalCallFailed(bytes); +// 0x4daa985d +error PointEvalFailed(bytes); +// 0x9b48e060 +error PreviousOperationNotExecuted(); +// 0x5c598b60 +error PreviousProtocolMajorVersionNotZero(); +// 0xa0f47245 +error PreviousUpgradeNotCleaned(); +// 0x101ba748 +error PreviousUpgradeNotFinalized(bytes32 txHash); +// 0xd5a99014 +error PriorityOperationsRollingHashMismatch(); +// 0x1a4d284a +error PriorityTxPubdataExceedsMaxPubDataPerBatch(); +// 0xa461f651 +error ProtocolIdMismatch(uint256 expectedProtocolVersion, uint256 providedProtocolId); +// 0x64f94ec2 +error ProtocolIdNotGreater(); +// 0xd328c12a +error ProtocolVersionMinorDeltaTooBig(uint256 limit, uint256 proposed); +// 0x88d7b498 +error ProtocolVersionTooSmall(); +// 0x53dee67b +error PubdataCommitmentsEmpty(); +// 0x7734c31a +error PubdataCommitmentsTooBig(); +// 0x959f26fb +error PubdataGreaterThanLimit(uint256 limit, uint256 length); +// 0x2a4a14df +error PubdataPerBatchIsLessThanTxn(); +// 0x63c36549 +error QueueIsEmpty(); +// 0xab143c06 +error Reentrancy(); +// 0x667d17de +error RemoveFunctionFacetAddressNotZero(address facet); +// 0xa2d4b16c +error RemoveFunctionFacetAddressZero(); +// 0x3580370c +error ReplaceFunctionFacetAddressZero(); +// 0xdab52f4b +error RevertedBatchBeforeNewBatch(); +// 0x9a67c1cb +error RevertedBatchNotAfterNewLastBatch(); +// 0xd3b6535b +error SelectorsMustAllHaveSameFreezability(); +// 0x7774d2f9 +error SharedBridgeValueNotSet(SharedBridgeKey); +// 0xc1d9246c +error SharedBridgeBalanceMismatch(); +// 0x856d5b77 +error SharedBridgeNotSet(); +// 0xcac5fc40 +error SharedBridgeValueAlreadySet(SharedBridgeKey); +// 0xdf3a8fdd +error SlotOccupied(); +// 0xd0bc70cf +error STMAlreadyRegistered(); +// 0x09865e10 +error STMNotRegistered(); +// 0xae43b424 +error SystemLogsSizeTooBig(); +// 0x08753982 +error TimeNotReached(uint256 expectedTimestamp, uint256 actualTimestamp); +// 0x2d50c33b +error TimestampError(); +// 0x4f4b634e +error TokenAlreadyRegistered(address token); +// 0xddef98d7 +error TokenNotRegistered(address token); +// 0x06439c6b +error TokenNotSupported(address token); +// 0x23830e28 +error TokensWithFeesNotSupported(); +// 0xf640f0e5 +error TooManyBlobs(); +// 0x76da24b9 +error TooManyFactoryDeps(); +// 0xf0b4e88f +error TooMuchGas(); +// 0x00c5a6a9 +error TransactionNotAllowed(); +// 0x4c991078 +error TxHashMismatch(); +// 0x2e311df8 +error TxnBodyGasLimitNotEnoughGas(); +// 0x8e4a23d6 +error Unauthorized(address caller); +// 0xe52478c7 +error UndefinedDiamondCutAction(); +// 0x07218375 +error UnexpectedNumberOfFactoryDeps(); +// 0x6aa39880 +error UnexpectedSystemLog(uint256 logKey); +// 0xf093c2e5 +error UpgradeBatchNumberIsNotZero(); +// 0x47b3b145 +error ValidateTxnNotEnoughGas(); +// 0x626ade30 +error ValueMismatch(uint256 expected, uint256 actual); +// 0xe1022469 +error VerifiedBatchesExceedsCommittedBatches(); +// 0x2dbdba00 +error VerifyProofCommittedVerifiedMismatch(); +// 0xae899454 +error WithdrawalAlreadyFinalized(); +// 0x27fcd9d1 +error WithdrawalFailed(); +// 0x750b219c +error WithdrawFailed(); +// 0x15e8e429 +error WrongMagicValue(uint256 expectedMagicValue, uint256 providedMagicValue); +// 0xd92e233d +error ZeroAddress(); +// 0x669567ea +error ZeroBalance(); +// 0xc84885d4 +error ZeroChainId(); + +enum SharedBridgeKey { + PostUpgradeFirstBatch, + LegacyBridgeFirstBatch, + LegacyBridgeLastDepositBatch, + LegacyBridgeLastDepositTxn +} + +enum BytecodeError { + Version, + NumberOfWords, + Length, + WordsMustBeOdd +} + +enum UpgradeTxVerifyParam { + From, + To, + Paymaster, + Value, + MaxFeePerGas, + MaxPriorityFeePerGas, + Reserved0, + Reserved1, + Reserved2, + Reserved3, + Signature, + PaymasterInput, + ReservedDynamic +} diff --git a/l1-contracts/contracts/common/L2ContractAddresses.sol b/l1-contracts/contracts/common/L2ContractAddresses.sol index 0becefe72..e8dbb1c83 100644 --- a/l1-contracts/contracts/common/L2ContractAddresses.sol +++ b/l1-contracts/contracts/common/L2ContractAddresses.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @dev The formal address of the initial program of the system: the bootloader address constant L2_BOOTLOADER_ADDRESS = address(0x8001); diff --git a/l1-contracts/contracts/common/Messaging.sol b/l1-contracts/contracts/common/Messaging.sol index 496760438..526d526dd 100644 --- a/l1-contracts/contracts/common/Messaging.sol +++ b/l1-contracts/contracts/common/Messaging.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @dev The enum that represents the transaction execution status /// @param Failure The transaction execution failed diff --git a/l1-contracts/contracts/common/ReentrancyGuard.sol b/l1-contracts/contracts/common/ReentrancyGuard.sol index 894f94f5e..7d3899658 100644 --- a/l1-contracts/contracts/common/ReentrancyGuard.sol +++ b/l1-contracts/contracts/common/ReentrancyGuard.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; -pragma solidity 0.8.24; - -// solhint-disable gas-custom-errors +import {SlotOccupied, NotInitializedReentrancyGuard, Reentrancy} from "./L1ContractErrors.sol"; /** * @custom:security-contact security@matterlabs.dev @@ -57,7 +57,9 @@ abstract contract ReentrancyGuard { } // Check that storage slot for reentrancy guard is empty to rule out possibility of slot conflict - require(lockSlotOldValue == 0, "1B"); + if (lockSlotOldValue != 0) { + revert SlotOccupied(); + } } /** @@ -73,8 +75,13 @@ abstract contract ReentrancyGuard { _status := sload(LOCK_FLAG_ADDRESS) } - // On the first call to nonReentrant, _notEntered will be true - require(_status == _NOT_ENTERED, "r1"); + if (_status == 0) { + revert NotInitializedReentrancyGuard(); + } + // On the first call to nonReentrant, _NOT_ENTERED will be true + if (_status != _NOT_ENTERED) { + revert Reentrancy(); + } // Any calls to nonReentrant after this point will fail assembly { diff --git a/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol index 31d796d45..99890dcca 100644 --- a/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol +++ b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /** * @author Matter Labs diff --git a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol index 808068d59..e21e7de72 100644 --- a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol +++ b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; -pragma solidity 0.8.24; - -// solhint-disable gas-custom-errors +import {BytecodeError, MalformedBytecode, LengthIsNotDivisibleBy32} from "../L1ContractErrors.sol"; /** * @author Matter Labs @@ -22,11 +22,19 @@ library L2ContractHelper { /// - Bytecode words length is not odd function hashL2Bytecode(bytes memory _bytecode) internal pure returns (bytes32 hashedBytecode) { // Note that the length of the bytecode must be provided in 32-byte words. - require(_bytecode.length % 32 == 0, "pq"); + if (_bytecode.length % 32 != 0) { + revert LengthIsNotDivisibleBy32(_bytecode.length); + } uint256 bytecodeLenInWords = _bytecode.length / 32; - require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words - require(bytecodeLenInWords % 2 == 1, "ps"); // bytecode length in words must be odd + // bytecode length must be less than 2^16 words + if (bytecodeLenInWords >= 2 ** 16) { + revert MalformedBytecode(BytecodeError.NumberOfWords); + } + // bytecode length in words must be odd + if (bytecodeLenInWords % 2 == 0) { + revert MalformedBytecode(BytecodeError.WordsMustBeOdd); + } hashedBytecode = sha256(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // Setting the version of the hash hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248))); @@ -40,9 +48,15 @@ library L2ContractHelper { /// @param _bytecodeHash The hash of the bytecode to validate. function validateBytecodeHash(bytes32 _bytecodeHash) internal pure { uint8 version = uint8(_bytecodeHash[0]); - require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash + // Incorrectly formatted bytecodeHash + if (version != 1 || _bytecodeHash[1] != bytes1(0)) { + revert MalformedBytecode(BytecodeError.Version); + } - require(bytecodeLen(_bytecodeHash) % 2 == 1, "uy"); // Code length in words must be odd + // Code length in words must be odd + if (bytecodeLen(_bytecodeHash) % 2 == 0) { + revert MalformedBytecode(BytecodeError.WordsMustBeOdd); + } } /// @notice Returns the length of the bytecode associated with the given hash. diff --git a/l1-contracts/contracts/common/libraries/SemVer.sol b/l1-contracts/contracts/common/libraries/SemVer.sol index d20f6a1d1..8d9fd10ac 100644 --- a/l1-contracts/contracts/common/libraries/SemVer.sol +++ b/l1-contracts/contracts/common/libraries/SemVer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @dev The number of bits dedicated to the "patch" portion of the protocol version. /// This also defines the bit starting from which the "minor" part is located. diff --git a/l1-contracts/contracts/common/libraries/UncheckedMath.sol b/l1-contracts/contracts/common/libraries/UncheckedMath.sol index 6adfabf17..91c3e652c 100644 --- a/l1-contracts/contracts/common/libraries/UncheckedMath.sol +++ b/l1-contracts/contracts/common/libraries/UncheckedMath.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /** * @author Matter Labs diff --git a/l1-contracts/contracts/common/libraries/UnsafeBytes.sol b/l1-contracts/contracts/common/libraries/UnsafeBytes.sol index 5f0647489..3b8fc3cb5 100644 --- a/l1-contracts/contracts/common/libraries/UnsafeBytes.sol +++ b/l1-contracts/contracts/common/libraries/UnsafeBytes.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /** * @author Matter Labs diff --git a/l1-contracts/contracts/dev-contracts/TestnetERC20Token.sol b/l1-contracts/contracts/dev-contracts/TestnetERC20Token.sol index 4eaddf921..2b189d1c9 100644 --- a/l1-contracts/contracts/dev-contracts/TestnetERC20Token.sol +++ b/l1-contracts/contracts/dev-contracts/TestnetERC20Token.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import {ERC20} from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; contract TestnetERC20Token is ERC20 { // add this to be excluded from coverage report diff --git a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol index a69f4c69b..bebdbe49d 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummySharedBridge.sol @@ -2,14 +2,12 @@ pragma solidity 0.8.24; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; import {TWO_BRIDGES_MAGIC_VALUE, ETH_TOKEN_ADDRESS} from "../../common/Config.sol"; -import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {UnsafeBytes} from "contracts/common/libraries/UnsafeBytes.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/security/PausableUpgradeable.sol"; +import {SafeERC20} from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import {IL2Bridge} from "../../bridge/interfaces/IL2Bridge.sol"; contract DummySharedBridge is PausableUpgradeable { diff --git a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol index b13050318..fba37465e 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import {EnumerableMap} from "@openzeppelin/contracts-v4/utils/structs/EnumerableMap.sol"; import {StateTransitionManager} from "../../state-transition/StateTransitionManager.sol"; diff --git a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol index 883d74ca1..5109f7b77 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import {EnumerableMap} from "@openzeppelin/contracts-v4/utils/structs/EnumerableMap.sol"; import {StateTransitionManager} from "../../state-transition/StateTransitionManager.sol"; diff --git a/l1-contracts/contracts/governance/ChainAdmin.sol b/l1-contracts/contracts/governance/ChainAdmin.sol index 874255d38..4d9ff858f 100644 --- a/l1-contracts/contracts/governance/ChainAdmin.sol +++ b/l1-contracts/contracts/governance/ChainAdmin.sol @@ -2,9 +2,10 @@ pragma solidity 0.8.24; -import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Ownable2Step} from "@openzeppelin/contracts-v4/access/Ownable2Step.sol"; import {IChainAdmin} from "./IChainAdmin.sol"; import {IAdmin} from "../state-transition/chain-interfaces/IAdmin.sol"; +import {NoCallsProvided, Unauthorized, ZeroAddress} from "../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -23,7 +24,9 @@ contract ChainAdmin is IChainAdmin, Ownable2Step { address public tokenMultiplierSetter; constructor(address _initialOwner, address _initialTokenMultiplierSetter) { - require(_initialOwner != address(0), "Initial owner should be non zero address"); + if (_initialOwner == address(0)) { + revert ZeroAddress(); + } _transferOwnership(_initialOwner); // Can be zero if no one has this permission. tokenMultiplierSetter = _initialTokenMultiplierSetter; @@ -50,7 +53,10 @@ contract ChainAdmin is IChainAdmin, Ownable2Step { /// @param _requireSuccess If true, reverts transaction on any call failure. /// @dev Intended for batch processing of contract interactions, managing gas efficiency and atomicity of operations. function multicall(Call[] calldata _calls, bool _requireSuccess) external payable onlyOwner { - require(_calls.length > 0, "No calls provided"); + if (_calls.length == 0) { + revert NoCallsProvided(); + } + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _calls.length; ++i) { // slither-disable-next-line arbitrary-send-eth (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data); @@ -69,7 +75,9 @@ contract ChainAdmin is IChainAdmin, Ownable2Step { /// @param _nominator The numerator part of the token multiplier. /// @param _denominator The denominator part of the token multiplier. function setTokenMultiplier(IAdmin _chainContract, uint128 _nominator, uint128 _denominator) external { - require(msg.sender == tokenMultiplierSetter, "Only the token multiplier setter can call this function"); + if (msg.sender != tokenMultiplierSetter) { + revert Unauthorized(msg.sender); + } _chainContract.setTokenMultiplier(_nominator, _denominator); } diff --git a/l1-contracts/contracts/governance/Governance.sol b/l1-contracts/contracts/governance/Governance.sol index 3f40721e9..45aa431da 100644 --- a/l1-contracts/contracts/governance/Governance.sol +++ b/l1-contracts/contracts/governance/Governance.sol @@ -2,10 +2,9 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors - -import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Ownable2Step} from "@openzeppelin/contracts-v4/access/Ownable2Step.sol"; import {IGovernance} from "./IGovernance.sol"; +import {ZeroAddress, Unauthorized, OperationMustBeReady, OperationMustBePending, OperationExists, InvalidDelay, PreviousOperationNotExecuted} from "../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -40,8 +39,11 @@ contract Governance is IGovernance, Ownable2Step { /// @param _admin The address to be assigned as the admin of the contract. /// @param _securityCouncil The address to be assigned as the security council of the contract. /// @param _minDelay The initial minimum delay (in seconds) to be set for operations. + /// @dev We allow for a zero address for _securityCouncil because it can be set later constructor(address _admin, address _securityCouncil, uint256 _minDelay) { - require(_admin != address(0), "Admin should be non zero address"); + if (_admin == address(0)) { + revert ZeroAddress(); + } _transferOwnership(_admin); @@ -58,25 +60,25 @@ contract Governance is IGovernance, Ownable2Step { /// @notice Checks that the message sender is contract itself. modifier onlySelf() { - // solhint-disable-next-line reason-string - require(msg.sender == address(this), "Only governance contract itself is allowed to call this function"); + if (msg.sender != address(this)) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks that the message sender is an active security council. modifier onlySecurityCouncil() { - // solhint-disable-next-line reason-string - require(msg.sender == securityCouncil, "Only security council is allowed to call this function"); + if (msg.sender != securityCouncil) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks that the message sender is an active owner or an active security council. modifier onlyOwnerOrSecurityCouncil() { - // solhint-disable-next-line reason-string - require( - msg.sender == owner() || msg.sender == securityCouncil, - "Only the owner and security council are allowed to call this function" - ); + if (msg.sender != owner() && msg.sender != securityCouncil) { + revert Unauthorized(msg.sender); + } _; } @@ -157,7 +159,9 @@ contract Governance is IGovernance, Ownable2Step { /// @dev Only owner can call this function. /// @param _id Proposal id value (see `hashOperation`) function cancel(bytes32 _id) external onlyOwner { - require(isOperationPending(_id), "Operation must be pending"); + if (!isOperationPending(_id)) { + revert OperationMustBePending(); + } delete timestamps[_id]; emit OperationCancelled(_id); } @@ -175,15 +179,17 @@ contract Governance is IGovernance, Ownable2Step { // Check if the predecessor operation is completed. _checkPredecessorDone(_operation.predecessor); // Ensure that the operation is ready to proceed. - // solhint-disable-next-line reason-string - require(isOperationReady(id), "Operation must be ready before execution"); + if (!isOperationReady(id)) { + revert OperationMustBeReady(); + } // Execute operation. // slither-disable-next-line reentrancy-eth _execute(_operation.calls); // Reconfirming that the operation is still ready after execution. // This is needed to avoid unexpected reentrancy attacks of re-executing the same operation. - // solhint-disable-next-line reason-string - require(isOperationReady(id), "Operation must be ready after execution"); + if (!isOperationReady(id)) { + revert OperationMustBeReady(); + } // Set operation to be done timestamps[id] = EXECUTED_PROPOSAL_TIMESTAMP; emit OperationExecuted(id); @@ -198,15 +204,17 @@ contract Governance is IGovernance, Ownable2Step { // Check if the predecessor operation is completed. _checkPredecessorDone(_operation.predecessor); // Ensure that the operation is in a pending state before proceeding. - // solhint-disable-next-line reason-string - require(isOperationPending(id), "Operation must be pending before execution"); + if (!isOperationPending(id)) { + revert OperationMustBePending(); + } // Execute operation. // slither-disable-next-line reentrancy-eth _execute(_operation.calls); // Reconfirming that the operation is still pending before execution. // This is needed to avoid unexpected reentrancy attacks of re-executing the same operation. - // solhint-disable-next-line reason-string - require(isOperationPending(id), "Operation must be pending after execution"); + if (!isOperationPending(id)) { + revert OperationMustBePending(); + } // Set operation to be done timestamps[id] = EXECUTED_PROPOSAL_TIMESTAMP; emit OperationExecuted(id); @@ -226,10 +234,12 @@ contract Governance is IGovernance, Ownable2Step { /// @param _id The operation hash (see `hashOperation` function) /// @param _delay The delay time (in seconds) after which the proposed upgrade can be executed by the owner. function _schedule(bytes32 _id, uint256 _delay) internal { - // solhint-disable reason-string - require(!isOperation(_id), "Operation with this proposal id already exists"); - require(_delay >= minDelay, "Proposed delay is less than minimum delay"); - // solhint-enable reason-string + if (isOperation(_id)) { + revert OperationExists(); + } + if (_delay < minDelay) { + revert InvalidDelay(); + } timestamps[_id] = block.timestamp + _delay; } @@ -237,6 +247,7 @@ contract Governance is IGovernance, Ownable2Step { /// @dev Execute an operation's calls. /// @param _calls The array of calls to be executed. function _execute(Call[] calldata _calls) internal { + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _calls.length; ++i) { // slither-disable-next-line arbitrary-send-eth @@ -254,8 +265,9 @@ contract Governance is IGovernance, Ownable2Step { /// @param _predecessorId The hash of the operation that should be completed. /// @dev Doesn't check the operation to be complete if the input is zero. function _checkPredecessorDone(bytes32 _predecessorId) internal view { - // solhint-disable-next-line reason-string - require(_predecessorId == bytes32(0) || isOperationDone(_predecessorId), "Predecessor operation not completed"); + if (_predecessorId != bytes32(0) && !isOperationDone(_predecessorId)) { + revert PreviousOperationNotExecuted(); + } } /*////////////////////////////////////////////////////////////// diff --git a/l1-contracts/contracts/governance/IGovernance.sol b/l1-contracts/contracts/governance/IGovernance.sol index 2b0228203..e2a600175 100644 --- a/l1-contracts/contracts/governance/IGovernance.sol +++ b/l1-contracts/contracts/governance/IGovernance.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @title Governance contract interface /// @author Matter Labs diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index 8743a4f82..d0111cf82 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {Diamond} from "./libraries/Diamond.sol"; import {L2CanonicalTransaction} from "../common/Messaging.sol"; @@ -121,7 +121,7 @@ interface IStateTransitionManager { function setNewVersionUpgrade( Diamond.DiamondCutData calldata _cutData, uint256 _oldProtocolVersion, - uint256 _oldprotocolVersionDeadline, + uint256 _oldProtocolVersionDeadline, uint256 _newProtocolVersion ) external; diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index 9ac15cf19..0dbdd2ad1 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -2,10 +2,8 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors, reason-string - -import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {EnumerableMap} from "@openzeppelin/contracts-v4/utils/structs/EnumerableMap.sol"; +import {SafeCast} from "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; import {Diamond} from "./libraries/Diamond.sol"; import {DiamondProxy} from "./chain-deps/DiamondProxy.sol"; @@ -19,11 +17,12 @@ import {IZkSyncHyperchain} from "./chain-interfaces/IZkSyncHyperchain.sol"; import {FeeParams} from "./chain-deps/ZkSyncHyperchainStorage.sol"; import {L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, L2_FORCE_DEPLOYER_ADDR} from "../common/L2ContractAddresses.sol"; import {L2CanonicalTransaction} from "../common/Messaging.sol"; -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/access/Ownable2StepUpgradeable.sol"; import {ProposedUpgrade} from "../upgrades/BaseZkSyncUpgrade.sol"; import {ReentrancyGuard} from "../common/ReentrancyGuard.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, L2_TO_L1_LOG_SERIALIZE_SIZE, DEFAULT_L2_LOGS_TREE_ROOT_HASH, EMPTY_STRING_KECCAK, SYSTEM_UPGRADE_L2_TX_TYPE, PRIORITY_TX_MAX_GAS_LIMIT} from "../common/Config.sol"; import {VerifierParams} from "./chain-interfaces/IVerifier.sol"; +import {Unauthorized, ZeroAddress, HashMismatch, HyperchainLimitReached, GenesisUpgradeZero, GenesisBatchHashZero, GenesisIndexStorageZero, GenesisBatchCommitmentZero} from "../common/L1ContractErrors.sol"; import {SemVer} from "../common/libraries/SemVer.sol"; /// @title State Transition Manager contract @@ -82,13 +81,17 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @notice only the bridgehub can call modifier onlyBridgehub() { - require(msg.sender == BRIDGE_HUB, "STM: only bridgehub"); + if (msg.sender != BRIDGE_HUB) { + revert Unauthorized(msg.sender); + } _; } /// @notice the admin can call, for non-critical updates modifier onlyOwnerOrAdmin() { - require(msg.sender == admin || msg.sender == owner(), "STM: not owner or admin"); + if (msg.sender != admin && msg.sender != owner()) { + revert Unauthorized(msg.sender); + } _; } @@ -104,7 +107,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own chainAddresses = new address[](keys.length); uint256 keysLength = keys.length; for (uint256 i = 0; i < keysLength; ++i) { - chainAddresses[i] = hyperchainMap.get(i); + chainAddresses[i] = hyperchainMap.get(keys[i]); } } @@ -128,7 +131,9 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own function initialize( StateTransitionManagerInitializeData calldata _initializeData ) external reentrancyGuardInitializer { - require(_initializeData.owner != address(0), "STM: owner zero"); + if (_initializeData.owner == address(0)) { + revert ZeroAddress(); + } _transferOwnership(_initializeData.owner); protocolVersion = _initializeData.protocolVersion; @@ -141,13 +146,18 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @notice Updates the parameters with which a new chain is created /// @param _chainCreationParams The new chain creation parameters function _setChainCreationParams(ChainCreationParams calldata _chainCreationParams) internal { - require(_chainCreationParams.genesisUpgrade != address(0), "STM: genesisUpgrade zero"); - require(_chainCreationParams.genesisBatchHash != bytes32(0), "STM: genesisBatchHash zero"); - require( - _chainCreationParams.genesisIndexRepeatedStorageChanges != uint64(0), - "STM: genesisIndexRepeatedStorageChanges zero" - ); - require(_chainCreationParams.genesisBatchCommitment != bytes32(0), "STM: genesisBatchCommitment zero"); + if (_chainCreationParams.genesisUpgrade == address(0)) { + revert GenesisUpgradeZero(); + } + if (_chainCreationParams.genesisBatchHash == bytes32(0)) { + revert GenesisBatchHashZero(); + } + if (_chainCreationParams.genesisIndexRepeatedStorageChanges == uint64(0)) { + revert GenesisIndexStorageZero(); + } + if (_chainCreationParams.genesisBatchCommitment == bytes32(0)) { + revert GenesisBatchCommitmentZero(); + } genesisUpgrade = _chainCreationParams.genesisUpgrade; @@ -197,7 +207,10 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. function acceptAdmin() external { address currentPendingAdmin = pendingAdmin; - require(msg.sender == currentPendingAdmin, "n42"); // Only proposed by current admin address can claim the admin rights + // Only proposed by current admin address can claim the admin rights + if (msg.sender != currentPendingAdmin) { + revert Unauthorized(msg.sender); + } address previousAdmin = admin; admin = currentPendingAdmin; @@ -370,7 +383,9 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @param _chainId the chain's id /// @param _hyperchain the chain's contract address function registerAlreadyDeployedHyperchain(uint256 _chainId, address _hyperchain) external onlyOwner { - require(_hyperchain != address(0), "STM: hyperchain zero"); + if (_hyperchain == address(0)) { + revert ZeroAddress(); + } _registerNewHyperchain(_chainId, _hyperchain); } @@ -398,7 +413,9 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own // check input bytes32 cutHashInput = keccak256(_diamondCut); - require(cutHashInput == initialCutHash, "STM: initial cutHash mismatch"); + if (cutHashInput != initialCutHash) { + revert HashMismatch(initialCutHash, cutHashInput); + } // construct init data bytes memory initData; @@ -409,12 +426,12 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own bytes32(_chainId), bytes32(uint256(uint160(BRIDGE_HUB))), bytes32(uint256(uint160(address(this)))), - bytes32(uint256(protocolVersion)), + bytes32(protocolVersion), bytes32(uint256(uint160(_admin))), bytes32(uint256(uint160(validatorTimelock))), bytes32(uint256(uint160(_baseToken))), bytes32(uint256(uint160(_sharedBridge))), - bytes32(storedBatchZero), + storedBatchZero, diamondCut.initCalldata ); @@ -435,7 +452,9 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own function _registerNewHyperchain(uint256 _chainId, address _hyperchain) internal { // slither-disable-next-line unused-return hyperchainMap.set(_chainId, _hyperchain); - require(hyperchainMap.length() <= MAX_NUMBER_OF_HYPERCHAINS, "STM: Hyperchain limit reached"); + if (hyperchainMap.length() > MAX_NUMBER_OF_HYPERCHAINS) { + revert HyperchainLimitReached(); + } emit NewHyperchain(_chainId, _hyperchain); } } diff --git a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol index 396276306..32d92b7b1 100644 --- a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol +++ b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol @@ -2,12 +2,11 @@ pragma solidity 0.8.24; -// solhint-disable reason-string, gas-custom-errors - -import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Ownable2Step} from "@openzeppelin/contracts-v4/access/Ownable2Step.sol"; import {LibMap} from "./libraries/LibMap.sol"; import {IExecutor} from "./chain-interfaces/IExecutor.sol"; import {IStateTransitionManager} from "./IStateTransitionManager.sol"; +import {Unauthorized, TimeNotReached, ZeroAddress} from "../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -64,18 +63,25 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { /// @notice Checks if the caller is the admin of the chain. modifier onlyChainAdmin(uint256 _chainId) { - require(msg.sender == stateTransitionManager.getChainAdmin(_chainId), "ValidatorTimelock: only chain admin"); + if (msg.sender != stateTransitionManager.getChainAdmin(_chainId)) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks if the caller is a validator. modifier onlyValidator(uint256 _chainId) { - require(validators[_chainId][msg.sender], "ValidatorTimelock: only validator"); + if (!validators[_chainId][msg.sender]) { + revert Unauthorized(msg.sender); + } _; } /// @dev Sets a new state transition manager. function setStateTransitionManager(IStateTransitionManager _stateTransitionManager) external onlyOwner { + if (address(_stateTransitionManager) == address(0)) { + revert ZeroAddress(); + } stateTransitionManager = _stateTransitionManager; } @@ -132,6 +138,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { // This contract is only a temporary solution, that hopefully will be disabled until 2106 year, so... // It is safe to cast. uint32 timestamp = uint32(block.timestamp); + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; ++i) { committedBatchTimestamp[_chainId].set(_newBatchesData[i].batchNumber, timestamp); @@ -196,6 +203,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { function _executeBatchesInner(uint256 _chainId, StoredBatchInfo[] calldata _newBatchesData) internal { uint256 delay = executionDelay; // uint32 unchecked { + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; ++i) { uint256 commitBatchTimestamp = committedBatchTimestamp[_chainId].get(_newBatchesData[i].batchNumber); @@ -205,7 +213,9 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { // * The batch wasn't committed at all, so execution will fail in the zkSync contract. // We allow executing such batches. - require(block.timestamp >= commitBatchTimestamp + delay, "5c"); // The delay is not passed + if (block.timestamp < commitBatchTimestamp + delay) { + revert TimeNotReached(commitBatchTimestamp + delay, block.timestamp); + } } } _propagateToZkSyncHyperchain(_chainId); diff --git a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol index 145056590..663cf260a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol @@ -2,12 +2,11 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors - import {Diamond} from "../libraries/Diamond.sol"; import {ZkSyncHyperchainBase} from "./facets/ZkSyncHyperchainBase.sol"; import {L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_GAS_PER_TRANSACTION} from "../../common/Config.sol"; import {InitializeData, IDiamondInit} from "../chain-interfaces/IDiamondInit.sol"; +import {ZeroAddress, TooMuchGas} from "../../common/L1ContractErrors.sol"; /// @author Matter Labs /// @dev The contract is used only once to initialize the diamond proxy. @@ -20,15 +19,33 @@ contract DiamondInit is ZkSyncHyperchainBase, IDiamondInit { /// @return Magic 32 bytes, which indicates that the contract logic is expected to be used as a diamond proxy /// initializer function initialize(InitializeData calldata _initializeData) external reentrancyGuardInitializer returns (bytes32) { - require(address(_initializeData.verifier) != address(0), "vt"); - require(_initializeData.admin != address(0), "vy"); - require(_initializeData.validatorTimelock != address(0), "hc"); - require(_initializeData.priorityTxMaxGasLimit <= MAX_GAS_PER_TRANSACTION, "vu"); - require(_initializeData.bridgehub != address(0), "DiamondInit: b0"); - require(_initializeData.stateTransitionManager != address(0), "DiamondInit: stm0"); - require(_initializeData.baseToken != address(0), "DiamondInit: bt0"); - require(_initializeData.baseTokenBridge != address(0), "DiamondInit: btb0"); - require(_initializeData.blobVersionedHashRetriever != address(0), "DiamondInit: bvhr0"); + if (address(_initializeData.verifier) == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.admin == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.validatorTimelock == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.priorityTxMaxGasLimit > MAX_GAS_PER_TRANSACTION) { + revert TooMuchGas(); + } + if (_initializeData.bridgehub == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.stateTransitionManager == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.baseToken == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.baseTokenBridge == address(0)) { + revert ZeroAddress(); + } + if (_initializeData.blobVersionedHashRetriever == address(0)) { + revert ZeroAddress(); + } s.chainId = _initializeData.chainId; s.bridgehub = _initializeData.bridgehub; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol index fd1f4929a..9f98c00ec 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol @@ -2,14 +2,13 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors, reason-string - import {IAdmin} from "../../chain-interfaces/IAdmin.sol"; import {Diamond} from "../../libraries/Diamond.sol"; import {MAX_GAS_PER_TRANSACTION} from "../../../common/Config.sol"; import {FeeParams, PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {IStateTransitionManager} from "../../IStateTransitionManager.sol"; +import {Unauthorized, TooMuchGas, PriorityTxPubdataExceedsMaxPubDataPerBatch, InvalidPubdataPricingMode, ProtocolIdMismatch, ChainAlreadyLive, HashMismatch, ProtocolIdNotGreater, DenominatorIsZero, DiamondAlreadyFrozen, DiamondNotFrozen} from "../../../common/L1ContractErrors.sol"; // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; @@ -33,7 +32,10 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { /// @inheritdoc IAdmin function acceptAdmin() external { address pendingAdmin = s.pendingAdmin; - require(msg.sender == pendingAdmin, "n4"); // Only proposed by current admin address can claim the admin rights + // Only proposed by current admin address can claim the admin rights + if (msg.sender != pendingAdmin) { + revert Unauthorized(msg.sender); + } address previousAdmin = s.admin; s.admin = pendingAdmin; @@ -58,7 +60,9 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { /// @inheritdoc IAdmin function setPriorityTxMaxGasLimit(uint256 _newPriorityTxMaxGasLimit) external onlyStateTransitionManager { - require(_newPriorityTxMaxGasLimit <= MAX_GAS_PER_TRANSACTION, "n5"); + if (_newPriorityTxMaxGasLimit > MAX_GAS_PER_TRANSACTION) { + revert TooMuchGas(); + } uint256 oldPriorityTxMaxGasLimit = s.priorityTxMaxGasLimit; s.priorityTxMaxGasLimit = _newPriorityTxMaxGasLimit; @@ -69,11 +73,16 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { function changeFeeParams(FeeParams calldata _newFeeParams) external onlyAdminOrStateTransitionManager { // Double checking that the new fee params are valid, i.e. // the maximal pubdata per batch is not less than the maximal pubdata per priority transaction. - require(_newFeeParams.maxPubdataPerBatch >= _newFeeParams.priorityTxMaxPubdata, "n6"); + if (_newFeeParams.maxPubdataPerBatch < _newFeeParams.priorityTxMaxPubdata) { + revert PriorityTxPubdataExceedsMaxPubDataPerBatch(); + } FeeParams memory oldFeeParams = s.feeParams; - require(_newFeeParams.pubdataPricingMode == oldFeeParams.pubdataPricingMode, "n7"); // we cannot change pubdata pricing mode + // we cannot change pubdata pricing mode + if (_newFeeParams.pubdataPricingMode != oldFeeParams.pubdataPricingMode) { + revert InvalidPubdataPricingMode(); + } s.feeParams = _newFeeParams; @@ -82,7 +91,9 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { /// @inheritdoc IAdmin function setTokenMultiplier(uint128 _nominator, uint128 _denominator) external onlyAdminOrStateTransitionManager { - require(_denominator != 0, "AF: denominator 0"); + if (_denominator == 0) { + revert DenominatorIsZero(); + } uint128 oldNominator = s.baseTokenGasPriceMultiplierNominator; uint128 oldDenominator = s.baseTokenGasPriceMultiplierDenominator; @@ -94,7 +105,10 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { /// @inheritdoc IAdmin function setPubdataPricingMode(PubdataPricingMode _pricingMode) external onlyAdmin { - require(s.totalBatchesCommitted == 0, "AdminFacet: set validium only after genesis"); // Validium mode can be set only before the first batch is processed + // Validium mode can be set only before the first batch is processed + if (s.totalBatchesCommitted != 0) { + revert ChainAlreadyLive(); + } s.feeParams.pubdataPricingMode = _pricingMode; emit ValidiumModeStatusUpdate(_pricingMode); } @@ -115,15 +129,19 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { Diamond.DiamondCutData calldata _diamondCut ) external onlyAdminOrStateTransitionManager { bytes32 cutHashInput = keccak256(abi.encode(_diamondCut)); - require( - cutHashInput == IStateTransitionManager(s.stateTransitionManager).upgradeCutHash(_oldProtocolVersion), - "AdminFacet: cutHash mismatch" - ); - - require(s.protocolVersion == _oldProtocolVersion, "AdminFacet: protocolVersion mismatch in STC when upgrading"); + bytes32 upgradeCutHash = IStateTransitionManager(s.stateTransitionManager).upgradeCutHash(_oldProtocolVersion); + if (cutHashInput != upgradeCutHash) { + revert HashMismatch(upgradeCutHash, cutHashInput); + } + + if (s.protocolVersion != _oldProtocolVersion) { + revert ProtocolIdMismatch(s.protocolVersion, _oldProtocolVersion); + } Diamond.diamondCut(_diamondCut); emit ExecuteUpgrade(_diamondCut); - require(s.protocolVersion > _oldProtocolVersion, "AdminFacet: protocolVersion mismatch in STC after upgrading"); + if (s.protocolVersion <= _oldProtocolVersion) { + revert ProtocolIdNotGreater(); + } } /// @inheritdoc IAdmin @@ -140,7 +158,10 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { function freezeDiamond() external onlyStateTransitionManager { Diamond.DiamondStorage storage diamondStorage = Diamond.getDiamondStorage(); - require(!diamondStorage.isFrozen, "a9"); // diamond proxy is frozen already + // diamond proxy is frozen already + if (diamondStorage.isFrozen) { + revert DiamondAlreadyFrozen(); + } diamondStorage.isFrozen = true; emit Freeze(); @@ -150,7 +171,10 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { function unfreezeDiamond() external onlyStateTransitionManager { Diamond.DiamondStorage storage diamondStorage = Diamond.getDiamondStorage(); - require(diamondStorage.isFrozen, "a7"); // diamond proxy is not frozen + // diamond proxy is not frozen + if (!diamondStorage.isFrozen) { + revert DiamondNotFrozen(); + } diamondStorage.isFrozen = false; emit Unfreeze(); diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 217e08a1a..f47870345 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -2,8 +2,6 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors, reason-string - import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER, COMMIT_TIMESTAMP_APPROXIMATION_DELTA, EMPTY_STRING_KECCAK, L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, PACKED_L2_BLOCK_TIMESTAMP_MASK, PUBLIC_INPUT_SHIFT, POINT_EVALUATION_PRECOMPILE_ADDR} from "../../../common/Config.sol"; import {IExecutor, L2_LOG_ADDRESS_OFFSET, L2_LOG_KEY_OFFSET, L2_LOG_VALUE_OFFSET, SystemLogKey, LogProcessingOutput, PubdataSource, BLS_MODULUS, PUBDATA_COMMITMENT_SIZE, PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET, PUBDATA_COMMITMENT_COMMITMENT_OFFSET, MAX_NUMBER_OF_BLOBS, TOTAL_BLOBS_IN_COMMITMENT, BLOB_SIZE_BYTES} from "../../chain-interfaces/IExecutor.sol"; @@ -13,6 +11,7 @@ import {UnsafeBytes} from "../../../common/libraries/UnsafeBytes.sol"; import {L2_BOOTLOADER_ADDRESS, L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, L2_PUBDATA_CHUNK_PUBLISHER_ADDR} from "../../../common/L2ContractAddresses.sol"; import {PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; import {IStateTransitionManager} from "../../IStateTransitionManager.sol"; +import {BatchNumberMismatch, TimeNotReached, TooManyBlobs, ValueMismatch, InvalidPubdataMode, InvalidPubdataLength, HashMismatch, NonIncreasingTimestamp, TimestampError, InvalidLogSender, TxHashMismatch, UnexpectedSystemLog, MissingSystemLogs, LogAlreadyProcessed, InvalidProtocolVersion, CanOnlyProcessOneBatch, BatchHashMismatch, UpgradeBatchNumberIsNotZero, NonSequentialBatch, CantExecuteUnprovenBatches, SystemLogsSizeTooBig, InvalidNumberOfBlobs, VerifiedBatchesExceedsCommittedBatches, InvalidProof, RevertedBatchNotAfterNewLastBatch, CantRevertExecutedBatch, PointEvalFailed, EmptyBlobVersionHash, NonEmptyBlobVersionHash, BlobHashCommitmentError, CalldataLengthTooBig, InvalidPubdataHash, L2TimestampTooBig, PriorityOperationsRollingHashMismatch, PubdataCommitmentsEmpty, PointEvalCallFailed, PubdataCommitmentsTooBig, InvalidPubdataCommitmentsSize} from "../../../common/L1ContractErrors.sol"; // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; @@ -35,16 +34,20 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { CommitBatchInfo calldata _newBatch, bytes32 _expectedSystemContractUpgradeTxHash ) internal view returns (StoredBatchInfo memory) { - require(_newBatch.batchNumber == _previousBatch.batchNumber + 1, "f"); // only commit next batch + // only commit next batch + if (_newBatch.batchNumber != _previousBatch.batchNumber + 1) { + revert BatchNumberMismatch(_previousBatch.batchNumber + 1, _newBatch.batchNumber); + } uint8 pubdataSource = uint8(bytes1(_newBatch.pubdataCommitments[0])); PubdataPricingMode pricingMode = s.feeParams.pubdataPricingMode; - require( - pricingMode == PubdataPricingMode.Validium || - pubdataSource == uint8(PubdataSource.Calldata) || - pubdataSource == uint8(PubdataSource.Blob), - "us" - ); + if ( + pricingMode != PubdataPricingMode.Validium && + pubdataSource != uint8(PubdataSource.Calldata) && + pubdataSource != uint8(PubdataSource.Blob) + ) { + revert InvalidPubdataMode(); + } // Check that batch contain all meta information for L2 logs. // Get the chained hash of priority transaction hashes. @@ -53,7 +56,9 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { bytes32[] memory blobCommitments = new bytes32[](MAX_NUMBER_OF_BLOBS); if (pricingMode == PubdataPricingMode.Validium) { // skipping data validation for validium, we just check that the data is empty - require(_newBatch.pubdataCommitments.length == 1, "EF: v0l"); + if (_newBatch.pubdataCommitments.length != 1) { + revert CalldataLengthTooBig(); + } for (uint8 i = uint8(SystemLogKey.BLOB_ONE_HASH_KEY); i <= uint8(SystemLogKey.BLOB_SIX_HASH_KEY); ++i) { logOutput.blobHashes[i - uint8(SystemLogKey.BLOB_ONE_HASH_KEY)] = bytes32(0); } @@ -62,12 +67,13 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { blobCommitments = _verifyBlobInformation(_newBatch.pubdataCommitments[1:], logOutput.blobHashes); } else if (pubdataSource == uint8(PubdataSource.Calldata)) { // In this scenario pubdataCommitments is actual pubdata consisting of l2 to l1 logs, l2 to l1 message, compressed smart contract bytecode, and compressed state diffs - require(_newBatch.pubdataCommitments.length <= BLOB_SIZE_BYTES, "cz"); - require( - logOutput.pubdataHash == - keccak256(_newBatch.pubdataCommitments[1:_newBatch.pubdataCommitments.length - 32]), - "wp" - ); + if (_newBatch.pubdataCommitments.length > BLOB_SIZE_BYTES) { + revert InvalidPubdataLength(); + } + bytes32 pubdataHash = keccak256(_newBatch.pubdataCommitments[1:_newBatch.pubdataCommitments.length - 32]); + if (logOutput.pubdataHash != pubdataHash) { + revert InvalidPubdataHash(pubdataHash, logOutput.pubdataHash); + } blobCommitments[0] = bytes32( _newBatch.pubdataCommitments[_newBatch.pubdataCommitments.length - 32:_newBatch .pubdataCommitments @@ -75,11 +81,17 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { ); } - require(_previousBatch.batchHash == logOutput.previousBatchHash, "l"); + if (_previousBatch.batchHash != logOutput.previousBatchHash) { + revert HashMismatch(logOutput.previousBatchHash, _previousBatch.batchHash); + } // Check that the priority operation hash in the L2 logs is as expected - require(logOutput.chainedPriorityTxsHash == _newBatch.priorityOperationsHash, "t"); + if (logOutput.chainedPriorityTxsHash != _newBatch.priorityOperationsHash) { + revert HashMismatch(logOutput.chainedPriorityTxsHash, _newBatch.priorityOperationsHash); + } // Check that the number of processed priority operations is as expected - require(logOutput.numberOfLayer1Txs == _newBatch.numberOfLayer1Txs, "ta"); + if (logOutput.numberOfLayer1Txs != _newBatch.numberOfLayer1Txs) { + revert ValueMismatch(logOutput.numberOfLayer1Txs, _newBatch.numberOfLayer1Txs); + } // Check the timestamp of the new batch _verifyBatchTimestamp(logOutput.packedBatchAndL2BlockTimestamp, _newBatch.timestamp, _previousBatch.timestamp); @@ -116,11 +128,15 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { ) internal view { // Check that the timestamp that came from the system context is expected uint256 batchTimestamp = _packedBatchAndL2BlockTimestamp >> 128; - require(batchTimestamp == _expectedBatchTimestamp, "tb"); + if (batchTimestamp != _expectedBatchTimestamp) { + revert TimestampError(); + } // While the fact that _previousBatchTimestamp < batchTimestamp is already checked on L2, // we double check it here for clarity - require(_previousBatchTimestamp < batchTimestamp, "h3"); + if (_previousBatchTimestamp >= batchTimestamp) { + revert NonIncreasingTimestamp(); + } uint256 lastL2BlockTimestamp = _packedBatchAndL2BlockTimestamp & PACKED_L2_BLOCK_TIMESTAMP_MASK; @@ -128,8 +144,14 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // So here we need to only double check that: // - The timestamp of the batch is not too small. // - The timestamp of the last L2 block is not too big. - require(block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER <= batchTimestamp, "h1"); // New batch timestamp is too small - require(lastL2BlockTimestamp <= block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA, "h2"); // The last L2 block timestamp is too big + // New batch timestamp is too small + if (block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER > batchTimestamp) { + revert TimeNotReached(batchTimestamp, block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER); + } + // The last L2 block timestamp is too big + if (lastL2BlockTimestamp > block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA) { + revert L2TimestampTooBig(); + } } /// @dev Check that L2 logs are proper and batch contain all meta information for them @@ -147,7 +169,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // Used as bitmap to set/check log processing happens exactly once. // See SystemLogKey enum in Constants.sol for ordering. - uint256 processedLogs; + uint256 processedLogs = 0; // linear traversal of the logs uint256 logsLength = emittedL2Logs.length; @@ -161,47 +183,69 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { (bytes32 logValue, ) = UnsafeBytes.readBytes32(emittedL2Logs, i + L2_LOG_VALUE_OFFSET); // Ensure that the log hasn't been processed already - require(!_checkBit(processedLogs, uint8(logKey)), "kp"); + if (_checkBit(processedLogs, uint8(logKey))) { + revert LogAlreadyProcessed(uint8(logKey)); + } processedLogs = _setBit(processedLogs, uint8(logKey)); // Need to check that each log was sent by the correct address. if (logKey == uint256(SystemLogKey.L2_TO_L1_LOGS_TREE_ROOT_KEY)) { - require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm"); + if (logSender != L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR) { + revert InvalidLogSender(logSender, logKey); + } logOutput.l2LogsTreeRoot = logValue; } else if (logKey == uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)) { - require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln"); + if (logSender != L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR) { + revert InvalidLogSender(logSender, logKey); + } logOutput.pubdataHash = logValue; } else if (logKey == uint256(SystemLogKey.STATE_DIFF_HASH_KEY)) { - require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb"); + if (logSender != L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR) { + revert InvalidLogSender(logSender, logKey); + } logOutput.stateDiffHash = logValue; } else if (logKey == uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY)) { - require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sc"); + if (logSender != L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR) { + revert InvalidLogSender(logSender, logKey); + } logOutput.packedBatchAndL2BlockTimestamp = uint256(logValue); } else if (logKey == uint256(SystemLogKey.PREV_BATCH_HASH_KEY)) { - require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sv"); + if (logSender != L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR) { + revert InvalidLogSender(logSender, logKey); + } logOutput.previousBatchHash = logValue; } else if (logKey == uint256(SystemLogKey.CHAINED_PRIORITY_TXN_HASH_KEY)) { - require(logSender == L2_BOOTLOADER_ADDRESS, "bl"); + if (logSender != L2_BOOTLOADER_ADDRESS) { + revert InvalidLogSender(logSender, logKey); + } logOutput.chainedPriorityTxsHash = logValue; } else if (logKey == uint256(SystemLogKey.NUMBER_OF_LAYER_1_TXS_KEY)) { - require(logSender == L2_BOOTLOADER_ADDRESS, "bk"); + if (logSender != L2_BOOTLOADER_ADDRESS) { + revert InvalidLogSender(logSender, logKey); + } logOutput.numberOfLayer1Txs = uint256(logValue); } else if ( logKey >= uint256(SystemLogKey.BLOB_ONE_HASH_KEY) && logKey <= uint256(SystemLogKey.BLOB_SIX_HASH_KEY) ) { - require(logSender == L2_PUBDATA_CHUNK_PUBLISHER_ADDR, "pc"); + if (logSender != L2_PUBDATA_CHUNK_PUBLISHER_ADDR) { + revert InvalidLogSender(logSender, logKey); + } uint8 blobNumber = uint8(logKey) - uint8(SystemLogKey.BLOB_ONE_HASH_KEY); - // While the fact that `blobNumber` is a valid blob number is implicitly checked by the fact - // that Solidity provides array overflow protection, we still double check it manually in case - // we accidentally put `unchecked` at the top of the loop and generally for better error messages. - require(blobNumber < MAX_NUMBER_OF_BLOBS, "b6"); + if (blobNumber >= MAX_NUMBER_OF_BLOBS) { + revert TooManyBlobs(); + } + logOutput.blobHashes[blobNumber] = logValue; } else if (logKey == uint256(SystemLogKey.EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY)) { - require(logSender == L2_BOOTLOADER_ADDRESS, "bu"); - require(_expectedSystemContractUpgradeTxHash == logValue, "ut"); + if (logSender != L2_BOOTLOADER_ADDRESS) { + revert InvalidLogSender(logSender, logKey); + } + if (_expectedSystemContractUpgradeTxHash != logValue) { + revert TxHashMismatch(); + } } else if (logKey > uint256(SystemLogKey.EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY)) { - revert("ul"); + revert UnexpectedSystemLog(logKey); } } @@ -209,9 +253,13 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // Without the protocol upgrade we expect 13 logs: 2^13 - 1 = 8191 // With the protocol upgrade we expect 14 logs: 2^14 - 1 = 16383 if (_expectedSystemContractUpgradeTxHash == bytes32(0)) { - require(processedLogs == 8191, "b7"); + if (processedLogs != 8191) { + revert MissingSystemLogs(8191, processedLogs); + } } else { - require(processedLogs == 16383, "b8"); + if (processedLogs != 16383) { + revert MissingSystemLogs(16383, processedLogs); + } } } @@ -243,14 +291,21 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // 2. A chain might become out of sync if it launches while we are in the middle of a protocol upgrade. This would mean they cannot process their genesis upgrade // as their protocolversion would be outdated, and they also cannot process the protocol upgrade tx as they have a pending upgrade. // 3. The protocol upgrade is increased in the BaseZkSyncUpgrade, in the executor only the systemContractsUpgradeTxHash is checked - require( - IStateTransitionManager(s.stateTransitionManager).protocolVersionIsActive(s.protocolVersion), - "Executor facet: wrong protocol version" - ); + if (!IStateTransitionManager(s.stateTransitionManager).protocolVersionIsActive(s.protocolVersion)) { + revert InvalidProtocolVersion(); + } // With the new changes for EIP-4844, namely the restriction on number of blobs per block, we only allow for a single batch to be committed at a time. - require(_newBatchesData.length == 1, "e4"); + if (_newBatchesData.length != 1) { + revert CanOnlyProcessOneBatch(); + } // Check that we commit batches after last committed batch - require(s.storedBatchHashes[s.totalBatchesCommitted] == _hashStoredBatchInfo(_lastCommittedBatchData), "i"); // incorrect previous batch data + if (s.storedBatchHashes[s.totalBatchesCommitted] != _hashStoredBatchInfo(_lastCommittedBatchData)) { + // incorrect previous batch data + revert BatchHashMismatch( + s.storedBatchHashes[s.totalBatchesCommitted], + _hashStoredBatchInfo(_lastCommittedBatchData) + ); + } bytes32 systemContractsUpgradeTxHash = s.l2SystemContractsUpgradeTxHash; // Upgrades are rarely done so we optimize a case with no active system contracts upgrade. @@ -274,6 +329,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) internal { + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { _lastCommittedBatchData = _commitOneBatch(_lastCommittedBatchData, _newBatchesData[i], bytes32(0)); @@ -301,12 +357,15 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // carried out within the first batch committed after the upgrade. // While the logic of the contract ensures that the s.l2SystemContractsUpgradeBatchNumber is 0 when this function is called, - // this check is added just in case. Since it is a hot read, it does not encure noticeable gas cost. - require(s.l2SystemContractsUpgradeBatchNumber == 0, "ik"); + // this check is added just in case. Since it is a hot read, it does not incur noticeable gas cost. + if (s.l2SystemContractsUpgradeBatchNumber != 0) { + revert UpgradeBatchNumberIsNotZero(); + } // Save the batch number where the upgrade transaction was executed. s.l2SystemContractsUpgradeBatchNumber = _newBatchesData[0].batchNumber; + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { // The upgrade transaction must only be included in the first batch. @@ -342,14 +401,17 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { /// @dev _executedBatchIdx is an index in the array of the batches that we want to execute together function _executeOneBatch(StoredBatchInfo memory _storedBatch, uint256 _executedBatchIdx) internal { uint256 currentBatchNumber = _storedBatch.batchNumber; - require(currentBatchNumber == s.totalBatchesExecuted + _executedBatchIdx + 1, "k"); // Execute batches in order - require( - _hashStoredBatchInfo(_storedBatch) == s.storedBatchHashes[currentBatchNumber], - "exe10" // executing batch should be committed - ); + if (currentBatchNumber != s.totalBatchesExecuted + _executedBatchIdx + 1) { + revert NonSequentialBatch(); + } + if (_hashStoredBatchInfo(_storedBatch) != s.storedBatchHashes[currentBatchNumber]) { + revert BatchHashMismatch(s.storedBatchHashes[currentBatchNumber], _hashStoredBatchInfo(_storedBatch)); + } bytes32 priorityOperationsHash = _collectOperationsFromPriorityQueue(_storedBatch.numberOfLayer1Txs); - require(priorityOperationsHash == _storedBatch.priorityOperationsHash, "x"); // priority operations hash does not match to expected + if (priorityOperationsHash != _storedBatch.priorityOperationsHash) { + revert PriorityOperationsRollingHashMismatch(); + } // Save root hash of L2 -> L1 logs tree s.l2LogsRootHashes[currentBatchNumber] = _storedBatch.l2LogsTreeRoot; @@ -377,7 +439,9 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { uint256 newTotalBatchesExecuted = s.totalBatchesExecuted + nBatches; s.totalBatchesExecuted = newTotalBatchesExecuted; - require(newTotalBatchesExecuted <= s.totalBatchesVerified, "n"); // Can't execute batches more than committed and proven currently. + if (newTotalBatchesExecuted > s.totalBatchesVerified) { + revert CantExecuteUnprovenBatches(); + } uint256 batchWhenUpgradeHappened = s.l2SystemContractsUpgradeBatchNumber; if (batchWhenUpgradeHappened != 0 && batchWhenUpgradeHappened <= newTotalBatchesExecuted) { @@ -418,22 +482,31 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { uint256[] memory proofPublicInput = new uint256[](committedBatchesLength); // Check that the batch passed by the validator is indeed the first unverified batch - require(_hashStoredBatchInfo(_prevBatch) == s.storedBatchHashes[currentTotalBatchesVerified], "t1"); + if (_hashStoredBatchInfo(_prevBatch) != s.storedBatchHashes[currentTotalBatchesVerified]) { + revert BatchHashMismatch( + s.storedBatchHashes[currentTotalBatchesVerified], + _hashStoredBatchInfo(_prevBatch) + ); + } bytes32 prevBatchCommitment = _prevBatch.commitment; for (uint256 i = 0; i < committedBatchesLength; i = i.uncheckedInc()) { currentTotalBatchesVerified = currentTotalBatchesVerified.uncheckedInc(); - require( - _hashStoredBatchInfo(_committedBatches[i]) == s.storedBatchHashes[currentTotalBatchesVerified], - "o1" - ); + if (_hashStoredBatchInfo(_committedBatches[i]) != s.storedBatchHashes[currentTotalBatchesVerified]) { + revert BatchHashMismatch( + s.storedBatchHashes[currentTotalBatchesVerified], + _hashStoredBatchInfo(_committedBatches[i]) + ); + } bytes32 currentBatchCommitment = _committedBatches[i].commitment; proofPublicInput[i] = _getBatchProofPublicInput(prevBatchCommitment, currentBatchCommitment); prevBatchCommitment = currentBatchCommitment; } - require(currentTotalBatchesVerified <= s.totalBatchesCommitted, "q"); + if (currentTotalBatchesVerified > s.totalBatchesCommitted) { + revert VerifiedBatchesExceedsCommittedBatches(); + } _verifyProof(proofPublicInput, _proof); @@ -443,14 +516,18 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { function _verifyProof(uint256[] memory proofPublicInput, ProofInput calldata _proof) internal view { // We can only process 1 batch proof at a time. - require(proofPublicInput.length == 1, "t4"); + if (proofPublicInput.length != 1) { + revert CanOnlyProcessOneBatch(); + } bool successVerifyProof = s.verifier.verify( proofPublicInput, _proof.serializedProof, _proof.recursiveAggregationInput ); - require(successVerifyProof, "p"); // Proof verification fail + if (!successVerifyProof) { + revert InvalidProof(); + } } /// @dev Gets zk proof public input @@ -473,8 +550,12 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { } function _revertBatches(uint256 _newLastBatch) internal { - require(s.totalBatchesCommitted > _newLastBatch, "v1"); // The last committed batch is less than new last batch - require(_newLastBatch >= s.totalBatchesExecuted, "v2"); // Already executed batches cannot be reverted + if (s.totalBatchesCommitted <= _newLastBatch) { + revert RevertedBatchNotAfterNewLastBatch(); + } + if (_newLastBatch < s.totalBatchesExecuted) { + revert CantRevertExecutedBatch(); + } if (_newLastBatch < s.totalBatchesVerified) { s.totalBatchesVerified = _newLastBatch; @@ -535,7 +616,9 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { bytes32[] memory _blobCommitments, bytes32[] memory _blobHashes ) internal pure returns (bytes memory) { - require(_batch.systemLogs.length <= MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, "pu"); + if (_batch.systemLogs.length > MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES) { + revert SystemLogsSizeTooBig(); + } bytes32 l2ToL1LogsHash = keccak256(_batch.systemLogs); @@ -560,8 +643,9 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { ) internal pure returns (bytes32[] memory blobAuxOutputWords) { // These invariants should be checked by the caller of this function, but we double check // just in case. - require(_blobCommitments.length == MAX_NUMBER_OF_BLOBS, "b10"); - require(_blobHashes.length == MAX_NUMBER_OF_BLOBS, "b11"); + if (_blobCommitments.length != MAX_NUMBER_OF_BLOBS || _blobHashes.length != MAX_NUMBER_OF_BLOBS) { + revert InvalidNumberOfBlobs(MAX_NUMBER_OF_BLOBS, _blobCommitments.length, _blobHashes.length); + } // for each blob we have: // linear hash (hash of preimage from system logs) and @@ -609,9 +693,13 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // We verify that the point evaluation precompile call was successful by testing the latter 32 bytes of the // response is equal to BLS_MODULUS as defined in https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile - require(success, "failed to call point evaluation precompile"); + if (!success) { + revert PointEvalCallFailed(precompileInput); + } (, uint256 result) = abi.decode(data, (uint256, uint256)); - require(result == BLS_MODULUS, "precompile unexpected output"); + if (result != BLS_MODULUS) { + revert PointEvalFailed(abi.encode(result)); + } } /// @dev Verifies that the blobs contain the correct data by calling the point evaluation precompile. For the precompile we need: @@ -624,16 +712,25 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { ) internal view returns (bytes32[] memory blobCommitments) { uint256 versionedHashIndex = 0; - require(_pubdataCommitments.length > 0, "pl"); - require(_pubdataCommitments.length <= PUBDATA_COMMITMENT_SIZE * MAX_NUMBER_OF_BLOBS, "bd"); - require(_pubdataCommitments.length % PUBDATA_COMMITMENT_SIZE == 0, "bs"); + if (_pubdataCommitments.length == 0) { + revert PubdataCommitmentsEmpty(); + } + if (_pubdataCommitments.length > PUBDATA_COMMITMENT_SIZE * MAX_NUMBER_OF_BLOBS) { + revert PubdataCommitmentsTooBig(); + } + if (_pubdataCommitments.length % PUBDATA_COMMITMENT_SIZE != 0) { + revert InvalidPubdataCommitmentsSize(); + } blobCommitments = new bytes32[](MAX_NUMBER_OF_BLOBS); + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _pubdataCommitments.length; i += PUBDATA_COMMITMENT_SIZE) { bytes32 blobVersionedHash = _getBlobVersionedHash(versionedHashIndex); - require(blobVersionedHash != bytes32(0), "vh"); + if (blobVersionedHash == bytes32(0)) { + revert EmptyBlobVersionHash(versionedHashIndex); + } // First 16 bytes is the opening point. While we get the point as 16 bytes, the point evaluation precompile // requires it to be 32 bytes. The blob commitment must use the opening point as 16 bytes though. @@ -657,16 +754,19 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // This check is required because we want to ensure that there aren't any extra blobs trying to be published. // Calling the BLOBHASH opcode with an index > # blobs - 1 yields bytes32(0) bytes32 versionedHash = _getBlobVersionedHash(versionedHashIndex); - require(versionedHash == bytes32(0), "lh"); + if (versionedHash != bytes32(0)) { + revert NonEmptyBlobVersionHash(versionedHashIndex); + } // We verify that for each set of blobHash/blobCommitment are either both empty // or there are values for both. for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { - require( - (_blobHashes[i] == bytes32(0) && blobCommitments[i] == bytes32(0)) || - (_blobHashes[i] != bytes32(0) && blobCommitments[i] != bytes32(0)), - "bh" - ); + if ( + (_blobHashes[i] == bytes32(0) && blobCommitments[i] != bytes32(0)) || + (_blobHashes[i] != bytes32(0) && blobCommitments[i] == bytes32(0)) + ) { + revert BlobHashCommitmentError(i, _blobHashes[i] == bytes32(0), blobCommitments[i] == bytes32(0)); + } } } diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol index 77800ed12..9cb2a2da8 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol @@ -2,8 +2,7 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {SafeCast} from "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; @@ -13,6 +12,7 @@ import {PriorityQueue, PriorityOperation} from "../../../state-transition/librar import {UncheckedMath} from "../../../common/libraries/UncheckedMath.sol"; import {IGetters} from "../../chain-interfaces/IGetters.sol"; import {ILegacyGetters} from "../../chain-interfaces/ILegacyGetters.sol"; +import {InvalidSelector} from "../../../common/L1ContractErrors.sol"; import {SemVer} from "../../../common/libraries/SemVer.sol"; // While formally the following import is not used, it is needed to inherit documentation from it @@ -190,7 +190,9 @@ contract GettersFacet is ZkSyncHyperchainBase, IGetters, ILegacyGetters { /// @inheritdoc IGetters function isFunctionFreezable(bytes4 _selector) external view returns (bool) { Diamond.DiamondStorage storage ds = Diamond.getDiamondStorage(); - require(ds.selectorToFacet[_selector].facetAddress != address(0), "g2"); + if (ds.selectorToFacet[_selector].facetAddress == address(0)) { + revert InvalidSelector(_selector); + } return ds.selectorToFacet[_selector].isFreezable; } diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol index 4c38ef4a2..1f380941c 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -2,9 +2,7 @@ pragma solidity 0.8.24; -// solhint-disable reason-string, gas-custom-errors - -import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {Math} from "@openzeppelin/contracts-v4/utils/math/Math.sol"; import {IMailbox} from "../../chain-interfaces/IMailbox.sol"; import {ITransactionFilterer} from "../../chain-interfaces/ITransactionFilterer.sol"; @@ -22,6 +20,8 @@ import {L2_BOOTLOADER_ADDRESS, L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR} from ".. import {IL1SharedBridge} from "../../../bridge/interfaces/IL1SharedBridge.sol"; +import {OnlyEraSupported, BatchNotExecuted, HashedLogIsDefault, BaseTokenGasPriceDenominatorNotSet, TransactionNotAllowed, GasPerPubdataMismatch, TooManyFactoryDeps, MsgValueTooLow} from "../../../common/L1ContractErrors.sol"; + // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; @@ -44,7 +44,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { /// @inheritdoc IMailbox function transferEthToSharedBridge() external onlyBaseTokenBridge { - require(s.chainId == ERA_CHAIN_ID, "Mailbox: transferEthToSharedBridge only available for Era on mailbox"); + if (s.chainId != ERA_CHAIN_ID) { + revert OnlyEraSupported(); + } uint256 amount = address(this).balance; address baseTokenBridgeAddress = s.baseTokenBridge; @@ -115,7 +117,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { L2Log memory _log, bytes32[] calldata _proof ) internal view returns (bool) { - require(_batchNumber <= s.totalBatchesExecuted, "xx"); + if (_batchNumber > s.totalBatchesExecuted) { + revert BatchNotExecuted(_batchNumber); + } bytes32 hashedLog = keccak256( // solhint-disable-next-line func-named-parameters @@ -123,7 +127,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { ); // Check that hashed log is not the default one, // otherwise it means that the value is out of range of sent L2 -> L1 logs - require(hashedLog != L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, "tw"); + if (hashedLog == L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH) { + revert HashedLogIsDefault(); + } // It is ok to not check length of `_proof` array, as length // of leaf preimage (which is `L2_TO_L1_LOG_SERIALIZE_SIZE`) is not @@ -164,7 +170,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { /// @return The price of L2 gas in the base token function _deriveL2GasPrice(uint256 _l1GasPrice, uint256 _gasPerPubdata) internal view returns (uint256) { FeeParams memory feeParams = s.feeParams; - require(s.baseTokenGasPriceMultiplierDenominator > 0, "Mailbox: baseTokenGasPriceDenominator not set"); + if (s.baseTokenGasPriceMultiplierDenominator == 0) { + revert BaseTokenGasPriceDenominatorNotSet(); + } uint256 l1GasPriceConverted = (_l1GasPrice * s.baseTokenGasPriceMultiplierNominator) / s.baseTokenGasPriceMultiplierDenominator; uint256 pubdataPriceBaseToken; @@ -193,7 +201,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { bytes calldata _message, bytes32[] calldata _merkleProof ) external nonReentrant { - require(s.chainId == ERA_CHAIN_ID, "Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + if (s.chainId != ERA_CHAIN_ID) { + revert OnlyEraSupported(); + } IL1SharedBridge(s.baseTokenBridge).finalizeWithdrawal({ _chainId: ERA_CHAIN_ID, _l2BatchNumber: _l2BatchNumber, @@ -214,7 +224,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { bytes[] calldata _factoryDeps, address _refundRecipient ) external payable returns (bytes32 canonicalTxHash) { - require(s.chainId == ERA_CHAIN_ID, "Mailbox: legacy interface only available for Era"); + if (s.chainId != ERA_CHAIN_ID) { + revert OnlyEraSupported(); + } canonicalTxHash = _requestL2TransactionSender( BridgehubL2TransactionRequest({ sender: msg.sender, @@ -241,17 +253,18 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { ) internal nonReentrant returns (bytes32 canonicalTxHash) { // Check that the transaction is allowed by the filterer (if the filterer is set). if (s.transactionFilterer != address(0)) { - require( - ITransactionFilterer(s.transactionFilterer).isTransactionAllowed({ + if ( + !ITransactionFilterer(s.transactionFilterer).isTransactionAllowed({ sender: _request.sender, contractL2: _request.contractL2, mintValue: _request.mintValue, l2Value: _request.l2Value, l2Calldata: _request.l2Calldata, refundRecipient: _request.refundRecipient - }), - "tf" - ); + }) + ) { + revert TransactionNotAllowed(); + } } // Enforcing that `_request.l2GasPerPubdataByteLimit` equals to a certain constant number. This is needed @@ -259,7 +272,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { // VERY IMPORTANT: nobody should rely on this constant to be fixed and every contract should give their users the ability to provide the // ability to provide `_request.l2GasPerPubdataByteLimit` for each independent transaction. // CHANGING THIS CONSTANT SHOULD BE A CLIENT-SIDE CHANGE. - require(_request.l2GasPerPubdataByteLimit == REQUIRED_L2_GAS_PRICE_PER_PUBDATA, "qp"); + if (_request.l2GasPerPubdataByteLimit != REQUIRED_L2_GAS_PRICE_PER_PUBDATA) { + revert GasPerPubdataMismatch(); + } WritePriorityOpParams memory params; params.request = _request; @@ -270,13 +285,17 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { function _requestL2Transaction(WritePriorityOpParams memory _params) internal returns (bytes32 canonicalTxHash) { BridgehubL2TransactionRequest memory request = _params.request; - require(request.factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "uj"); + if (request.factoryDeps.length > MAX_NEW_FACTORY_DEPS) { + revert TooManyFactoryDeps(); + } _params.txId = s.priorityQueue.getTotalPriorityTxs(); // Checking that the user provided enough ether to pay for the transaction. _params.l2GasPrice = _deriveL2GasPrice(tx.gasprice, request.l2GasPerPubdataByteLimit); uint256 baseCost = _params.l2GasPrice * request.l2GasLimit; - require(request.mintValue >= baseCost + request.l2Value, "mv"); // The `msg.value` doesn't cover the transaction cost + if (request.mintValue < baseCost + request.l2Value) { + revert MsgValueTooLow(baseCost + request.l2Value, request.mintValue); + } request.refundRecipient = AddressAliasHelper.actualRefundRecipient(request.refundRecipient, request.sender); // Change the sender address if it is a smart contract to prevent address collision between L1 and L2. @@ -286,6 +305,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { if (request.sender != tx.origin) { request.sender = AddressAliasHelper.applyL1ToL2Alias(request.sender); } + // solhint-enable avoid-tx-origin // populate missing fields _params.expirationTimestamp = uint64(block.timestamp + PRIORITY_EXPIRATION); // Safe to cast diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol index 3c855e87a..0910fcab3 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol @@ -2,11 +2,11 @@ pragma solidity 0.8.24; -// solhint-disable reason-string, gas-custom-errors - import {ZkSyncHyperchainStorage} from "../ZkSyncHyperchainStorage.sol"; import {ReentrancyGuard} from "../../../common/ReentrancyGuard.sol"; +import {Unauthorized} from "../../../common/L1ContractErrors.sol"; + /// @title Base contract containing functions accessible to the other facets. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -16,44 +16,52 @@ contract ZkSyncHyperchainBase is ReentrancyGuard { /// @notice Checks that the message sender is an active admin modifier onlyAdmin() { - require(msg.sender == s.admin, "Hyperchain: not admin"); + if (msg.sender != s.admin) { + revert Unauthorized(msg.sender); + } _; } /// @notice Checks if validator is active modifier onlyValidator() { - require(s.validators[msg.sender], "Hyperchain: not validator"); + if (!s.validators[msg.sender]) { + revert Unauthorized(msg.sender); + } _; } modifier onlyStateTransitionManager() { - require(msg.sender == s.stateTransitionManager, "Hyperchain: not state transition manager"); + if (msg.sender != s.stateTransitionManager) { + revert Unauthorized(msg.sender); + } _; } modifier onlyBridgehub() { - require(msg.sender == s.bridgehub, "Hyperchain: not bridgehub"); + if (msg.sender != s.bridgehub) { + revert Unauthorized(msg.sender); + } _; } modifier onlyAdminOrStateTransitionManager() { - require( - msg.sender == s.admin || msg.sender == s.stateTransitionManager, - "Hyperchain: Only by admin or state transition manager" - ); + if (msg.sender != s.admin && msg.sender != s.stateTransitionManager) { + revert Unauthorized(msg.sender); + } _; } modifier onlyValidatorOrStateTransitionManager() { - require( - s.validators[msg.sender] || msg.sender == s.stateTransitionManager, - "Hyperchain: Only by validator or state transition manager" - ); + if (!s.validators[msg.sender] && msg.sender != s.stateTransitionManager) { + revert Unauthorized(msg.sender); + } _; } modifier onlyBaseTokenBridge() { - require(msg.sender == s.baseTokenBridge, "Hyperchain: Only base token bridge can call this function"); + if (msg.sender != s.baseTokenBridge) { + revert Unauthorized(msg.sender); + } _; } } diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol index f2252fee6..79c034f36 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "../chain-interfaces/IZkSyncHyperchainBase.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol index a8209b546..e222a623e 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IVerifier, VerifierParams} from "./IVerifier.sol"; import {FeeParams} from "../chain-deps/ZkSyncHyperchainStorage.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol index 149b97027..7679be75e 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "./IZkSyncHyperchainBase.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol index 9d77efdf3..38e2adbfe 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {PriorityOperation} from "../libraries/PriorityQueue.sol"; import {VerifierParams} from "../chain-interfaces/IVerifier.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol b/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol index 5d3c36094..4d6941edf 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "./IZkSyncHyperchainBase.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol index b0b535d68..065b3819d 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "./IZkSyncHyperchainBase.sol"; import {L2CanonicalTransaction, L2Log, L2Message, TxStatus, BridgehubL2TransactionRequest} from "../../common/Messaging.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol b/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol index 9e1178fc9..49dee07fd 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @title The interface of the L1 -> L2 transaction filterer. /// @author Matter Labs diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol index 0577102b1..dbca3bf0c 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @notice Part of the configuration parameters of ZKP circuits struct VerifierParams { diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol index 6641985a8..bf9a88a5e 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {IAdmin} from "./IAdmin.sol"; import {IExecutor} from "./IExecutor.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol index 1b6629f7d..15fda726d 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @title The interface of the zkSync contract, responsible for the main zkSync logic. /// @author Matter Labs diff --git a/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol b/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol index fded0f4d2..6aa1b09ff 100644 --- a/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol +++ b/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; interface ISystemContext { function setChainId(uint256 _newChainId) external; diff --git a/l1-contracts/contracts/state-transition/libraries/Diamond.sol b/l1-contracts/contracts/state-transition/libraries/Diamond.sol index 8699f750e..6d8416fde 100644 --- a/l1-contracts/contracts/state-transition/libraries/Diamond.sol +++ b/l1-contracts/contracts/state-transition/libraries/Diamond.sol @@ -1,11 +1,10 @@ // SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; -pragma solidity 0.8.24; - -// solhint-disable gas-custom-errors - -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {SafeCast} from "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; +import {NoFunctionsForDiamondCut, UndefinedDiamondCutAction, AddressHasNoCode, FacetExists, RemoveFunctionFacetAddressZero, SelectorsMustAllHaveSameFreezability, NonEmptyCalldata, ReplaceFunctionFacetAddressZero, RemoveFunctionFacetAddressNotZero, DelegateCallFailed} from "../../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -107,7 +106,9 @@ library Diamond { bool isFacetFreezable = facetCuts[i].isFreezable; bytes4[] memory selectors = facetCuts[i].selectors; - require(selectors.length > 0, "B"); // no functions for diamond cut + if (selectors.length == 0) { + revert NoFunctionsForDiamondCut(); + } if (action == Action.Add) { _addFunctions(facet, selectors, isFacetFreezable); @@ -116,7 +117,7 @@ library Diamond { } else if (action == Action.Remove) { _removeFunctions(facet, selectors); } else { - revert("C"); // undefined diamond cut action + revert UndefinedDiamondCutAction(); } } @@ -132,7 +133,9 @@ library Diamond { // Facet with no code cannot be added. // This check also verifies that the facet does not have zero address, since it is the // address with which 0x00000000 selector is associated. - require(_facet.code.length > 0, "G"); + if (_facet.code.length == 0) { + revert AddressHasNoCode(_facet); + } // Add facet to the list of facets if the facet address is new one _saveFacetIfNew(_facet); @@ -141,7 +144,9 @@ library Diamond { for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) { bytes4 selector = _selectors[i]; SelectorToFacet memory oldFacet = ds.selectorToFacet[selector]; - require(oldFacet.facetAddress == address(0), "J"); // facet for this selector already exists + if (oldFacet.facetAddress != address(0)) { + revert FacetExists(selector, oldFacet.facetAddress); + } _addOneFunction(_facet, selector, _isFacetFreezable); } @@ -155,13 +160,18 @@ library Diamond { // Facet with no code cannot be added. // This check also verifies that the facet does not have zero address, since it is the // address with which 0x00000000 selector is associated. - require(_facet.code.length > 0, "K"); + if (_facet.code.length == 0) { + revert AddressHasNoCode(_facet); + } uint256 selectorsLength = _selectors.length; for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) { bytes4 selector = _selectors[i]; SelectorToFacet memory oldFacet = ds.selectorToFacet[selector]; - require(oldFacet.facetAddress != address(0), "L"); // it is impossible to replace the facet with zero address + // it is impossible to replace the facet with zero address + if (oldFacet.facetAddress == address(0)) { + revert ReplaceFunctionFacetAddressZero(); + } _removeOneFunction(oldFacet.facetAddress, selector); // Add facet to the list of facets if the facet address is a new one @@ -175,13 +185,19 @@ library Diamond { function _removeFunctions(address _facet, bytes4[] memory _selectors) private { DiamondStorage storage ds = getDiamondStorage(); - require(_facet == address(0), "a1"); // facet address must be zero + // facet address must be zero + if (_facet != address(0)) { + revert RemoveFunctionFacetAddressNotZero(_facet); + } uint256 selectorsLength = _selectors.length; for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) { bytes4 selector = _selectors[i]; SelectorToFacet memory oldFacet = ds.selectorToFacet[selector]; - require(oldFacet.facetAddress != address(0), "a2"); // Can't delete a non-existent facet + // Can't delete a non-existent facet + if (oldFacet.facetAddress == address(0)) { + revert RemoveFunctionFacetAddressZero(); + } _removeOneFunction(oldFacet.facetAddress, selector); } @@ -215,7 +231,9 @@ library Diamond { // so all the selectors in a facet will have the same freezability if (selectorPosition != 0) { bytes4 selector0 = ds.facetToSelectors[_facet].selectors[0]; - require(_isSelectorFreezable == ds.selectorToFacet[selector0].isFreezable, "J1"); + if (_isSelectorFreezable != ds.selectorToFacet[selector0].isFreezable) { + revert SelectorsMustAllHaveSameFreezability(); + } } ds.selectorToFacet[_selector] = SelectorToFacet({ @@ -280,14 +298,18 @@ library Diamond { /// @dev Used as a final step of diamond cut to execute the logic of the initialization for changed facets function _initializeDiamondCut(address _init, bytes memory _calldata) private { if (_init == address(0)) { - require(_calldata.length == 0, "H"); // Non-empty calldata for zero address + // Non-empty calldata for zero address + if (_calldata.length != 0) { + revert NonEmptyCalldata(); + } } else { // Do not check whether `_init` is a contract since later we check that it returns data. (bool success, bytes memory data) = _init.delegatecall(_calldata); if (!success) { // If the returndata is too small, we still want to produce some meaningful error - if (data.length <= 4) { - revert("I"); // delegatecall failed + + if (data.length < 4) { + revert DelegateCallFailed(data); } assembly { @@ -297,8 +319,12 @@ library Diamond { // Check that called contract returns magic value to make sure that contract logic // supposed to be used as diamond cut initializer. - require(data.length == 32, "lp"); - require(abi.decode(data, (bytes32)) == DIAMOND_INIT_SUCCESS_RETURN_VALUE, "lp1"); + if (data.length != 32) { + revert DelegateCallFailed(data); + } + if (abi.decode(data, (bytes32)) != DIAMOND_INIT_SUCCESS_RETURN_VALUE) { + revert DelegateCallFailed(data); + } } } } diff --git a/l1-contracts/contracts/state-transition/libraries/LibMap.sol b/l1-contracts/contracts/state-transition/libraries/LibMap.sol index 1ba8a82be..9bedb1cce 100644 --- a/l1-contracts/contracts/state-transition/libraries/LibMap.sol +++ b/l1-contracts/contracts/state-transition/libraries/LibMap.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; /// @notice Library for storage of packed unsigned integers. /// @author Matter Labs diff --git a/l1-contracts/contracts/state-transition/libraries/Merkle.sol b/l1-contracts/contracts/state-transition/libraries/Merkle.sol index 8680f9ac6..79287d00b 100644 --- a/l1-contracts/contracts/state-transition/libraries/Merkle.sol +++ b/l1-contracts/contracts/state-transition/libraries/Merkle.sol @@ -1,10 +1,9 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -// solhint-disable gas-custom-errors +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; +import {MerklePathEmpty, MerklePathOutOfBounds, MerkleIndexOutOfBounds} from "../../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -23,9 +22,15 @@ library Merkle { bytes32 _itemHash ) internal pure returns (bytes32) { uint256 pathLength = _path.length; - require(pathLength > 0, "xc"); - require(pathLength < 256, "bt"); - require(_index < (1 << pathLength), "px"); + if (pathLength == 0) { + revert MerklePathEmpty(); + } + if (pathLength >= 256) { + revert MerklePathOutOfBounds(); + } + if (_index >= (1 << pathLength)) { + revert MerkleIndexOutOfBounds(); + } bytes32 currentHash = _itemHash; for (uint256 i; i < pathLength; i = i.uncheckedInc()) { diff --git a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol index 186ecda09..762350039 100644 --- a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol +++ b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; -pragma solidity 0.8.24; - -// solhint-disable gas-custom-errors +import {QueueIsEmpty} from "../../common/L1ContractErrors.sol"; /// @notice The structure that contains meta information of the L2 transaction that was requested from L1 /// @dev The weird size of fields was selected specifically to minimize the structure storage size @@ -64,7 +64,10 @@ library PriorityQueue { /// @return The first unprocessed priority operation from the queue function front(Queue storage _queue) internal view returns (PriorityOperation memory) { - require(!_queue.isEmpty(), "D"); // priority queue is empty + // priority queue is empty + if (_queue.isEmpty()) { + revert QueueIsEmpty(); + } return _queue.data[_queue.head]; } @@ -72,7 +75,10 @@ library PriorityQueue { /// @notice Remove the first unprocessed priority operation from the queue /// @return priorityOperation that was popped from the priority queue function popFront(Queue storage _queue) internal returns (PriorityOperation memory priorityOperation) { - require(!_queue.isEmpty(), "s"); // priority queue is empty + // priority queue is empty + if (_queue.isEmpty()) { + revert QueueIsEmpty(); + } // Save value into the stack to avoid double reading from the storage uint256 head = _queue.head; diff --git a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol index 86bdb4294..485aef9a2 100644 --- a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol +++ b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol @@ -1,13 +1,12 @@ // SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; -pragma solidity 0.8.24; - -// solhint-disable gas-custom-errors - -import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {Math} from "@openzeppelin/contracts-v4/utils/math/Math.sol"; import {L2CanonicalTransaction} from "../../common/Messaging.sol"; import {TX_SLOT_OVERHEAD_L2_GAS, MEMORY_OVERHEAD_GAS, L1_TX_INTRINSIC_L2_GAS, L1_TX_DELTA_544_ENCODING_BYTES, L1_TX_DELTA_FACTORY_DEPS_L2_GAS, L1_TX_MIN_L2_GAS_BASE, L1_TX_INTRINSIC_PUBDATA, L1_TX_DELTA_FACTORY_DEPS_PUBDATA} from "../../common/Config.sol"; +import {TooMuchGas, InvalidUpgradeTxn, UpgradeTxVerifyParam, PubdataGreaterThanLimit, ValidateTxnNotEnoughGas, TxnBodyGasLimitNotEnoughGas} from "../../common/L1ContractErrors.sol"; /// @title zkSync Library for validating L1 -> L2 transactions /// @author Matter Labs @@ -27,39 +26,70 @@ library TransactionValidator { uint256 l2GasForTxBody = getTransactionBodyGasLimit(_transaction.gasLimit, _encoded.length); // Ensuring that the transaction is provable - require(l2GasForTxBody <= _priorityTxMaxGasLimit, "ui"); + if (l2GasForTxBody > _priorityTxMaxGasLimit) { + revert TooMuchGas(); + } // Ensuring that the transaction cannot output more pubdata than is processable - require(l2GasForTxBody / _transaction.gasPerPubdataByteLimit <= _priorityTxMaxPubdata, "uk"); + if (l2GasForTxBody / _transaction.gasPerPubdataByteLimit > _priorityTxMaxPubdata) { + revert PubdataGreaterThanLimit(_priorityTxMaxPubdata, l2GasForTxBody / _transaction.gasPerPubdataByteLimit); + } // Ensuring that the transaction covers the minimal costs for its processing: // hashing its content, publishing the factory dependencies, etc. - require( + if ( getMinimalPriorityTransactionGasLimit( _encoded.length, _transaction.factoryDeps.length, _transaction.gasPerPubdataByteLimit - ) <= l2GasForTxBody, - "up" - ); + ) > l2GasForTxBody + ) { + revert ValidateTxnNotEnoughGas(); + } } /// @dev Used to validate upgrade transactions /// @param _transaction The transaction to validate function validateUpgradeTransaction(L2CanonicalTransaction memory _transaction) internal pure { // Restrict from to be within system contract range (0...2^16 - 1) - require(_transaction.from <= type(uint16).max, "ua"); - require(_transaction.to <= type(uint160).max, "ub"); - require(_transaction.paymaster == 0, "uc"); - require(_transaction.value == 0, "ud"); - require(_transaction.maxFeePerGas == 0, "uq"); - require(_transaction.maxPriorityFeePerGas == 0, "ux"); - require(_transaction.reserved[0] == 0, "ue"); - require(_transaction.reserved[1] <= type(uint160).max, "uf"); - require(_transaction.reserved[2] == 0, "ug"); - require(_transaction.reserved[3] == 0, "uo"); - require(_transaction.signature.length == 0, "uh"); - require(_transaction.paymasterInput.length == 0, "ul1"); - require(_transaction.reservedDynamic.length == 0, "um"); + if (_transaction.from > type(uint16).max) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.From); + } + if (_transaction.to > type(uint160).max) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.To); + } + if (_transaction.paymaster != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Paymaster); + } + if (_transaction.value != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Value); + } + if (_transaction.maxFeePerGas != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.MaxFeePerGas); + } + if (_transaction.maxPriorityFeePerGas != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.MaxPriorityFeePerGas); + } + if (_transaction.reserved[0] != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Reserved0); + } + if (_transaction.reserved[1] > type(uint160).max) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Reserved1); + } + if (_transaction.reserved[2] != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Reserved2); + } + if (_transaction.reserved[3] != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Reserved3); + } + if (_transaction.signature.length != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.Signature); + } + if (_transaction.paymasterInput.length != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.PaymasterInput); + } + if (_transaction.reservedDynamic.length != 0) { + revert InvalidUpgradeTxn(UpgradeTxVerifyParam.ReservedDynamic); + } } /// @dev Calculates the approximate minimum gas limit required for executing a priority transaction. @@ -114,7 +144,10 @@ library TransactionValidator { ) internal pure returns (uint256 txBodyGasLimit) { uint256 overhead = getOverheadForTransaction(_encodingLength); - require(_totalGasLimit >= overhead, "my"); // provided gas limit doesn't cover transaction overhead + // provided gas limit doesn't cover transaction overhead + if (_totalGasLimit < overhead) { + revert TxnBodyGasLimitNotEnoughGas(); + } unchecked { // We enforce the fact that `_totalGasLimit >= overhead` explicitly above. txBodyGasLimit = _totalGasLimit - overhead; diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol index 6510a2b7d..4534884d5 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol @@ -2,8 +2,7 @@ pragma solidity 0.8.24; -// solhint-disable reason-string, gas-custom-errors -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {SafeCast} from "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; import {ZkSyncHyperchainBase} from "../state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol"; import {VerifierParams} from "../state-transition/chain-interfaces/IVerifier.sol"; @@ -12,6 +11,7 @@ import {L2ContractHelper} from "../common/libraries/L2ContractHelper.sol"; import {TransactionValidator} from "../state-transition/libraries/TransactionValidator.sol"; import {MAX_NEW_FACTORY_DEPS, SYSTEM_UPGRADE_L2_TX_TYPE, MAX_ALLOWED_MINOR_VERSION_DELTA} from "../common/Config.sol"; import {L2CanonicalTransaction} from "../common/Messaging.sol"; +import {ProtocolVersionMinorDeltaTooBig, TimeNotReached, InvalidTxType, L2UpgradeNonceNotEqualToNewProtocolVersion, TooManyFactoryDeps, UnexpectedNumberOfFactoryDeps, ProtocolVersionTooSmall, PreviousUpgradeNotFinalized, PreviousUpgradeNotCleaned, L2BytecodeHashMismatch, PatchCantSetUpgradeTxn, PreviousProtocolMajorVersionNotZero, NewProtocolMajorVersionNotZero, PatchUpgradeCantSetDefaultAccount, PatchUpgradeCantSetBootloader} from "./ZkSyncUpgradeErrors.sol"; import {SemVer} from "../common/libraries/SemVer.sol"; /// @notice The struct that represents the upgrade proposal. @@ -72,7 +72,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { // of the L1 block at which the upgrade occurred. This means that using timestamp as a signifier of "upgraded" // on the L2 side would be inaccurate. The effects of this "back-dating" of L2 upgrade batches will be reduced // as the permitted delay window is reduced in the future. - require(block.timestamp >= _proposedUpgrade.upgradeTimestamp, "Upgrade is not ready yet"); + if (block.timestamp < _proposedUpgrade.upgradeTimestamp) { + revert TimeNotReached(_proposedUpgrade.upgradeTimestamp, block.timestamp); + } (uint32 newMinorVersion, bool isPatchOnly) = _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); _upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata); @@ -99,7 +101,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { return; } - require(!_patchOnly, "Patch only upgrade can not set new default account"); + if (_patchOnly) { + revert PatchUpgradeCantSetDefaultAccount(); + } L2ContractHelper.validateBytecodeHash(_l2DefaultAccountBytecodeHash); @@ -119,7 +123,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { return; } - require(!_patchOnly, "Patch only upgrade can not set new bootloader"); + if (_patchOnly) { + revert PatchUpgradeCantSetBootloader(); + } L2ContractHelper.validateBytecodeHash(_l2BootloaderBytecodeHash); @@ -203,9 +209,12 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { return bytes32(0); } - require(!_patchOnly, "Patch only upgrade can not set upgrade transaction"); - - require(_l2ProtocolUpgradeTx.txType == SYSTEM_UPGRADE_L2_TX_TYPE, "L2 system upgrade tx type is wrong"); + if (_l2ProtocolUpgradeTx.txType != SYSTEM_UPGRADE_L2_TX_TYPE) { + revert InvalidTxType(_l2ProtocolUpgradeTx.txType); + } + if (_patchOnly) { + revert PatchCantSetUpgradeTxn(); + } bytes memory encodedTransaction = abi.encode(_l2ProtocolUpgradeTx); @@ -220,10 +229,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { // We want the hashes of l2 system upgrade transactions to be unique. // This is why we require that the `nonce` field is unique to each upgrade. - require( - _l2ProtocolUpgradeTx.nonce == _newMinorProtocolVersion, - "The new protocol version should be included in the L2 system upgrade tx" - ); + if (_l2ProtocolUpgradeTx.nonce != _newMinorProtocolVersion) { + revert L2UpgradeNonceNotEqualToNewProtocolVersion(_l2ProtocolUpgradeTx.nonce, _newMinorProtocolVersion); + } _verifyFactoryDeps(_factoryDeps, _l2ProtocolUpgradeTx.factoryDeps); @@ -238,15 +246,19 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @param _factoryDeps The list of factory deps /// @param _expectedHashes The list of expected bytecode hashes function _verifyFactoryDeps(bytes[] calldata _factoryDeps, uint256[] calldata _expectedHashes) private pure { - require(_factoryDeps.length == _expectedHashes.length, "Wrong number of factory deps"); - require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "Factory deps can be at most 32"); + if (_factoryDeps.length != _expectedHashes.length) { + revert UnexpectedNumberOfFactoryDeps(); + } + if (_factoryDeps.length > MAX_NEW_FACTORY_DEPS) { + revert TooManyFactoryDeps(); + } uint256 length = _factoryDeps.length; for (uint256 i = 0; i < length; ++i) { - require( - L2ContractHelper.hashL2Bytecode(_factoryDeps[i]) == bytes32(_expectedHashes[i]), - "Wrong factory dep hash" - ); + bytes32 bytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[i]); + if (bytecodeHash != bytes32(_expectedHashes[i])) { + revert L2BytecodeHashMismatch(bytecodeHash, bytes32(_expectedHashes[i])); + } } } @@ -256,20 +268,23 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { uint256 _newProtocolVersion ) internal virtual returns (uint32 newMinorVersion, bool patchOnly) { uint256 previousProtocolVersion = s.protocolVersion; - require( - _newProtocolVersion > previousProtocolVersion, - "New protocol version is not greater than the current one" - ); + if (_newProtocolVersion <= previousProtocolVersion) { + revert ProtocolVersionTooSmall(); + } // slither-disable-next-line unused-return (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( SafeCast.toUint96(previousProtocolVersion) ); - require(previousMajorVersion == 0, "Implementation requires that the major version is 0 at all times"); + if (previousMajorVersion != 0) { + revert PreviousProtocolMajorVersionNotZero(); + } uint32 newMajorVersion; // slither-disable-next-line unused-return (newMajorVersion, newMinorVersion, ) = SemVer.unpackSemVer(SafeCast.toUint96(_newProtocolVersion)); - require(newMajorVersion == 0, "Major must always be 0"); + if (newMajorVersion != 0) { + revert NewProtocolMajorVersionNotZero(); + } // Since `_newProtocolVersion > previousProtocolVersion`, and both old and new major version is 0, // the difference between minor versions is >= 0. @@ -280,19 +295,22 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { } // While this is implicitly enforced by other checks above, we still double check just in case - require(minorDelta <= MAX_ALLOWED_MINOR_VERSION_DELTA, "Too big protocol version difference"); + if (minorDelta > MAX_ALLOWED_MINOR_VERSION_DELTA) { + revert ProtocolVersionMinorDeltaTooBig(MAX_ALLOWED_MINOR_VERSION_DELTA, minorDelta); + } // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. // In case the minor version does not change, we permit to keep the old upgrade transaction in the system, but it - // must be ensured in the other parts of the upgrade that the is not overridden. + // must be ensured in the other parts of the upgrade that the upgrade transaction is not overridden. if (!patchOnly) { // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. // Note it is important to keep this check, as otherwise hyperchains might skip upgrades by overwriting - require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); - require( - s.l2SystemContractsUpgradeBatchNumber == 0, - "The batch number of the previous upgrade has not been cleaned" - ); + if (s.l2SystemContractsUpgradeTxHash != bytes32(0)) { + revert PreviousUpgradeNotFinalized(s.l2SystemContractsUpgradeTxHash); + } + if (s.l2SystemContractsUpgradeBatchNumber != 0) { + revert PreviousUpgradeNotCleaned(); + } } s.protocolVersion = _newProtocolVersion; diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol index 51d24592d..561f25d23 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.24; -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {SafeCast} from "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; import {BaseZkSyncUpgrade} from "./BaseZkSyncUpgrade.sol"; -import {ProtocolVersionShouldBeGreater, ProtocolVersionDeltaTooLarge, PreviousUpgradeNotFinalized, PreviousUpgradeBatchNotCleared, ProtocolMajorVersionNotZero} from "./ZkSyncUpgradeErrors.sol"; +import {ProtocolVersionTooSmall, ProtocolVersionDeltaTooLarge, PreviousUpgradeNotFinalized, PreviousUpgradeBatchNotCleared, ProtocolMajorVersionNotZero} from "./ZkSyncUpgradeErrors.sol"; import {MAX_ALLOWED_MINOR_VERSION_DELTA} from "../common/Config.sol"; import {SemVer} from "../common/libraries/SemVer.sol"; @@ -20,10 +20,10 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { ) internal override returns (uint32 newMinorVersion, bool patchOnly) { uint256 previousProtocolVersion = s.protocolVersion; if ( - // IMPORTANT Genesis Upgrade difference: Note this is the only thing change > to >= + // IMPORTANT Genesis Upgrade difference: Note this is the only thing change <= to < _newProtocolVersion < previousProtocolVersion ) { - revert ProtocolVersionShouldBeGreater(previousProtocolVersion, _newProtocolVersion); + revert ProtocolVersionTooSmall(); } // slither-disable-next-line unused-return (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( @@ -55,12 +55,12 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. // In case the minor version does not change, we permit to keep the old upgrade transaction in the system, but it - // must be ensured in the other parts of the upgrade that the is not overridden. + // must be ensured in the other parts of the upgrade that the upgrade transaction is not overridden. if (!patchOnly) { // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. // Note it is important to keep this check, as otherwise hyperchains might skip upgrades by overwriting if (s.l2SystemContractsUpgradeTxHash != bytes32(0)) { - revert PreviousUpgradeNotFinalized(); + revert PreviousUpgradeNotFinalized(s.l2SystemContractsUpgradeTxHash); } if (s.l2SystemContractsUpgradeBatchNumber != 0) { revert PreviousUpgradeBatchNotCleared(); diff --git a/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol index d71680e73..b30c882e7 100644 --- a/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol +++ b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol @@ -1,9 +1,48 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.24; +pragma solidity ^0.8.21; -error ProtocolVersionShouldBeGreater(uint256 _oldProtocolVersion, uint256 _newProtocolVersion); -error ProtocolVersionDeltaTooLarge(uint256 _proposedDelta, uint256 _maxDelta); -error PreviousUpgradeNotFinalized(); +// 0x7a47c9a2 +error InvalidChainId(); +// 0xd7f8c13e error PreviousUpgradeBatchNotCleared(); +// 0x3c43ccce error ProtocolMajorVersionNotZero(); +// 0xd7f50a9d +error PatchCantSetUpgradeTxn(); +// 0xd2c011d6 +error L2UpgradeNonceNotEqualToNewProtocolVersion(uint256 nonce, uint256 protocolVersion); +// 0xcb5e4247 +error L2BytecodeHashMismatch(bytes32 expected, bytes32 provided); +// 0x88d7b498 +error ProtocolVersionTooSmall(); +// 0x56d45b12 +error ProtocolVersionTooBig(); +// 0x5c598b60 +error PreviousProtocolMajorVersionNotZero(); +// 0x72ea85ad +error NewProtocolMajorVersionNotZero(); +// 0xd328c12a +error ProtocolVersionMinorDeltaTooBig(uint256 limit, uint256 proposed); +// 0xe1a9736b +error ProtocolVersionDeltaTooLarge(uint256 _proposedDelta, uint256 _maxDelta); +// 0x6d172ab2 +error ProtocolVersionShouldBeGreater(uint256 _oldProtocolVersion, uint256 _newProtocolVersion); +// 0x559cc34e +error PatchUpgradeCantSetDefaultAccount(); +// 0x962fd7d0 +error PatchUpgradeCantSetBootloader(); +// 0x101ba748 +error PreviousUpgradeNotFinalized(bytes32 txHash); +// 0xa0f47245 +error PreviousUpgradeNotCleaned(); +// 0x07218375 +error UnexpectedNumberOfFactoryDeps(); +// 0x76da24b9 +error TooManyFactoryDeps(); +// 0x5cb29523 +error InvalidTxType(uint256 txType); +// 0x08753982 +error TimeNotReached(uint256 expectedTimestamp, uint256 actualTimestamp); +// 0xd92e233d +error ZeroAddress(); diff --git a/l1-contracts/contracts/vendor/AddressAliasHelper.sol b/l1-contracts/contracts/vendor/AddressAliasHelper.sol index fe705cfc3..e5bc1da07 100644 --- a/l1-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l1-contracts/contracts/vendor/AddressAliasHelper.sol @@ -15,8 +15,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.21; library AddressAliasHelper { uint160 private constant offset = uint160(0x1111000000000000000000000000000000001111); @@ -56,6 +56,7 @@ library AddressAliasHelper { _recipient = _prevMsgSender == tx.origin ? _prevMsgSender : AddressAliasHelper.applyL1ToL2Alias(_prevMsgSender); + // solhint-enable avoid-tx-origin } else if (_refundRecipient.code.length > 0) { // If the `_refundRecipient` is a smart contract, we apply the L1 to L2 alias to prevent foot guns. _recipient = AddressAliasHelper.applyL1ToL2Alias(_refundRecipient); diff --git a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol index b201204c5..bb601457b 100644 --- a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol +++ b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.21; import {Script} from "forge-std/Script.sol"; -import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Ownable2Step} from "@openzeppelin/contracts-v4/access/Ownable2Step.sol"; import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; import {ChainAdmin} from "contracts/governance/ChainAdmin.sol"; import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; diff --git a/l1-contracts/deploy-scripts/DecentralizeGovernanceUpgradeScript.s.sol b/l1-contracts/deploy-scripts/DecentralizeGovernanceUpgradeScript.s.sol index f0fc73617..1e35d3fe4 100644 --- a/l1-contracts/deploy-scripts/DecentralizeGovernanceUpgradeScript.s.sol +++ b/l1-contracts/deploy-scripts/DecentralizeGovernanceUpgradeScript.s.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT +// solhint-disable reason-string, gas-custom-errors pragma solidity 0.8.24; import {Script} from "forge-std/Script.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol"; +import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {Governance} from "contracts/governance/Governance.sol"; import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; diff --git a/l1-contracts/deploy-scripts/DeployErc20.s.sol b/l1-contracts/deploy-scripts/DeployErc20.s.sol index b391e5105..60f34230a 100644 --- a/l1-contracts/deploy-scripts/DeployErc20.s.sol +++ b/l1-contracts/deploy-scripts/DeployErc20.s.sol @@ -119,11 +119,14 @@ contract DeployErc20Script is Script { if (mint > 0) { vm.broadcast(); additionalAddressesForMinting.push(config.deployerAddress); - for (uint256 i = 0; i < additionalAddressesForMinting.length; i++) { + uint256 addressMintListLength = additionalAddressesForMinting.length; + for (uint256 i = 0; i < addressMintListLength; ++i) { (bool success, ) = tokenAddress.call( abi.encodeWithSignature("mint(address,uint256)", additionalAddressesForMinting[i], mint) ); - require(success, "Mint failed"); + if (!success) { + revert MintFailed(); + } console.log("Minting to:", additionalAddressesForMinting[i]); } } diff --git a/l1-contracts/deploy-scripts/DeployL1.s.sol b/l1-contracts/deploy-scripts/DeployL1.s.sol index 51eb55346..098aee5bc 100644 --- a/l1-contracts/deploy-scripts/DeployL1.s.sol +++ b/l1-contracts/deploy-scripts/DeployL1.s.sol @@ -5,8 +5,8 @@ pragma solidity 0.8.24; import {Script, console2 as console} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {Utils} from "./Utils.sol"; import {Multicall3} from "contracts/dev-contracts/Multicall3.sol"; diff --git a/l1-contracts/deploy-scripts/DeployL2Contracts.sol b/l1-contracts/deploy-scripts/DeployL2Contracts.sol index e3de2d82d..0d7c1e0bb 100644 --- a/l1-contracts/deploy-scripts/DeployL2Contracts.sol +++ b/l1-contracts/deploy-scripts/DeployL2Contracts.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.24; +pragma solidity ^0.8.21; import {Script} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; @@ -72,20 +72,22 @@ contract DeployL2Script is Script { function loadContracts() internal { //HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat - contracts.l2StandardErc20FactoryBytecode = Utils.readFoundryBytecode( - "/../l2-contracts/zkout/UpgradeableBeacon.sol/UpgradeableBeacon.json" + contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" ); - contracts.beaconProxy = Utils.readFoundryBytecode("/../l2-contracts/zkout/BeaconProxy.sol/BeaconProxy.json"); - contracts.l2StandardErc20Bytecode = Utils.readFoundryBytecode( - "/../l2-contracts/zkout/L2StandardERC20.sol/L2StandardERC20.json" + contracts.beaconProxy = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol/BeaconProxy.json" + ); + contracts.l2StandardErc20Bytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" ); contracts.l2SharedBridgeBytecode = Utils.readFoundryBytecode( "/../l2-contracts/zkout/L2SharedBridge.sol/L2SharedBridge.json" ); - contracts.l2SharedBridgeProxyBytecode = Utils.readFoundryBytecode( - "/../l2-contracts/zkout/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" + contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" ); contracts.forceDeployUpgrader = Utils.readFoundryBytecode( "/../l2-contracts/zkout/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" diff --git a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol index d6d854363..08374e3d1 100644 --- a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol +++ b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.24; +pragma solidity ^0.8.21; import {Script} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; diff --git a/l1-contracts/deploy-scripts/InitializeL2WethToken.s.sol b/l1-contracts/deploy-scripts/InitializeL2WethToken.s.sol index 815008317..c9b1de8c6 100644 --- a/l1-contracts/deploy-scripts/InitializeL2WethToken.s.sol +++ b/l1-contracts/deploy-scripts/InitializeL2WethToken.s.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.21; // solhint-disable no-console import {Script, console2 as console} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {Utils} from "./Utils.sol"; import {L2TransactionRequestDirect} from "contracts/bridgehub/IBridgehub.sol"; diff --git a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol index ab3e73ea9..e0039b969 100644 --- a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol +++ b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol @@ -7,7 +7,7 @@ import {Script, console2 as console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; import {stdToml} from "forge-std/StdToml.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {Ownable} from "@openzeppelin/contracts-v4/access/Ownable.sol"; import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 4b74035c0..24011951b 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -8,7 +8,7 @@ import {Vm} from "forge-std/Vm.sol"; import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; import {L2TransactionRequestDirect} from "contracts/bridgehub/IBridgehub.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; import {L2_DEPLOYER_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol"; import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index b0bd14e79..2051dd070 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -1,35 +1,12 @@ [profile.default] src = 'contracts' out = 'out' -libs = ['node_modules', 'lib'] -remappings = [ - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", - "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", - "murky=lib/murky/src/", - "l2-contracts/=../l2-contracts/contracts/" -] -allow_paths = ["../l2-contracts/contracts"] -fs_permissions = [ - { access = "read", path = "../system-contracts/bootloader/build/artifacts" }, - { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed" }, - { access = "read", path = "../l2-contracts/artifacts-zk/" }, - { access = "read", path = "../l2-contracts/zkout/" }, - { access = "read", path = "../system-contracts/zkout/" }, - { access = "read", path = "./script-config" }, - { access = "read-write", path = "./script-out" }, - { access = "read", path = "./out" } -] +libs = ['node_modules', '../lib'] cache_path = 'cache-forge' test = 'test/foundry' solc_version = "0.8.24" evm_version = "cancun" -ignored_error_codes = [ - "missing-receive-ether", - "code-size", -] -ignored_warnings_from = [ - "test", - "contracts/dev-contracts" -] +ignored_error_codes = ["missing-receive-ether", "code-size"] +ignored_warnings_from = ["test", "contracts/dev-contracts"] # See more config options https://github.com/foundry-rs/foundry/tree/master/crates/config diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std deleted file mode 120000 index edce15694..000000000 --- a/l1-contracts/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -../../lib/forge-std \ No newline at end of file diff --git a/l1-contracts/lib/murky b/l1-contracts/lib/murky deleted file mode 120000 index a556a15e5..000000000 --- a/l1-contracts/lib/murky +++ /dev/null @@ -1 +0,0 @@ -../../lib/murky \ No newline at end of file diff --git a/l1-contracts/lib/openzeppelin-contracts b/l1-contracts/lib/openzeppelin-contracts deleted file mode 120000 index 99aa45507..000000000 --- a/l1-contracts/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -../../lib/openzeppelin-contracts \ No newline at end of file diff --git a/l1-contracts/lib/openzeppelin-contracts-upgradeable b/l1-contracts/lib/openzeppelin-contracts-upgradeable deleted file mode 120000 index f1fc7a76a..000000000 --- a/l1-contracts/lib/openzeppelin-contracts-upgradeable +++ /dev/null @@ -1 +0,0 @@ -../../lib/openzeppelin-contracts-upgradeable \ No newline at end of file diff --git a/l1-contracts/package.json b/l1-contracts/package.json index de33649f8..aaceec20c 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -9,8 +9,8 @@ "@nomiclabs/hardhat-ethers": "^2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.0", "@nomiclabs/hardhat-waffle": "^2.0.0", - "@openzeppelin/contracts": "4.9.5", - "@openzeppelin/contracts-upgradeable": "4.9.5", + "@openzeppelin/contracts-upgradeable-v4": "npm:@openzeppelin/contracts-upgradeable@4.9.5", + "@openzeppelin/contracts-v4": "npm:@openzeppelin/contracts@4.9.5", "@typechain/ethers-v5": "^2.0.0", "@types/argparse": "^1.0.36", "@types/chai": "^4.2.21", diff --git a/l1-contracts/remappings.txt b/l1-contracts/remappings.txt index d866a0c22..1b0710cf5 100644 --- a/l1-contracts/remappings.txt +++ b/l1-contracts/remappings.txt @@ -1,7 +1,7 @@ -@ensdomains/=node_modules/@ensdomains/ -ds-test/=lib/forge-std/lib/ds-test/src/ -eth-gas-reporter/=node_modules/eth-gas-reporter/ -forge-std/=lib/forge-std/src/ -hardhat/=node_modules/hardhat/ -murky/=lib/murky/src/ +@ensdomains/=../node_modules/@ensdomains/ +ds-test/=../lib/forge-std/lib/ds-test/src/ +eth-gas-reporter/=../node_modules/eth-gas-reporter/ +forge-std/=../lib/forge-std/src/ +hardhat/=../node_modules/hardhat/ +murky/=../lib/murky/src/ foundry-test/=test/foundry/ diff --git a/l1-contracts/scripts/initialize-l2-weth-token.ts b/l1-contracts/scripts/initialize-l2-weth-token.ts index f38b1f8f8..4bf9dd933 100644 --- a/l1-contracts/scripts/initialize-l2-weth-token.ts +++ b/l1-contracts/scripts/initialize-l2-weth-token.ts @@ -20,7 +20,7 @@ const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "cont const l2BridgeArtifactsPath = path.join(contractArtifactsPath, "contracts/bridge/"); const openzeppelinTransparentProxyArtifactsPath = path.join( contractArtifactsPath, - "@openzeppelin/contracts/proxy/transparent/" + "@openzeppelin/contracts-v4/proxy/transparent/" ); function readInterface(path: string, fileName: string, solFileName?: string) { @@ -34,7 +34,7 @@ const L2_WETH_INTERFACE = readInterface(l2BridgeArtifactsPath, "L2WrappedBaseTok const TRANSPARENT_UPGRADEABLE_PROXY = readInterface( openzeppelinTransparentProxyArtifactsPath, "ITransparentUpgradeableProxy", - "TransparentUpgradeableProxy" + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy" ); function getL2Calldata(l2SharedBridgeAddress: string, l1WethTokenAddress: string, l2WethTokenImplAddress: string) { diff --git a/l1-contracts/scripts/setup-legacy-bridge-era.ts b/l1-contracts/scripts/setup-legacy-bridge-era.ts index dde08b6f2..deaf060fa 100644 --- a/l1-contracts/scripts/setup-legacy-bridge-era.ts +++ b/l1-contracts/scripts/setup-legacy-bridge-era.ts @@ -16,7 +16,7 @@ import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; import { ethTestConfig, getAddressFromEnv } from "../src.ts/utils"; import { hashL2Bytecode } from "../../l2-contracts/src/utils"; import { Provider } from "zksync-ethers"; -import beaconProxy = require("../../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json"); +import beaconProxy = require("../../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol/BeaconProxy.json"); const provider = web3Provider(); @@ -64,7 +64,9 @@ async function main() { await deployer.deploySharedBridgeImplementation(create2Salt, { nonce }); - const proxyAdminInterface = new Interface(hardhat.artifacts.readArtifactSync("ProxyAdmin").abi); + const proxyAdminInterface = new Interface( + hardhat.artifacts.readArtifactSync("@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol:ProxyAdmin").abi + ); let calldata = proxyAdminInterface.encodeFunctionData("upgrade(address,address)", [ deployer.addresses.Bridges.SharedBridgeProxy, deployer.addresses.Bridges.SharedBridgeImplementation, diff --git a/l1-contracts/scripts/upgrade-consistency-checker.ts b/l1-contracts/scripts/upgrade-consistency-checker.ts index 5da064a04..530d47dc3 100644 --- a/l1-contracts/scripts/upgrade-consistency-checker.ts +++ b/l1-contracts/scripts/upgrade-consistency-checker.ts @@ -112,7 +112,9 @@ async function extractInitCode(data: string) { async function extractProxyInitializationData(contract: ethers.Contract, data: string) { const initCode = await extractInitCode(data); - const artifact = await hardhat.artifacts.readArtifact("TransparentUpgradeableProxy"); + const artifact = await hardhat.artifacts.readArtifact( + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy" + ); // Deployment tx is a concatenation of the init code and the constructor data // constructor has the following type `constructor(address _logic, address admin_, bytes memory _data)` @@ -449,9 +451,11 @@ async function checkLegacyBridge() { } async function checkProxyAdmin() { - await checkIdenticalBytecode(proxyAdmin, "ProxyAdmin"); + await checkIdenticalBytecode(proxyAdmin, "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol:ProxyAdmin"); - const artifact = await hardhat.artifacts.readArtifact("ProxyAdmin"); + const artifact = await hardhat.artifacts.readArtifact( + "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol:ProxyAdmin" + ); const contract = new ethers.Contract(proxyAdmin, artifact.abi, l1Provider); const currentOwner = await contract.owner(); diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index c1229e60f..3ee3bb07b 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -241,9 +241,12 @@ export class Deployer { console.log("Deploying Proxy Admin"); } // Note: we cannot deploy using Create2, as the owner of the ProxyAdmin is msg.sender - const contractFactory = await hardhat.ethers.getContractFactory("ProxyAdmin", { - signer: this.deployWallet, - }); + const contractFactory = await hardhat.ethers.getContractFactory( + "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", + { + signer: this.deployWallet, + } + ); const proxyAdmin = await contractFactory.deploy(...[ethTxOptions]); const rec = await proxyAdmin.deployTransaction.wait(); @@ -279,7 +282,7 @@ export class Deployer { const initCalldata = bridgehub.encodeFunctionData("initialize", [this.ownerAddress]); const contractAddress = await this.deployViaCreate2( - "TransparentUpgradeableProxy", + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy", [this.addresses.Bridgehub.BridgehubImplementation, this.addresses.TransparentProxyAdmin, initCalldata], create2Salt, ethTxOptions @@ -343,7 +346,7 @@ export class Deployer { ]); const contractAddress = await this.deployViaCreate2( - "TransparentUpgradeableProxy", + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy", [ this.addresses.StateTransition.StateTransitionImplementation, this.addresses.TransparentProxyAdmin, @@ -539,7 +542,7 @@ export class Deployer { "initialize" ); const contractAddress = await this.deployViaCreate2( - "TransparentUpgradeableProxy", + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy", [this.addresses.Bridges.ERC20BridgeImplementation, this.addresses.TransparentProxyAdmin, initCalldata], create2Salt, ethTxOptions @@ -582,7 +585,7 @@ export class Deployer { [this.addresses.Governance] ); const contractAddress = await this.deployViaCreate2( - "TransparentUpgradeableProxy", + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy", [this.addresses.Bridges.SharedBridgeImplementation, this.addresses.TransparentProxyAdmin, initCalldata], create2Salt, ethTxOptions diff --git a/l1-contracts/test/foundry/integration/deploy-scripts/script-out/output-deploy-l1.toml b/l1-contracts/test/foundry/integration/deploy-scripts/script-out/output-deploy-l1.toml new file mode 100644 index 000000000..fa3301825 --- /dev/null +++ b/l1-contracts/test/foundry/integration/deploy-scripts/script-out/output-deploy-l1.toml @@ -0,0 +1,54 @@ +create2_factory_salt = "0x00000000000000000000000000000000000000000000000000000000000000ff" +deployer_addr = "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496" +era_chain_id = 9 +l1_chain_id = 31337 +multicall3_addr = "0x9735C424DEa176DC4304D1A240C824783D841f20" +owner_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + +[contracts_config] +diamond_cut_data = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000009a5d498f9fdab5d26090b68aec33363ac3706c5e0000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000bc0000000000000000000000000c49e34de76847b6ce4933cae561d6ae7c72b1c2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000140e18b681000000000000000000000000000000000000000000000000000000001733894500000000000000000000000000000000000000000000000000000000fc57565f000000000000000000000000000000000000000000000000000000001cc5d1030000000000000000000000000000000000000000000000000000000021f603d700000000000000000000000000000000000000000000000000000000235d9eb50000000000000000000000000000000000000000000000000000000027ae4c160000000000000000000000000000000000000000000000000000000043dc2951000000000000000000000000000000000000000000000000000000004623c91d000000000000000000000000000000000000000000000000000000004dd18bf5000000000000000000000000000000000000000000000000000000006223258e0000000000000000000000000000000000000000000000000000000064b554ad0000000000000000000000000000000000000000000000000000000064bf8d660000000000000000000000000000000000000000000000000000000082b57749000000000000000000000000000000000000000000000000000000008c564cc100000000000000000000000000000000000000000000000000000000a37dc1d400000000000000000000000000000000000000000000000000000000a3bd011200000000000000000000000000000000000000000000000000000000a9f6d94100000000000000000000000000000000000000000000000000000000be6f11cf00000000000000000000000000000000000000000000000000000000e76db86500000000000000000000000000000000000000000000000000000000000000000000000000000000ab0aa7c14904459f4bcde7f3b465546f022ec22a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000002c06d49e5b00000000000000000000000000000000000000000000000000000000086a56f8000000000000000000000000000000000000000000000000000000000ec6b0b700000000000000000000000000000000000000000000000000000000fe26699e0000000000000000000000000000000000000000000000000000000018e3a941000000000000000000000000000000000000000000000000000000001de72e340000000000000000000000000000000000000000000000000000000029b98c670000000000000000000000000000000000000000000000000000000033ce93fe000000000000000000000000000000000000000000000000000000003408e470000000000000000000000000000000000000000000000000000000003591c1a000000000000000000000000000000000000000000000000000000000396073820000000000000000000000000000000000000000000000000000000039d7d4aa0000000000000000000000000000000000000000000000000000000046657fe90000000000000000000000000000000000000000000000000000000052ef6b2c000000000000000000000000000000000000000000000000000000005518c73b0000000000000000000000000000000000000000000000000000000056142d7a00000000000000000000000000000000000000000000000000000000631f4bac000000000000000000000000000000000000000000000000000000006e9960c30000000000000000000000000000000000000000000000000000000074f4d30d0000000000000000000000000000000000000000000000000000000079823c9a000000000000000000000000000000000000000000000000000000007a0ed627000000000000000000000000000000000000000000000000000000007b30c8da0000000000000000000000000000000000000000000000000000000098acd7a6000000000000000000000000000000000000000000000000000000009cd939e4000000000000000000000000000000000000000000000000000000009d1b5a8100000000000000000000000000000000000000000000000000000000a1954fc500000000000000000000000000000000000000000000000000000000a7358efb00000000000000000000000000000000000000000000000000000000adfca15e00000000000000000000000000000000000000000000000000000000af6a2dcd00000000000000000000000000000000000000000000000000000000b22dd78e00000000000000000000000000000000000000000000000000000000b8c2f66f00000000000000000000000000000000000000000000000000000000bd7c541200000000000000000000000000000000000000000000000000000000c3bbd2d700000000000000000000000000000000000000000000000000000000cdffacc600000000000000000000000000000000000000000000000000000000d046815600000000000000000000000000000000000000000000000000000000d86970d800000000000000000000000000000000000000000000000000000000db1f0bf900000000000000000000000000000000000000000000000000000000e5355c7500000000000000000000000000000000000000000000000000000000e81e0ba100000000000000000000000000000000000000000000000000000000ea6c029c00000000000000000000000000000000000000000000000000000000ef3f0bae00000000000000000000000000000000000000000000000000000000f5c1182c00000000000000000000000000000000000000000000000000000000facd743b00000000000000000000000000000000000000000000000000000000fd791f3c0000000000000000000000000000000000000000000000000000000000000000000000000000000066825543c5c82b711de855426946f6929573cf55000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000b042901c70000000000000000000000000000000000000000000000000000000008522c300000000000000000000000000000000000000000000000000000000012f43dab00000000000000000000000000000000000000000000000000000000eb67241900000000000000000000000000000000000000000000000000000000263b7f8e000000000000000000000000000000000000000000000000000000006c0960f9000000000000000000000000000000000000000000000000000000007efda2ae00000000000000000000000000000000000000000000000000000000b473318e00000000000000000000000000000000000000000000000000000000d06b26e200000000000000000000000000000000000000000000000000000000dcabb98200000000000000000000000000000000000000000000000000000000e4948f430000000000000000000000000000000000000000000000000000000000000000000000000000000049c0372a531af3cf3fe715c1918c278c07affce5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000800a22e22000000000000000000000000000000000000000000000000000000000f23da4300000000000000000000000000000000000000000000000000000000c37533bb000000000000000000000000000000000000000000000000000000006edd4f1200000000000000000000000000000000000000000000000000000000701f58c5000000000000000000000000000000000000000000000000000000007f61885c0000000000000000000000000000000000000000000000000000000097c09d3400000000000000000000000000000000000000000000000000000000bd6db4990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000032c101edc4d322abd5da779f1a5376e412e21160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c4b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000001d4c00000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000000000182b8000000000000000000000000000000000000000000000000000000000ee6b280000000000000000000000000a4cb26d6933d2c3e76718d30de8547bcdf8dd241" +diamond_init_batch_overhead_l1_gas = 1000000 +diamond_init_max_l2_gas_per_batch = 80000000 +diamond_init_max_pubdata_per_batch = 120000 +diamond_init_minimal_l2_gas_price = 250000000 +diamond_init_priority_tx_max_pubdata = 99000 +diamond_init_pubdata_pricing_mode = 0 +force_deployments_data = "0x00" +priority_tx_max_gas_limit = 80000000 +recursion_circuits_set_vks_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +recursion_leaf_level_vk_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +recursion_node_level_vk_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + +[deployed_addresses] +blob_versioned_hash_retriever_addr = "0xA4cB26d6933D2c3E76718D30de8547bCDF8dD241" +governance_addr = "0x6ba327EAE385c52A861b1cacAc60021F03489413" +native_token_vault_addr = "0x153e4040C649Fe562cAa0A71Fd79f79BCA2593aB" +transparent_proxy_admin_addr = "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809" +validator_timelock_addr = "0xDb50CefBF1F40e85951dAbd0194c477D6270Fe5E" + +[deployed_addresses.bridgehub] +bridgehub_implementation_addr = "0xa53970305e11ac9eD420Ec7C7AABb59fC3a64B0e" +bridgehub_proxy_addr = "0xC6585692481e509DDD11Eb2033535c6FF6e89B99" +message_root_implementation_addr = "0x67c321b17102Cbd39068B8bAeC3fF925FEc76C46" +message_root_proxy_addr = "0x88001933Ff48C53181cf1b11935AC2126954cb9e" +stm_deployment_tracker_implementation_addr = "0x205CEF369839dF59C016b02e4ECb45fB706576d0" +stm_deployment_tracker_proxy_addr = "0x8D9731582480f2CB74BC93168D86fB26788986b2" + +[deployed_addresses.bridges] +erc20_bridge_implementation_addr = "0xD23dF92Df88AF35d9f804BCd576B12C212A8BbD9" +erc20_bridge_proxy_addr = "0x6DDEFe6C5B5068347E278D5Be9B2a8a81c9C4F23" +shared_bridge_implementation_addr = "0xA66087143CEBcd6859aEd08420B1228De567Cd88" +shared_bridge_proxy_addr = "0x1e1314a32AaE641325b6BEfC625f499f1d7c7B2a" + +[deployed_addresses.state_transition] +admin_facet_addr = "0xC49E34dE76847b6Ce4933caE561d6aE7C72B1c25" +default_upgrade_addr = "0x7C0213Ecf479fE20b03B9e0d5a62B6D1602fe9a5" +diamond_init_addr = "0x9a5D498f9FdAB5D26090B68AEc33363ac3706C5e" +diamond_proxy_addr = "0x0000000000000000000000000000000000000000" +executor_facet_addr = "0x49C0372A531aF3cF3Fe715c1918c278c07aFfCe5" +genesis_upgrade_addr = "0xAFAb4F3F4B7984A3A93A5eC3B1028aC6e7194602" +getters_facet_addr = "0xab0AA7c14904459F4bCDe7f3B465546f022ec22A" +mailbox_facet_addr = "0x66825543c5c82b711de855426946f6929573cF55" +state_transition_implementation_addr = "0x2051075b03d1F2E0902C9cFd349fbdD4c73bB2d4" +state_transition_proxy_addr = "0x236e89885449f7ef4650743Ba350Fd557060905E" +verifier_addr = "0x32C101EDC4D322AbD5da779f1A5376e412E21160" diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/Initialize.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/Initialize.t.sol index 38bba5ec2..a31095dea 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/Initialize.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/Initialize.t.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.21; import {BridgehubTest} from "./_Bridgehub_Shared.t.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/_Bridgehub_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/_Bridgehub_Shared.t.sol index 3d0b445a5..54d264daa 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/_Bridgehub_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/_Bridgehub_Shared.t.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.21; import {Test} from "forge-std/Test.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol index 2f15cdc88..27174089b 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol @@ -17,6 +17,7 @@ import {L2TransactionRequestTwoBridgesInner} from "contracts/bridgehub/IBridgehu import {L2Message, L2Log, TxStatus, BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; import {ETH_TOKEN_ADDRESS, REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS, TWO_BRIDGES_MAGIC_VALUE} from "contracts/common/Config.sol"; import {L1ERC20Bridge} from "contracts/bridge/L1ERC20Bridge.sol"; +import {ZeroChainId, AddressTooLow, ChainIdTooBig, WrongMagicValue, SharedBridgeNotSet, TokenNotRegistered, BridgeHubAlreadyRegistered, MsgValueMismatch, SlotOccupied, STMAlreadyRegistered, TokenAlreadyRegistered, Unauthorized, NonEmptyMsgValue, STMNotRegistered, InvalidChainId} from "contracts/common/L1ContractErrors.sol"; contract ExperimentalBridgeTest is Test { using stdStorage for StdStorage; @@ -94,7 +95,7 @@ contract ExperimentalBridgeTest is Test { defaultOwner = bridgeHub.owner(); // Now, the `reentrancyGuardInitializer` should prevent anyone from calling `initialize` since we have called the constructor of the contract - vm.expectRevert(bytes("1B")); + vm.expectRevert(SlotOccupied.selector); bridgeHub.initialize(bridgeOwner); vm.store( @@ -123,6 +124,8 @@ contract ExperimentalBridgeTest is Test { } function test_newPendingAdminReplacesPrevious(address randomDeployer, address otherRandomDeployer) public { + vm.assume(randomDeployer != address(0)); + vm.assume(otherRandomDeployer != address(0)); assertEq(address(0), bridgeHub.admin()); vm.assume(randomDeployer != otherRandomDeployer); @@ -139,13 +142,15 @@ contract ExperimentalBridgeTest is Test { } function test_onlyPendingAdminCanAccept(address randomDeployer, address otherRandomDeployer) public { + vm.assume(randomDeployer != address(0)); + vm.assume(otherRandomDeployer != address(0)); assertEq(address(0), bridgeHub.admin()); vm.assume(randomDeployer != otherRandomDeployer); vm.prank(bridgeHub.owner()); bridgeHub.setPendingAdmin(randomDeployer); - vm.expectRevert(bytes("n42")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, otherRandomDeployer)); vm.prank(otherRandomDeployer); bridgeHub.acceptAdmin(); @@ -153,6 +158,7 @@ contract ExperimentalBridgeTest is Test { } function test_onlyOwnerCanSetDeployer(address randomDeployer) public { + vm.assume(randomDeployer != address(0)); assertEq(address(0), bridgeHub.admin()); vm.prank(bridgeHub.owner()); @@ -166,7 +172,7 @@ contract ExperimentalBridgeTest is Test { function test_randomCallerCannotSetDeployer(address randomCaller, address randomDeployer) public { if (randomCaller != bridgeHub.owner() && randomCaller != bridgeHub.admin()) { vm.prank(randomCaller); - vm.expectRevert(bytes("Bridgehub: not owner or admin")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomCaller)); bridgeHub.setPendingAdmin(randomDeployer); // The deployer shouldn't have changed. @@ -175,6 +181,7 @@ contract ExperimentalBridgeTest is Test { } function test_addStateTransitionManager(address randomAddressWithoutTheCorrectInterface) public { + vm.assume(randomAddressWithoutTheCorrectInterface != address(0)); bool isSTMRegistered = bridgeHub.stateTransitionManagerIsRegistered(randomAddressWithoutTheCorrectInterface); assertTrue(!isSTMRegistered); @@ -186,7 +193,7 @@ contract ExperimentalBridgeTest is Test { // An address that has already been registered, cannot be registered again (at least not before calling `removeStateTransitionManager`). vm.prank(bridgeOwner); - vm.expectRevert(bytes("Bridgehub: state transition already registered")); + vm.expectRevert(STMAlreadyRegistered.selector); bridgeHub.addStateTransitionManager(randomAddressWithoutTheCorrectInterface); isSTMRegistered = bridgeHub.stateTransitionManagerIsRegistered(randomAddressWithoutTheCorrectInterface); @@ -197,6 +204,7 @@ contract ExperimentalBridgeTest is Test { address randomCaller, address randomAddressWithoutTheCorrectInterface ) public { + vm.assume(randomAddressWithoutTheCorrectInterface != address(0)); bool isSTMRegistered = bridgeHub.stateTransitionManagerIsRegistered(randomAddressWithoutTheCorrectInterface); assertTrue(!isSTMRegistered); @@ -215,7 +223,7 @@ contract ExperimentalBridgeTest is Test { // An address that has already been registered, cannot be registered again (at least not before calling `removeStateTransitionManager`). vm.prank(bridgeOwner); - vm.expectRevert(bytes("Bridgehub: state transition already registered")); + vm.expectRevert(STMAlreadyRegistered.selector); bridgeHub.addStateTransitionManager(randomAddressWithoutTheCorrectInterface); // Definitely not by a random caller @@ -230,12 +238,13 @@ contract ExperimentalBridgeTest is Test { } function test_removeStateTransitionManager(address randomAddressWithoutTheCorrectInterface) public { + vm.assume(randomAddressWithoutTheCorrectInterface != address(0)); bool isSTMRegistered = bridgeHub.stateTransitionManagerIsRegistered(randomAddressWithoutTheCorrectInterface); assertTrue(!isSTMRegistered); // A non-existent STM cannot be removed vm.prank(bridgeOwner); - vm.expectRevert(bytes("Bridgehub: state transition not registered yet")); + vm.expectRevert(STMNotRegistered.selector); bridgeHub.removeStateTransitionManager(randomAddressWithoutTheCorrectInterface); // Let's first register our particular stateTransitionManager @@ -254,7 +263,7 @@ contract ExperimentalBridgeTest is Test { // An already removed STM cannot be removed again vm.prank(bridgeOwner); - vm.expectRevert(bytes("Bridgehub: state transition not registered yet")); + vm.expectRevert(STMNotRegistered.selector); bridgeHub.removeStateTransitionManager(randomAddressWithoutTheCorrectInterface); } @@ -262,6 +271,7 @@ contract ExperimentalBridgeTest is Test { address randomAddressWithoutTheCorrectInterface, address randomCaller ) public { + vm.assume(randomAddressWithoutTheCorrectInterface != address(0)); bool isSTMRegistered = bridgeHub.stateTransitionManagerIsRegistered(randomAddressWithoutTheCorrectInterface); assertTrue(!isSTMRegistered); @@ -274,7 +284,7 @@ contract ExperimentalBridgeTest is Test { // A non-existent STM cannot be removed vm.prank(bridgeOwner); - vm.expectRevert(bytes("Bridgehub: state transition not registered yet")); + vm.expectRevert(STMNotRegistered.selector); bridgeHub.removeStateTransitionManager(randomAddressWithoutTheCorrectInterface); // Let's first register our particular stateTransitionManager @@ -293,7 +303,7 @@ contract ExperimentalBridgeTest is Test { // An already removed STM cannot be removed again vm.prank(bridgeOwner); - vm.expectRevert(bytes("Bridgehub: state transition not registered yet")); + vm.expectRevert(STMNotRegistered.selector); bridgeHub.removeStateTransitionManager(randomAddressWithoutTheCorrectInterface); // Not possible by a randomcaller as well @@ -325,7 +335,7 @@ contract ExperimentalBridgeTest is Test { // An already registered token cannot be registered again vm.prank(bridgeOwner); - vm.expectRevert("Bridgehub: token already registered"); + vm.expectRevert(abi.encodeWithSelector(TokenAlreadyRegistered.selector, address(randomAddress))); bridgeHub.addToken(randomAddress); } @@ -361,12 +371,13 @@ contract ExperimentalBridgeTest is Test { // An already registered token cannot be registered again by randomCaller if (randomCaller != bridgeOwner) { vm.prank(bridgeOwner); - vm.expectRevert("Bridgehub: token already registered"); + vm.expectRevert(abi.encodeWithSelector(TokenAlreadyRegistered.selector, address(randomAddress))); bridgeHub.addToken(randomAddress); } } function test_setSharedBridge(address randomAddress) public { + vm.assume(randomAddress != address(0)); assertTrue( bridgeHub.sharedBridge() == IL1SharedBridge(address(0)), "This random address is not registered as sharedBridge" @@ -382,6 +393,7 @@ contract ExperimentalBridgeTest is Test { } function test_setSharedBridge_cannotBeCalledByRandomAddress(address randomCaller, address randomAddress) public { + vm.assume(randomAddress != address(0)); if (randomCaller != bridgeOwner) { vm.prank(randomCaller); vm.expectRevert(bytes("Ownable: caller is not the owner")); @@ -435,7 +447,7 @@ contract ExperimentalBridgeTest is Test { vm.prank(bridgeOwner); bridgeHub.unpause(); - vm.expectRevert("Bridgehub: state transition not registered"); + vm.expectRevert(STMNotRegistered.selector); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: 1, @@ -462,7 +474,7 @@ contract ExperimentalBridgeTest is Test { bridgeHub.acceptAdmin(); chainId = bound(chainId, 1, type(uint48).max); - vm.expectRevert("Bridgehub: state transition not registered"); + vm.expectRevert(STMNotRegistered.selector); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: chainId, @@ -489,7 +501,7 @@ contract ExperimentalBridgeTest is Test { bridgeHub.acceptAdmin(); chainId = bound(chainId, type(uint48).max + uint256(1), type(uint256).max); - vm.expectRevert("Bridgehub: chainId too large"); + vm.expectRevert(ChainIdTooBig.selector); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: chainId, @@ -501,7 +513,7 @@ contract ExperimentalBridgeTest is Test { }); chainId = 0; - vm.expectRevert("Bridgehub: chainId cannot be 0"); + vm.expectRevert(ZeroChainId.selector); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: chainId, @@ -531,7 +543,7 @@ contract ExperimentalBridgeTest is Test { bridgeHub.addStateTransitionManager(address(mockSTM)); vm.stopPrank(); - vm.expectRevert("Bridgehub: token not registered"); + vm.expectRevert(abi.encodeWithSelector(TokenNotRegistered.selector, address(testToken))); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: chainId, @@ -562,7 +574,7 @@ contract ExperimentalBridgeTest is Test { bridgeHub.addToken(address(testToken)); vm.stopPrank(); - vm.expectRevert("Bridgehub: weth bridge not set"); + vm.expectRevert(SharedBridgeNotSet.selector); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: chainId, @@ -597,7 +609,7 @@ contract ExperimentalBridgeTest is Test { address(mockSTM) ); - vm.expectRevert("Bridgehub: chainId already registered"); + vm.expectRevert(BridgeHubAlreadyRegistered.selector); vm.prank(deployerAddress); bridgeHub.createNewChain({ _chainId: chainId, @@ -636,7 +648,7 @@ contract ExperimentalBridgeTest is Test { if (randomCaller != deployerAddress && randomCaller != bridgeOwner) { vm.prank(randomCaller); - vm.expectRevert(bytes("Bridgehub: not owner or admin")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomCaller)); bridgeHub.createNewChain({ _chainId: chainId, _stateTransitionManager: address(mockSTM), @@ -958,7 +970,7 @@ contract ExperimentalBridgeTest is Test { }); vm.deal(randomCaller, msgValue); - vm.expectRevert("Bridgehub: msg.value mismatch 1"); + vm.expectRevert(abi.encodeWithSelector(MsgValueMismatch.selector, mockMintValue, msgValue)); vm.prank(randomCaller); bridgeHub.requestL2TransactionDirect{value: msgValue}(l2TxnReqDirect); } @@ -1055,7 +1067,7 @@ contract ExperimentalBridgeTest is Test { vm.deal(randomCaller, 1 ether); vm.prank(randomCaller); - vm.expectRevert("Bridgehub: non-eth bridge with msg.value"); + vm.expectRevert(abi.encodeWithSelector(MsgValueMismatch.selector, 0, randomCaller.balance)); bytes32 resultantHash = bridgeHub.requestL2TransactionDirect{value: randomCaller.balance}(l2TxnReqDirect); // Now, let's call the same function with zero msg.value @@ -1125,7 +1137,7 @@ contract ExperimentalBridgeTest is Test { abi.encode(request) ); - vm.expectRevert("Bridgehub: magic value mismatch"); + vm.expectRevert(abi.encodeWithSelector(WrongMagicValue.selector, TWO_BRIDGES_MAGIC_VALUE, magicValue)); vm.prank(randomCaller); bridgeHub.requestL2TransactionTwoBridges{value: randomCaller.balance}(l2TxnReq2BridgeOut); } @@ -1204,7 +1216,7 @@ contract ExperimentalBridgeTest is Test { ); l2TxnReq2BridgeOut.secondBridgeAddress = address(secondBridgeAddressValue); - vm.expectRevert("Bridgehub: second bridge address too low"); + vm.expectRevert(abi.encodeWithSelector(AddressTooLow.selector, secondBridgeAddress)); vm.prank(randomCaller); bridgeHub.requestL2TransactionTwoBridges{value: randomCaller.balance}(l2TxnReq2BridgeOut); } @@ -1277,7 +1289,7 @@ contract ExperimentalBridgeTest is Test { testToken.mint(randomCaller, l2TxnReq2BridgeOut.mintValue); vm.startPrank(randomCaller); testToken.approve(sharedBridgeAddress, l2TxnReq2BridgeOut.mintValue); - vm.expectRevert("Bridgehub: msg.value mismatch 3"); + vm.expectRevert(abi.encodeWithSelector(MsgValueMismatch.selector, l2TxnReq2BridgeOut.secondBridgeValue, 0)); bridgeHub.requestL2TransactionTwoBridges(l2TxnReq2BridgeOut); vm.stopPrank(); } @@ -1321,17 +1333,21 @@ contract ExperimentalBridgeTest is Test { mockChainContract.setBridgeHubAddress(address(bridgeHub)); - bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); + { + bytes32 canonicalHash = keccak256(abi.encode("CANONICAL_TX_HASH")); - vm.mockCall( - address(mockChainContract), - abi.encodeWithSelector(mockChainContract.bridgehubRequestL2Transaction.selector), - abi.encode(canonicalHash) - ); + vm.mockCall( + address(mockChainContract), + abi.encodeWithSelector(mockChainContract.bridgehubRequestL2Transaction.selector), + abi.encode(canonicalHash) + ); + } if (msgValue != secondBridgeValue) { vm.deal(randomCaller, msgValue); - vm.expectRevert("Bridgehub: msg.value mismatch 3"); + vm.expectRevert( + abi.encodeWithSelector(MsgValueMismatch.selector, l2TxnReq2BridgeOut.secondBridgeValue, msgValue) + ); vm.prank(randomCaller); bridgeHub.requestL2TransactionTwoBridges{value: msgValue}(l2TxnReq2BridgeOut); } diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol index 0ab45bdbc..e434dd8f4 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/ClaimFailedDeposit.t.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; import {StdStorage, stdStorage} from "forge-std/Test.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; +import {EmptyDeposit} from "contracts/common/L1ContractErrors.sol"; contract ClaimFailedDepositTest is L1Erc20BridgeTest { using stdStorage for StdStorage; @@ -12,7 +13,7 @@ contract ClaimFailedDepositTest is L1Erc20BridgeTest { event ClaimedFailedDeposit(address indexed to, address indexed l1Token, uint256 amount); function test_RevertWhen_ClaimAmountIsZero() public { - vm.expectRevert(bytes("2T")); + vm.expectRevert(EmptyDeposit.selector); bytes32[] memory merkleProof; bridge.claimFailedDeposit({ diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol index df43e652f..ee679d0e1 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Deposit.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; +import {EmptyDeposit, ValueMismatch, TokensWithFeesNotSupported} from "contracts/common/L1ContractErrors.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; contract DepositTest is L1Erc20BridgeTest { @@ -15,7 +16,7 @@ contract DepositTest is L1Erc20BridgeTest { ); function test_RevertWhen_depositAmountIsZero() public { - vm.expectRevert(bytes("0T")); + vm.expectRevert(EmptyDeposit.selector); bridge.deposit({ _l2Receiver: randomSigner, _l1Token: address(token), @@ -27,7 +28,7 @@ contract DepositTest is L1Erc20BridgeTest { } function test_RevertWhen_legacyDepositAmountIsZero() public { - vm.expectRevert(bytes("0T")); + vm.expectRevert(EmptyDeposit.selector); bridge.deposit({ _l2Receiver: randomSigner, _l1Token: address(token), @@ -85,7 +86,7 @@ contract DepositTest is L1Erc20BridgeTest { uint256 amount = 2; vm.prank(alice); feeOnTransferToken.approve(address(bridge), amount); - vm.expectRevert(bytes("3T")); + vm.expectRevert(TokensWithFeesNotSupported.selector); vm.prank(alice); bridge.deposit({ _l2Receiver: randomSigner, @@ -100,7 +101,7 @@ contract DepositTest is L1Erc20BridgeTest { uint256 amount = 4; vm.prank(alice); feeOnTransferToken.approve(address(bridge), amount); - vm.expectRevert(bytes("3T")); + vm.expectRevert(TokensWithFeesNotSupported.selector); vm.prank(alice); bridge.deposit({ _l2Receiver: randomSigner, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol index 5f39fe240..59cc80323 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/FinalizeWithdrawal.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; import {StdStorage, stdStorage} from "forge-std/Test.sol"; +import {WithdrawalAlreadyFinalized} from "contracts/common/L1ContractErrors.sol"; contract FinalizeWithdrawalTest is L1Erc20BridgeTest { using stdStorage for StdStorage; @@ -23,7 +24,7 @@ contract FinalizeWithdrawalTest is L1Erc20BridgeTest { assertTrue(bridge.isWithdrawalFinalized(l2BatchNumber, l2MessageIndex)); - vm.expectRevert(bytes("pw")); + vm.expectRevert(WithdrawalAlreadyFinalized.selector); bytes32[] memory merkleProof; bridge.finalizeWithdrawal({ _l2BatchNumber: l2BatchNumber, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Initialization.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Initialization.t.sol index 281ec169a..d3e5c9357 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Initialization.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Initialization.t.sol @@ -3,10 +3,11 @@ pragma solidity 0.8.24; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; +import {SlotOccupied} from "contracts/common/L1ContractErrors.sol"; contract InitializationTest is L1Erc20BridgeTest { function test_RevertWhen_DoubleInitialization() public { - vm.expectRevert(bytes("1B")); + vm.expectRevert(SlotOccupied.selector); bridge.initialize(); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol index cf182cac8..528239434 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/Reentrancy.t.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.24; import {StdStorage, stdStorage} from "forge-std/Test.sol"; import {L1Erc20BridgeTest} from "./_L1Erc20Bridge_Shared.t.sol"; import {ReenterL1ERC20Bridge} from "contracts/dev-contracts/test/ReenterL1ERC20Bridge.sol"; +import {SlotOccupied, Reentrancy} from "contracts/common/L1ContractErrors.sol"; contract ReentrancyTest is L1Erc20BridgeTest { using stdStorage for StdStorage; @@ -15,7 +16,7 @@ contract ReentrancyTest is L1Erc20BridgeTest { token.approve(address(bridgeReenterItself), amount); vm.prank(alice); - vm.expectRevert(bytes("r1")); + vm.expectRevert(Reentrancy.selector); bridgeReenterItself.deposit({ _l2Receiver: randomSigner, _l1Token: address(token), @@ -32,7 +33,7 @@ contract ReentrancyTest is L1Erc20BridgeTest { token.approve(address(bridgeReenterItself), amount); vm.prank(alice); - vm.expectRevert(bytes("r1")); + vm.expectRevert(Reentrancy.selector); bridgeReenterItself.deposit({ _l2Receiver: randomSigner, _l1Token: address(token), @@ -54,7 +55,7 @@ contract ReentrancyTest is L1Erc20BridgeTest { vm.prank(alice); bytes32[] memory merkleProof; - vm.expectRevert(bytes("r1")); + vm.expectRevert(Reentrancy.selector); bridgeReenterItself.claimFailedDeposit({ _depositSender: alice, _l1Token: address(token), @@ -71,7 +72,7 @@ contract ReentrancyTest is L1Erc20BridgeTest { uint256 l2MessageIndex = 4; vm.prank(alice); - vm.expectRevert(bytes("r1")); + vm.expectRevert(Reentrancy.selector); bytes32[] memory merkleProof; bridgeReenterItself.finalizeWithdrawal({ _l2BatchNumber: l2BatchNumber, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol index 753e9ab79..25b617d3e 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1Erc20Bridge/_L1Erc20Bridge_Shared.t.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; +pragma solidity ^0.8.21; import {Test} from "forge-std/Test.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol index 15ef94080..3c9272b46 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.24; import {L1SharedBridgeTest} from "./_L1SharedBridge_Shared.t.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {ETH_TOKEN_ADDRESS} from "contracts/common/Config.sol"; @@ -14,11 +14,12 @@ import {IMailbox} from "contracts/state-transition/chain-interfaces/IMailbox.sol import {IL1ERC20Bridge} from "contracts/bridge/interfaces/IL1ERC20Bridge.sol"; import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol"; import {IGetters} from "contracts/state-transition/chain-interfaces/IGetters.sol"; +import {L2BridgeNotSet, L2WithdrawalMessageWrongLength, InsufficientChainBalance, ZeroAddress, ValueMismatch, NonEmptyMsgValue, DepositExists, ValueMismatch, NonEmptyMsgValue, TokenNotSupported, EmptyDeposit, L2BridgeNotDeployed, DepositIncorrectAmount, InvalidProof, NoFundsTransferred, InsufficientFunds, DepositDoesNotExist, WithdrawalAlreadyFinalized, InsufficientFunds, MalformedMessage, InvalidSelector, TokensWithFeesNotSupported} from "contracts/common/L1ContractErrors.sol"; /// We are testing all the specified revert and require cases. contract L1SharedBridgeFailTest is L1SharedBridgeTest { function test_initialize_wrongOwner() public { - vm.expectRevert("ShB owner 0"); + vm.expectRevert(ZeroAddress.selector); new TransparentUpgradeableProxy( address(sharedBridgeImpl), admin, @@ -30,7 +31,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { function test_bridgehubDepositBaseToken_EthwrongMsgValue() public { vm.deal(bridgehubAddress, amount); vm.prank(bridgehubAddress); - vm.expectRevert("L1SharedBridge: msg.value not equal to amount"); + vm.expectRevert(abi.encodeWithSelector(ValueMismatch.selector, amount, uint256(0))); sharedBridge.bridgehubDepositBaseToken(chainId, alice, ETH_TOKEN_ADDRESS, amount); } @@ -40,7 +41,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { vm.prank(alice); token.approve(address(sharedBridge), amount); vm.prank(bridgehubAddress); - vm.expectRevert("ShB m.v > 0 b d.it"); + vm.expectRevert(NonEmptyMsgValue.selector); sharedBridge.bridgehubDepositBaseToken{value: amount}(chainId, alice, address(token), amount); } @@ -51,8 +52,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { vm.mockCall(address(token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(10)); - bytes memory message = bytes("3T"); - vm.expectRevert(message); + vm.expectRevert(TokensWithFeesNotSupported.selector); vm.prank(bridgehubAddress); sharedBridge.bridgehubDepositBaseToken(chainId, alice, address(token), amount); } @@ -67,14 +67,14 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encodeWithSelector(IBridgehub.baseToken.selector), abi.encode(address(token)) ); - vm.expectRevert("ShB l2 bridge not deployed"); + vm.expectRevert(abi.encodeWithSelector(L2BridgeNotSet.selector, chainId)); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit{value: amount}(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, 0, bob)); } function test_bridgehubDeposit_Erc_weth() public { vm.prank(bridgehubAddress); - vm.expectRevert("ShB: WETH deposit not supported"); + vm.expectRevert(abi.encodeWithSelector(TokenNotSupported.selector, l1WethAddress)); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(l1WethAddress, amount, bob)); } @@ -86,7 +86,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encodeWithSelector(IBridgehub.baseToken.selector), abi.encode(ETH_TOKEN_ADDRESS) ); - vm.expectRevert("ShB: baseToken deposit not supported"); + vm.expectRevert(abi.encodeWithSelector(TokenNotSupported.selector, ETH_TOKEN_ADDRESS)); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, 0, bob)); } @@ -101,7 +101,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encodeWithSelector(IBridgehub.baseToken.selector), abi.encode(address(token)) ); - vm.expectRevert("ShB wrong withdraw amount"); + vm.expectRevert(abi.encodeWithSelector(DepositIncorrectAmount.selector, 0, amount)); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, amount, bob)); } @@ -117,7 +117,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encodeWithSelector(IBridgehub.baseToken.selector), abi.encode(ETH_TOKEN_ADDRESS) ); - vm.expectRevert("ShB m.v > 0 for BH d.it 2"); + vm.expectRevert(NonEmptyMsgValue.selector); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit{value: amount}(chainId, alice, 0, abi.encode(address(token), amount, bob)); } @@ -133,8 +133,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(ETH_TOKEN_ADDRESS) ); vm.mockCall(address(token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(10)); - bytes memory message = bytes("5T"); - vm.expectRevert(message); + vm.expectRevert(abi.encodeWithSelector(DepositIncorrectAmount.selector, 0, amount)); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(address(token), amount, bob)); } @@ -146,8 +145,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encodeWithSelector(IBridgehub.baseToken.selector), abi.encode(address(token)) ); - bytes memory message = bytes("6T"); - vm.expectRevert(message); + vm.expectRevert(EmptyDeposit.selector); // solhint-disable-next-line func-named-parameters sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, 0, bob)); } @@ -156,7 +154,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { bytes32 txDataHash = keccak256(abi.encode(alice, address(token), amount)); _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); vm.prank(bridgehubAddress); - vm.expectRevert("ShB tx hap"); + vm.expectRevert(DepositExists.selector); sharedBridge.bridgehubConfirmL2Transaction(chainId, txDataHash, txHash); } @@ -167,8 +165,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(address(0)) ); vm.prank(bridgehubAddress); - bytes memory message = bytes("yn"); - vm.expectRevert(message); + vm.expectRevert(InvalidProof.selector); sharedBridge.claimFailedDeposit({ _chainId: chainId, _depositSender: alice, @@ -201,8 +198,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(true) ); - bytes memory message = bytes("y1"); - vm.expectRevert(message); + vm.expectRevert(NoFundsTransferred.selector); sharedBridge.claimFailedDeposit({ _chainId: chainId, _depositSender: alice, @@ -235,7 +231,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(true) ); - vm.expectRevert("ShB: d.it not hap"); + vm.expectRevert(DepositDoesNotExist.selector); sharedBridge.claimFailedDeposit({ _chainId: chainId, _depositSender: alice, @@ -272,7 +268,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(true) ); - vm.expectRevert("ShB n funds"); + vm.expectRevert(InsufficientChainBalance.selector); sharedBridge.claimFailedDeposit({ _chainId: chainId, _depositSender: alice, @@ -303,7 +299,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { amount ); - vm.expectRevert("ShB: legacy withdrawal"); + vm.expectRevert(WithdrawalAlreadyFinalized.selector); sharedBridge.finalizeWithdrawal({ _chainId: eraChainId, _l2BatchNumber: legacyBatchNumber, @@ -347,7 +343,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { amount ); - vm.expectRevert("Withdrawal is already finalized"); + vm.expectRevert(WithdrawalAlreadyFinalized.selector); sharedBridge.finalizeWithdrawal({ _chainId: eraChainId, _l2BatchNumber: legacyBatchNumber, @@ -380,8 +376,8 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { address(token), amount ); - vm.expectRevert("Withdrawal is already finalized 2"); + vm.expectRevert(WithdrawalAlreadyFinalized.selector); sharedBridge.finalizeWithdrawal({ _chainId: eraChainId, _l2BatchNumber: legacyBatchNumber, @@ -422,8 +418,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(true) ); - vm.expectRevert("ShB not enough funds 2"); - + vm.expectRevert(InsufficientChainBalance.selector); sharedBridge.finalizeWithdrawal({ _chainId: chainId, _l2BatchNumber: l2BatchNumber, @@ -464,8 +459,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { abi.encode(false) ); - vm.expectRevert("ShB withd w proof"); - + vm.expectRevert(InvalidProof.selector); sharedBridge.finalizeWithdrawal({ _chainId: chainId, _l2BatchNumber: l2BatchNumber, @@ -487,7 +481,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { bytes memory message = abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector); - vm.expectRevert("ShB wrong msg len"); + vm.expectRevert(abi.encodeWithSelector(L2WithdrawalMessageWrongLength.selector, message.length)); sharedBridge.finalizeWithdrawal({ _chainId: chainId, _l2BatchNumber: l2BatchNumber, @@ -510,8 +504,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { bytes memory message = abi.encodePacked(IL1ERC20Bridge.finalizeWithdrawal.selector, alice, amount); // should have more data here - vm.expectRevert("ShB wrong msg len 2"); - + vm.expectRevert(abi.encodeWithSelector(L2WithdrawalMessageWrongLength.selector, message.length)); sharedBridge.finalizeWithdrawal({ _chainId: eraChainId, _l2BatchNumber: l2BatchNumber, @@ -534,7 +527,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { // notice that the selector is wrong bytes memory message = abi.encodePacked(IMailbox.proveL2LogInclusion.selector, alice, amount); - vm.expectRevert("ShB Incorrect message function selector"); + vm.expectRevert(abi.encodeWithSelector(InvalidSelector.selector, IMailbox.proveL2LogInclusion.selector)); sharedBridge.finalizeWithdrawal({ _chainId: eraChainId, _l2BatchNumber: l2BatchNumber, @@ -553,7 +546,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { vm.prank(owner); sharedBridge.initializeChainGovernance(eraChainId, address(0)); - vm.expectRevert("ShB b. n dep"); + vm.expectRevert(abi.encodeWithSelector(L2BridgeNotSet.selector, eraChainId)); vm.prank(l1ERC20BridgeAddress); sharedBridge.depositLegacyErc20Bridge({ _prevMsgSender: alice, @@ -571,7 +564,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { uint256 l2TxGasPerPubdataByte = 100; address refundRecipient = address(0); - vm.expectRevert("ShB: WETH deposit not supported 2"); + vm.expectRevert(abi.encodeWithSelector(TokenNotSupported.selector, l1WethAddress)); vm.prank(l1ERC20BridgeAddress); sharedBridge.depositLegacyErc20Bridge({ _prevMsgSender: alice, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol index cad8482fb..0b917efca 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.24; import {StdStorage, stdStorage} from "forge-std/Test.sol"; import {Test} from "forge-std/Test.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol index adceecddb..0aee58ce7 100644 --- a/l1-contracts/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/DiamondCut/FacetCut.t.sol @@ -9,6 +9,7 @@ import {ExecutorFacet} from "contracts/state-transition/chain-deps/facets/Execut import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; +import {ReplaceFunctionFacetAddressZero, RemoveFunctionFacetAddressNotZero, FacetExists, SelectorsMustAllHaveSameFreezability, AddressHasNoCode, NonZeroAddress, ZeroAddress} from "contracts/common/L1ContractErrors.sol"; contract FacetCutTest is DiamondCutTest { MailboxFacet private mailboxFacet; @@ -88,7 +89,9 @@ contract FacetCutTest is DiamondCutTest { diamondCutTestContract.diamondCut(diamondCutData); - vm.expectRevert(abi.encodePacked("J")); + vm.expectRevert( + abi.encodeWithSelector(FacetExists.selector, Utils.getMailboxSelectors()[0], address(mailboxFacet)) + ); diamondCutTestContract.diamondCut(diamondCutData); } @@ -107,7 +110,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("G")); + vm.expectRevert(abi.encodeWithSelector(AddressHasNoCode.selector, address(0))); diamondCutTestContract.diamondCut(diamondCutData); } @@ -126,7 +129,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("L")); + vm.expectRevert(ReplaceFunctionFacetAddressZero.selector); diamondCutTestContract.diamondCut(diamondCutData); } @@ -145,7 +148,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("a1")); + vm.expectRevert(abi.encodeWithSelector(RemoveFunctionFacetAddressNotZero.selector, address(mailboxFacet))); diamondCutTestContract.diamondCut(diamondCutData); } @@ -288,7 +291,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("G")); + vm.expectRevert(abi.encodeWithSelector(AddressHasNoCode.selector, address(1))); diamondCutTestContract.diamondCut(diamondCutData1); } @@ -310,7 +313,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("K")); + vm.expectRevert(abi.encodeWithSelector(AddressHasNoCode.selector, address(1))); diamondCutTestContract.diamondCut(diamondCutData1); } @@ -341,7 +344,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("J1")); + vm.expectRevert(SelectorsMustAllHaveSameFreezability.selector); diamondCutTestContract.diamondCut(diamondCutData); } @@ -377,7 +380,7 @@ contract FacetCutTest is DiamondCutTest { initCalldata: bytes("") }); - vm.expectRevert(abi.encodePacked("J1")); + vm.expectRevert(SelectorsMustAllHaveSameFreezability.selector); diamondCutTestContract.diamondCut(diamondCutData); } diff --git a/l1-contracts/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol index cbcb012a5..94996c5e1 100644 --- a/l1-contracts/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/DiamondCut/Initialization.t.sol @@ -6,6 +6,7 @@ import {RevertFallback} from "contracts/dev-contracts/RevertFallback.sol"; import {ReturnSomething} from "contracts/dev-contracts/ReturnSomething.sol"; import {DiamondCutTestContract} from "contracts/dev-contracts/test/DiamondCutTestContract.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; +import {DelegateCallFailed, BadReturnData, MalformedCalldata, NonEmptyCalldata} from "contracts/common/L1ContractErrors.sol"; contract InitializationTest is DiamondCutTest { address private revertFallbackAddress; @@ -27,8 +28,8 @@ contract InitializationTest is DiamondCutTest { initAddress: revertFallbackAddress, initCalldata: bytes("") }); - - vm.expectRevert(abi.encodePacked("I")); + bytes memory emptyBytes; + vm.expectRevert(abi.encodeWithSelector(DelegateCallFailed.selector, emptyBytes)); diamondCutTestContract.diamondCut(diamondCutData); } @@ -40,8 +41,8 @@ contract InitializationTest is DiamondCutTest { initAddress: signerAddress, initCalldata: bytes("") }); - - vm.expectRevert(abi.encodePacked("lp")); + bytes memory emptyBytes; + vm.expectRevert(abi.encodeWithSelector(DelegateCallFailed.selector, emptyBytes)); diamondCutTestContract.diamondCut(diamondCutData); } @@ -54,7 +55,7 @@ contract InitializationTest is DiamondCutTest { initCalldata: bytes("0x11") }); - vm.expectRevert(abi.encodePacked("H")); + vm.expectRevert(NonEmptyCalldata.selector); diamondCutTestContract.diamondCut(diamondCutData); } @@ -66,8 +67,8 @@ contract InitializationTest is DiamondCutTest { initAddress: returnSomethingAddress, initCalldata: bytes("") }); - - vm.expectRevert(abi.encodePacked("lp1")); + bytes memory returnData = hex"0000000000000000000000000000000000000000000000000000000000000000"; + vm.expectRevert(abi.encodeWithSelector(DelegateCallFailed.selector, returnData)); diamondCutTestContract.diamondCut(diamondCutData); } } diff --git a/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol index 41c07d9a2..7a4badf5f 100644 --- a/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol @@ -14,6 +14,7 @@ import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {Utils} from "../Utils/Utils.sol"; import {InitializeData} from "contracts/state-transition/chain-deps/DiamondInit.sol"; import {DummyStateTransitionManager} from "contracts/dev-contracts/test/DummyStateTransitionManager.sol"; +import {DiamondAlreadyFrozen, Unauthorized, DiamondFreezeIncorrectState, DiamondNotFrozen} from "contracts/common/L1ContractErrors.sol"; contract UpgradeLogicTest is DiamondCutTest { DiamondProxy private diamondProxy; @@ -118,8 +119,7 @@ contract UpgradeLogicTest is DiamondCutTest { function test_RevertWhen_EmergencyFreezeWhenUnauthorizedGovernor() public { vm.startPrank(randomSigner); - - vm.expectRevert(abi.encodePacked("Hyperchain: not state transition manager")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); proxyAsAdmin.freezeDiamond(); } @@ -128,14 +128,14 @@ contract UpgradeLogicTest is DiamondCutTest { proxyAsAdmin.freezeDiamond(); - vm.expectRevert(abi.encodePacked("a9")); + vm.expectRevert(DiamondAlreadyFrozen.selector); proxyAsAdmin.freezeDiamond(); } function test_RevertWhen_UnfreezingWhenNotFrozen() public { vm.startPrank(stateTransitionManager); - vm.expectRevert(abi.encodePacked("a7")); + vm.expectRevert(DiamondNotFrozen.selector); proxyAsAdmin.unfreezeDiamond(); } diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/Authorization.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Authorization.t.sol index 498fb21a2..8cc19a11d 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/Authorization.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/Authorization.t.sol @@ -6,6 +6,7 @@ import {Utils} from "../Utils/Utils.sol"; import {ExecutorTest} from "./_Executor_Shared.t.sol"; import {IExecutor} from "contracts/state-transition/chain-interfaces/IExecutor.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract AuthorizationTest is ExecutorTest { IExecutor.StoredBatchInfo private storedBatchInfo; @@ -43,7 +44,7 @@ contract AuthorizationTest is ExecutorTest { vm.prank(randomSigner); - vm.expectRevert(bytes.concat("Hyperchain: not validator")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); executor.commitBatches(storedBatchInfo, commitBatchInfoArray); } @@ -53,7 +54,7 @@ contract AuthorizationTest is ExecutorTest { vm.prank(owner); - vm.expectRevert(bytes.concat("Hyperchain: not validator")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, owner)); executor.proveBatches(storedBatchInfo, storedBatchInfoArray, proofInput); } @@ -63,7 +64,7 @@ contract AuthorizationTest is ExecutorTest { vm.prank(randomSigner); - vm.expectRevert(bytes.concat("Hyperchain: not validator")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); executor.executeBatches(storedBatchInfoArray); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/Committing.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Committing.t.sol index ce3e5947c..eb64051c5 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/Committing.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/Committing.t.sol @@ -9,6 +9,7 @@ import {IExecutor, MAX_NUMBER_OF_BLOBS} from "contracts/state-transition/chain-i import {SystemLogKey} from "contracts/state-transition/chain-interfaces/IExecutor.sol"; import {POINT_EVALUATION_PRECOMPILE_ADDR} from "contracts/common/Config.sol"; import {L2_PUBDATA_CHUNK_PUBLISHER_ADDR} from "contracts/common/L2ContractAddresses.sol"; +import {TimeNotReached, BatchNumberMismatch, PubdataCommitmentsTooBig, InvalidPubdataCommitmentsSize, PubdataCommitmentsEmpty, L2TimestampTooBig, EmptyBlobVersionHash, CanOnlyProcessOneBatch, TimestampError, LogAlreadyProcessed, InvalidLogSender, UnexpectedSystemLog, HashMismatch, BatchHashMismatch, ValueMismatch, MissingSystemLogs, InvalidPubdataLength, NonEmptyBlobVersionHash, BlobHashCommitmentError} from "contracts/common/L1ContractErrors.sol"; contract CommittingTest is ExecutorTest { function test_RevertWhen_CommittingWithWrongLastCommittedBatchData() public { @@ -20,7 +21,13 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("i")); + vm.expectRevert( + abi.encodeWithSelector( + BatchHashMismatch.selector, + keccak256(abi.encode(genesisStoredBatchInfo)), + keccak256(abi.encode(wrongGenesisStoredBatchInfo)) + ) + ); executor.commitBatches(wrongGenesisStoredBatchInfo, newCommitBatchInfoArray); } @@ -33,7 +40,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("f")); + vm.expectRevert(abi.encodeWithSelector(BatchNumberMismatch.selector, uint256(1), uint256(2))); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -56,7 +63,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("tb")); + vm.expectRevert(TimestampError.selector); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -79,7 +86,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("h1")); + vm.expectRevert(abi.encodeWithSelector(TimeNotReached.selector, 1, 2)); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -102,7 +109,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("h2")); + vm.expectRevert(abi.encodeWithSelector(L2TimestampTooBig.selector)); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -124,7 +131,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("l")); + vm.expectRevert(abi.encodeWithSelector(HashMismatch.selector, wrongPreviousBatchHash, bytes32(0))); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -140,7 +147,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("b7")); + vm.expectRevert(abi.encodeWithSelector(MissingSystemLogs.selector, 8191, 8183)); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -166,7 +173,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("kp")); + vm.expectRevert(abi.encodeWithSelector(LogAlreadyProcessed.selector, 3)); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -188,7 +195,13 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("sc")); + vm.expectRevert( + abi.encodeWithSelector( + InvalidLogSender.selector, + address(0), + uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY) + ) + ); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -210,7 +223,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("t")); + vm.expectRevert(abi.encodeWithSelector(HashMismatch.selector, wrongChainedPriorityHash, keccak256(""))); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -232,7 +245,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("ta")); + vm.expectRevert(abi.encodeWithSelector(ValueMismatch.selector, uint256(bytes32(bytes1(0x01))), uint256(2))); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -245,14 +258,14 @@ contract CommittingTest is ExecutorTest { ); IExecutor.CommitBatchInfo memory wrongNewCommitBatchInfo = newCommitBatchInfo; - wrongNewCommitBatchInfo.systemLogs = abi.encodePacked(bytes4(0x00000008), wrongL2Logs); + wrongNewCommitBatchInfo.systemLogs = abi.encodePacked(wrongL2Logs); IExecutor.CommitBatchInfo[] memory wrongNewCommitBatchInfoArray = new IExecutor.CommitBatchInfo[](1); wrongNewCommitBatchInfoArray[0] = wrongNewCommitBatchInfo; vm.prank(validator); - vm.expectRevert(bytes.concat("ul")); + vm.expectRevert(abi.encodeWithSelector(UnexpectedSystemLog.selector, uint256(119))); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } @@ -290,7 +303,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(errors[i]); + vm.expectRevert(abi.encodeWithSelector(InvalidLogSender.selector, wrongAddress, i)); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } } @@ -308,7 +321,8 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("b7")); + uint256 allLogsProcessed = uint256(8191); + vm.expectRevert(abi.encodeWithSelector(MissingSystemLogs.selector, 8191, allLogsProcessed ^ (1 << i))); executor.commitBatches(genesisStoredBatchInfo, wrongNewCommitBatchInfoArray); } } @@ -506,7 +520,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("e4")); + vm.expectRevert(abi.encodeWithSelector(CanOnlyProcessOneBatch.selector)); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); } @@ -530,7 +544,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("pl")); + vm.expectRevert(PubdataCommitmentsEmpty.selector); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); } @@ -555,7 +569,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("bs")); + vm.expectRevert(InvalidPubdataCommitmentsSize.selector); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); } @@ -580,7 +594,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("bd")); + vm.expectRevert(PubdataCommitmentsTooBig.selector); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); } @@ -624,7 +638,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("lh")); + vm.expectRevert(abi.encodeWithSelector(NonEmptyBlobVersionHash.selector, uint256(1))); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); vm.clearMockedCalls(); @@ -661,7 +675,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("vh")); + vm.expectRevert(abi.encodeWithSelector(EmptyBlobVersionHash.selector, 0)); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); vm.clearMockedCalls(); @@ -706,7 +720,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("lh")); + vm.expectRevert(abi.encodeWithSelector(NonEmptyBlobVersionHash.selector, uint256(1))); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); vm.clearMockedCalls(); @@ -769,7 +783,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("bh")); + vm.expectRevert(abi.encodeWithSelector(BlobHashCommitmentError.selector, uint256(1), true, false)); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); } @@ -819,7 +833,7 @@ contract CommittingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes("bh")); + vm.expectRevert(abi.encodeWithSelector(BlobHashCommitmentError.selector, uint256(1), false, true)); executor.commitBatches(genesisStoredBatchInfo, correctCommitBatchInfoArray); vm.clearMockedCalls(); diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/Executing.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Executing.t.sol index 3360150d5..288febf94 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/Executing.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/Executing.t.sol @@ -9,6 +9,7 @@ import {ExecutorTest} from "./_Executor_Shared.t.sol"; import {L2_BOOTLOADER_ADDRESS} from "contracts/common/L2ContractAddresses.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER, REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; import {IExecutor, SystemLogKey} from "contracts/state-transition/chain-interfaces/IExecutor.sol"; +import {PriorityOperationsRollingHashMismatch, BatchHashMismatch, NonSequentialBatch, CantExecuteUnprovenBatches, QueueIsEmpty, TxHashMismatch} from "contracts/common/L1ContractErrors.sol"; contract ExecutingTest is ExecutorTest { function setUp() public { @@ -62,7 +63,7 @@ contract ExecutingTest is ExecutorTest { storedBatchInfoArray[0] = wrongNewStoredBatchInfo; vm.prank(validator); - vm.expectRevert(bytes.concat("k")); + vm.expectRevert(NonSequentialBatch.selector); executor.executeBatches(storedBatchInfoArray); } @@ -74,7 +75,13 @@ contract ExecutingTest is ExecutorTest { storedBatchInfoArray[0] = wrongNewStoredBatchInfo; vm.prank(validator); - vm.expectRevert(bytes.concat("exe10")); + vm.expectRevert( + abi.encodeWithSelector( + BatchHashMismatch.selector, + keccak256(abi.encode(newStoredBatchInfo)), + keccak256(abi.encode(wrongNewStoredBatchInfo)) + ) + ); executor.executeBatches(storedBatchInfoArray); } @@ -86,7 +93,7 @@ contract ExecutingTest is ExecutorTest { storedBatchInfoArray[0] = newStoredBatchInfo; vm.prank(validator); - vm.expectRevert(bytes.concat("n")); + vm.expectRevert(CantExecuteUnprovenBatches.selector); executor.executeBatches(storedBatchInfoArray); } @@ -143,7 +150,7 @@ contract ExecutingTest is ExecutorTest { executor.proveBatches(genesisStoredBatchInfo, correctNewStoredBatchInfoArray, proofInput); vm.prank(validator); - vm.expectRevert(bytes.concat("s")); + vm.expectRevert(QueueIsEmpty.selector); executor.executeBatches(correctNewStoredBatchInfoArray); } @@ -220,7 +227,7 @@ contract ExecutingTest is ExecutorTest { }); vm.prank(validator); - vm.expectRevert(bytes.concat("x")); + vm.expectRevert(PriorityOperationsRollingHashMismatch.selector); executor.executeBatches(correctNewStoredBatchInfoArray); } @@ -245,8 +252,12 @@ contract ExecutingTest is ExecutorTest { IExecutor.StoredBatchInfo memory genesisBlock = genesisStoredBatchInfo; genesisBlock.batchHash = wrongPreviousBatchHash; + bytes32 storedBatchHash = getters.storedBlockHash(1); + vm.prank(validator); - vm.expectRevert(bytes.concat("i")); + vm.expectRevert( + abi.encodeWithSelector(BatchHashMismatch.selector, storedBatchHash, keccak256(abi.encode(genesisBlock))) + ); executor.commitBatches(genesisBlock, correctNewCommitBatchInfoArray); } diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/Proving.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Proving.t.sol index 184de78e2..92f1878f8 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/Proving.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/Proving.t.sol @@ -8,6 +8,7 @@ import {ExecutorTest} from "./_Executor_Shared.t.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER} from "contracts/common/Config.sol"; import {IExecutor, SystemLogKey} from "contracts/state-transition/chain-interfaces/IExecutor.sol"; +import {VerifiedBatchesExceedsCommittedBatches, BatchHashMismatch} from "contracts/common/L1ContractErrors.sol"; contract ProvingTest is ExecutorTest { function setUp() public { @@ -56,7 +57,13 @@ contract ProvingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("t1")); + vm.expectRevert( + abi.encodeWithSelector( + BatchHashMismatch.selector, + keccak256(abi.encode(genesisStoredBatchInfo)), + keccak256(abi.encode(wrongPreviousStoredBatchInfo)) + ) + ); executor.proveBatches(wrongPreviousStoredBatchInfo, storedBatchInfoArray, proofInput); } @@ -69,7 +76,13 @@ contract ProvingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("o1")); + vm.expectRevert( + abi.encodeWithSelector( + BatchHashMismatch.selector, + keccak256(abi.encode(newStoredBatchInfo)), + keccak256(abi.encode(wrongNewStoredBatchInfo)) + ) + ); executor.proveBatches(genesisStoredBatchInfo, storedBatchInfoArray, proofInput); } @@ -82,7 +95,7 @@ contract ProvingTest is ExecutorTest { vm.prank(validator); - vm.expectRevert(bytes.concat("q")); + vm.expectRevert(VerifiedBatchesExceedsCommittedBatches.selector); executor.proveBatches(genesisStoredBatchInfo, storedBatchInfoArray, proofInput); } diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/Reverting.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/Reverting.t.sol index 9419c9dad..c6e3ea777 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/Reverting.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/Reverting.t.sol @@ -8,6 +8,7 @@ import {ExecutorTest} from "./_Executor_Shared.t.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER} from "contracts/common/Config.sol"; import {IExecutor, SystemLogKey} from "contracts/state-transition/chain-interfaces/IExecutor.sol"; +import {RevertedBatchNotAfterNewLastBatch} from "contracts/common/L1ContractErrors.sol"; contract RevertingTest is ExecutorTest { function setUp() public { @@ -55,7 +56,7 @@ contract RevertingTest is ExecutorTest { function test_RevertWhen_RevertingMoreBatchesThanAlreadyCommitted() public { vm.prank(validator); - vm.expectRevert(bytes.concat("v1")); + vm.expectRevert(RevertedBatchNotAfterNewLastBatch.selector); executor.revertBatches(10); } diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol index b96602f63..d81e9cc30 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol @@ -67,7 +67,7 @@ contract ExecutorTest is Test { } function getGettersSelectors() public view returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](28); + bytes4[] memory selectors = new bytes4[](29); selectors[0] = getters.getVerifier.selector; selectors[1] = getters.getAdmin.selector; selectors[2] = getters.getPendingAdmin.selector; @@ -96,6 +96,7 @@ contract ExecutorTest is Test { selectors[25] = getters.getTotalBatchesCommitted.selector; selectors[26] = getters.getTotalBatchesVerified.selector; selectors[27] = getters.getTotalBatchesExecuted.selector; + selectors[28] = getters.storedBlockHash.selector; return selectors; } diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol index 540870032..5cc75bf06 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {GovernanceTest} from "./_Governance_Shared.t.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract Authorization is GovernanceTest { function test_RevertWhen_SchedulingByUnauthorisedAddress() public { @@ -33,21 +34,21 @@ contract Authorization is GovernanceTest { function test_RevertWhen_ExecutingByUnauthorisedAddress() public { vm.prank(randomSigner); - vm.expectRevert("Only the owner and security council are allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); IGovernance.Operation memory op = operationWithOneCallZeroSaltAndPredecessor(address(eventOnFallback), 0, ""); governance.execute(op); } function test_RevertWhen_ExecutingInstantByUnauthorisedAddress() public { vm.prank(randomSigner); - vm.expectRevert("Only security council is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); IGovernance.Operation memory op = operationWithOneCallZeroSaltAndPredecessor(address(eventOnFallback), 0, ""); governance.executeInstant(op); } function test_RevertWhen_ExecutingInstantByOwner() public { vm.prank(owner); - vm.expectRevert("Only security council is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, owner)); IGovernance.Operation memory op = operationWithOneCallZeroSaltAndPredecessor(address(eventOnFallback), 0, ""); governance.executeInstant(op); } @@ -60,37 +61,37 @@ contract Authorization is GovernanceTest { function test_RevertWhen_UpdateDelayByUnauthorisedAddress() public { vm.prank(randomSigner); - vm.expectRevert("Only governance contract itself is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); governance.updateDelay(0); } function test_RevertWhen_UpdateDelayByOwner() public { vm.prank(owner); - vm.expectRevert("Only governance contract itself is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, owner)); governance.updateDelay(0); } function test_RevertWhen_UpdateDelayBySecurityCouncil() public { vm.prank(securityCouncil); - vm.expectRevert("Only governance contract itself is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, securityCouncil)); governance.updateDelay(0); } function test_RevertWhen_UpdateSecurityCouncilByUnauthorisedAddress() public { vm.prank(randomSigner); - vm.expectRevert("Only governance contract itself is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomSigner)); governance.updateSecurityCouncil(address(0)); } function test_RevertWhen_UpdateSecurityCouncilByOwner() public { vm.prank(owner); - vm.expectRevert("Only governance contract itself is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, owner)); governance.updateSecurityCouncil(address(0)); } function test_RevertWhen_UpdateSecurityCouncilBySecurityCouncil() public { vm.prank(securityCouncil); - vm.expectRevert("Only governance contract itself is allowed to call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, securityCouncil)); governance.updateSecurityCouncil(address(0)); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol index 160cee2f6..9a1e5eeb2 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol @@ -7,6 +7,7 @@ import {Utils} from "../Utils/Utils.sol"; import {GovernanceTest} from "./_Governance_Shared.t.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {OperationMustBeReady, OperationMustBePending, OperationExists, PreviousOperationNotExecuted, InvalidDelay} from "contracts/common/L1ContractErrors.sol"; contract ExecutingTest is GovernanceTest { using stdStorage for StdStorage; @@ -51,7 +52,7 @@ contract ExecutingTest is GovernanceTest { vm.startPrank(owner); IGovernance.Operation memory op = operationWithOneCallZeroSaltAndPredecessor(address(eventOnFallback), 0, ""); governance.scheduleTransparent(op, 10000); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(op); } @@ -65,7 +66,7 @@ contract ExecutingTest is GovernanceTest { governance.scheduleTransparent(validOp, 0); IGovernance.Operation memory invalidOp = operationWithOneCallZeroSaltAndPredecessor(address(0), 0, ""); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(invalidOp); } @@ -83,7 +84,7 @@ contract ExecutingTest is GovernanceTest { 1, "" ); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(invalidOp); } @@ -101,7 +102,7 @@ contract ExecutingTest is GovernanceTest { 0, "00" ); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(invalidOp); } @@ -133,7 +134,7 @@ contract ExecutingTest is GovernanceTest { invalidOp.predecessor = governance.hashOperation(executedOp); // Failed to execute operation that wasn't scheduled - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(invalidOp); } @@ -152,7 +153,7 @@ contract ExecutingTest is GovernanceTest { "" ); invalidOp.salt = Utils.randomBytes32("wrongSalt"); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(invalidOp); } @@ -166,7 +167,7 @@ contract ExecutingTest is GovernanceTest { ); invalidOp.predecessor = Utils.randomBytes32("randomPredecessor"); governance.scheduleTransparent(invalidOp, 0); - vm.expectRevert("Predecessor operation not completed"); + vm.expectRevert(PreviousOperationNotExecuted.selector); governance.execute(invalidOp); } @@ -181,7 +182,7 @@ contract ExecutingTest is GovernanceTest { governance.scheduleTransparent(op, 0); executeOpAndCheck(op); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(op); } @@ -193,7 +194,7 @@ contract ExecutingTest is GovernanceTest { 0, "1122" ); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(op); } @@ -205,7 +206,7 @@ contract ExecutingTest is GovernanceTest { 0, "1122" ); - vm.expectRevert("Operation must be pending before execution"); + vm.expectRevert(OperationMustBePending.selector); governance.executeInstant(op); } @@ -219,7 +220,7 @@ contract ExecutingTest is GovernanceTest { ); governance.scheduleTransparent(op, 0); governance.cancel(governance.hashOperation(op)); - vm.expectRevert("Operation must be ready before execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(op); } @@ -247,7 +248,7 @@ contract ExecutingTest is GovernanceTest { ); governance.scheduleTransparent(op, 0); executeOpAndCheck(op); - vm.expectRevert("Operation with this proposal id already exists"); + vm.expectRevert(OperationExists.selector); governance.scheduleTransparent(op, 0); } @@ -270,7 +271,7 @@ contract ExecutingTest is GovernanceTest { function test_RevertWhen_CancelNonExistingOperation() public { vm.startPrank(owner); - vm.expectRevert("Operation must be pending"); + vm.expectRevert(OperationMustBePending.selector); governance.cancel(bytes32(0)); } @@ -279,7 +280,7 @@ contract ExecutingTest is GovernanceTest { stdstore.target(address(governance)).sig(governance.minDelay.selector).checked_write(1000); IGovernance.Operation memory op = operationWithOneCallZeroSaltAndPredecessor(address(revertFallback), 0, ""); - vm.expectRevert("Proposed delay is less than minimum delay"); + vm.expectRevert(InvalidDelay.selector); governance.scheduleTransparent(op, 0); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol b/l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol index 1076d1015..1f6beb10a 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol @@ -9,6 +9,7 @@ import {GovernanceTest} from "./_Governance_Shared.t.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; import {ReenterGovernance} from "contracts/dev-contracts/test/ReenterGovernance.sol"; +import {OperationMustBeReady, OperationMustBePending} from "contracts/common/L1ContractErrors.sol"; contract ReentrancyTest is GovernanceTest { using stdStorage for StdStorage; @@ -88,7 +89,7 @@ contract ReentrancyTest is GovernanceTest { vm.startPrank(address(reenterGovernance)); governance.scheduleTransparent(op, 0); - vm.expectRevert("Operation must be ready after execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(op); } @@ -108,7 +109,7 @@ contract ReentrancyTest is GovernanceTest { vm.startPrank(address(reenterGovernance)); governance.scheduleTransparent(op, 0); - vm.expectRevert("Operation must be pending after execution"); + vm.expectRevert(OperationMustBePending.selector); governance.executeInstant(op); } @@ -125,7 +126,7 @@ contract ReentrancyTest is GovernanceTest { vm.startPrank(address(reenterGovernance)); governance.scheduleTransparent(op, 0); - vm.expectRevert("Operation must be ready after execution"); + vm.expectRevert(OperationMustBeReady.selector); governance.execute(op); } @@ -145,7 +146,7 @@ contract ReentrancyTest is GovernanceTest { vm.startPrank(address(reenterGovernance)); governance.scheduleTransparent(op, 0); - vm.expectRevert("Operation must be pending after execution"); + vm.expectRevert(OperationMustBePending.selector); governance.executeInstant(op); } } diff --git a/l1-contracts/test/foundry/unit/concrete/ValidatorTimelock/ValidatorTimelock.t.sol b/l1-contracts/test/foundry/unit/concrete/ValidatorTimelock/ValidatorTimelock.t.sol index dacc45160..a2217cc13 100644 --- a/l1-contracts/test/foundry/unit/concrete/ValidatorTimelock/ValidatorTimelock.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/ValidatorTimelock/ValidatorTimelock.t.sol @@ -6,6 +6,7 @@ import {Utils} from "../Utils/Utils.sol"; import {ValidatorTimelock, IExecutor} from "contracts/state-transition/ValidatorTimelock.sol"; import {DummyStateTransitionManagerForValidatorTimelock} from "contracts/dev-contracts/test/DummyStateTransitionManagerForValidatorTimelock.sol"; import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; +import {Unauthorized, TimeNotReached} from "contracts/common/L1ContractErrors.sol"; contract ValidatorTimelockTest is Test { /// @notice A new validator has been added. @@ -270,7 +271,7 @@ contract ValidatorTimelockTest is Test { function test_RevertWhen_addValidatorNotAdmin() public { assert(validator.validators(chainId, bob) == false); - vm.expectRevert("ValidatorTimelock: only chain admin"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, address(this))); validator.addValidator(chainId, bob); assert(validator.validators(chainId, bob) == false); @@ -279,7 +280,7 @@ contract ValidatorTimelockTest is Test { function test_RevertWhen_removeValidatorNotAdmin() public { assert(validator.validators(chainId, alice) == true); - vm.expectRevert("ValidatorTimelock: only chain admin"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, address(this))); validator.removeValidator(chainId, alice); assert(validator.validators(chainId, alice) == true); @@ -309,7 +310,7 @@ contract ValidatorTimelockTest is Test { batchesToCommit[0] = batchToCommit; vm.prank(bob); - vm.expectRevert(bytes("ValidatorTimelock: only validator")); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, bob)); validator.commitBatches(storedBatch, batchesToCommit); } @@ -319,12 +320,12 @@ contract ValidatorTimelockTest is Test { } function test_RevertWhen_revertBatchesNotValidator() public { - vm.expectRevert("ValidatorTimelock: only validator"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, address(this))); validator.revertBatches(lastBatchNumber); } function test_RevertWhen_revertBatchesSharedBridgeNotValidator() public { - vm.expectRevert("ValidatorTimelock: only validator"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, address(this))); validator.revertBatchesSharedBridge(chainId, lastBatchNumber); } @@ -336,7 +337,7 @@ contract ValidatorTimelockTest is Test { IExecutor.StoredBatchInfo[] memory batchesToProve = new IExecutor.StoredBatchInfo[](1); batchesToProve[0] = batchToProve; - vm.expectRevert("ValidatorTimelock: only validator"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, address(this))); validator.proveBatches(prevBatch, batchesToProve, proof); } @@ -349,7 +350,7 @@ contract ValidatorTimelockTest is Test { batchesToProve[0] = batchToProve; vm.prank(bob); - vm.expectRevert("ValidatorTimelock: only validator"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, bob)); validator.proveBatchesSharedBridge(chainId, prevBatch, batchesToProve, proof); } @@ -360,7 +361,7 @@ contract ValidatorTimelockTest is Test { storedBatches[0] = storedBatch; vm.prank(bob); - vm.expectRevert("ValidatorTimelock: only validator"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, bob)); validator.executeBatches(storedBatches); } @@ -371,7 +372,7 @@ contract ValidatorTimelockTest is Test { storedBatches[0] = storedBatch; vm.prank(bob); - vm.expectRevert("ValidatorTimelock: only validator"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, bob)); validator.executeBatchesSharedBridge(chainId, storedBatches); } @@ -400,7 +401,9 @@ contract ValidatorTimelockTest is Test { vm.prank(dan); vm.warp(timestamp + executionDelay - 1); - vm.expectRevert(bytes("5c")); + vm.expectRevert( + abi.encodeWithSelector(TimeNotReached.selector, timestamp + executionDelay, timestamp + executionDelay - 1) + ); validator.executeBatches(storedBatches); } @@ -429,7 +432,9 @@ contract ValidatorTimelockTest is Test { vm.prank(alice); vm.warp(timestamp + executionDelay - 1); - vm.expectRevert(bytes("5c")); + vm.expectRevert( + abi.encodeWithSelector(TimeNotReached.selector, timestamp + executionDelay, timestamp + executionDelay - 1) + ); validator.executeBatchesSharedBridge(chainId, storedBatches); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol index dc66d38b9..ba69c6bd7 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol @@ -3,21 +3,27 @@ pragma solidity 0.8.24; import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; +import {Unauthorized, HashMismatch} from "contracts/common/L1ContractErrors.sol"; contract createNewChainTest is StateTransitionManagerTest { function test_RevertWhen_InitialDiamondCutHashMismatch() public { Diamond.DiamondCutData memory initialDiamondCutData = getDiamondCutData(sharedBridge); - - vm.expectRevert(bytes("STM: initial cutHash mismatch")); - + Diamond.DiamondCutData memory correctDiamondCutData = getDiamondCutData(address(diamondInit)); + + vm.expectRevert( + abi.encodeWithSelector( + HashMismatch.selector, + keccak256(abi.encode(correctDiamondCutData)), + keccak256(abi.encode(initialDiamondCutData)) + ) + ); createNewChain(initialDiamondCutData); } function test_RevertWhen_CalledNotByBridgehub() public { Diamond.DiamondCutData memory initialDiamondCutData = getDiamondCutData(diamondInit); - vm.expectRevert(bytes("STM: only bridgehub")); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, governor)); chainContractAddress.createNewChain({ _chainId: chainId, _baseToken: baseToken, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol index 590d5d4ab..1bf8c8a40 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.24; import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; +import {IAdmin} from "contracts/state-transition/chain-interfaces/IAdmin.sol"; +import {FacetIsFrozen} from "contracts/common/L1ContractErrors.sol"; contract freezeChainTest is StateTransitionManagerTest { function test_FreezingChain() public { @@ -19,11 +21,11 @@ contract freezeChainTest is StateTransitionManagerTest { chainContractAddress.freezeChain(block.chainid); // Repeated call should revert - vm.expectRevert(bytes.concat("q1")); // storage frozen + vm.expectRevert(bytes("q1")); // storage frozen chainContractAddress.freezeChain(block.chainid); // Call fails as storage is frozen - vm.expectRevert(bytes.concat("q1")); + vm.expectRevert(bytes("q1")); isChainFrozen = gettersFacet.isDiamondStorageFrozen(); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol index 8fae0aa1e..d8fb6e187 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol"; import {StateTransitionManagerInitializeData, ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; +import {ZeroAddress} from "contracts/common/L1ContractErrors.sol"; contract initializingSTMOwnerZeroTest is StateTransitionManagerTest { function test_InitializingSTMWithGovernorZeroShouldRevert() public { @@ -23,7 +24,7 @@ contract initializingSTMOwnerZeroTest is StateTransitionManagerTest { protocolVersion: 0 }); - vm.expectRevert(bytes("STM: owner zero")); + vm.expectRevert(ZeroAddress.selector); new TransparentUpgradeableProxy( address(stateTransitionManager), admin, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol index 1cd596436..999336642 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; +pragma solidity ^0.8.21; import {Test} from "forge-std/Test.sol"; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {Utils} from "foundry-test/unit/concrete/Utils/Utils.sol"; import {UtilsFacet} from "foundry-test/unit/concrete/Utils/UtilsFacet.sol"; @@ -18,6 +18,7 @@ import {InitializeDataNewChain} from "contracts/state-transition/chain-interface import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol"; import {StateTransitionManagerInitializeData, ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; +import {ZeroAddress} from "contracts/common/L1ContractErrors.sol"; contract StateTransitionManagerTest is Test { StateTransitionManager internal stateTransitionManager; @@ -93,7 +94,7 @@ contract StateTransitionManagerTest is Test { protocolVersion: 0 }); - vm.expectRevert(bytes.concat("STM: owner zero")); + vm.expectRevert(ZeroAddress.selector); new TransparentUpgradeableProxy( address(stateTransitionManager), admin, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol index 3c2b01dd5..205752a9f 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol @@ -11,6 +11,7 @@ import {DiamondProxy} from "contracts/state-transition/chain-deps/DiamondProxy.s import {InitializeData} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; import {IVerifier} from "contracts/state-transition/chain-interfaces/IVerifier.sol"; import {MAX_GAS_PER_TRANSACTION} from "contracts/common/Config.sol"; +import {MalformedCalldata, ZeroAddress, TooMuchGas} from "contracts/common/L1ContractErrors.sol"; contract InitializeTest is DiamondInitTest { function test_revertWhen_verifierIsZeroAddress() public { @@ -23,7 +24,7 @@ contract InitializeTest is DiamondInitTest { initCalldata: abi.encodeWithSelector(DiamondInit.initialize.selector, initializeData) }); - vm.expectRevert(bytes.concat("vt")); + vm.expectRevert(ZeroAddress.selector); new DiamondProxy(block.chainid, diamondCutData); } @@ -37,7 +38,7 @@ contract InitializeTest is DiamondInitTest { initCalldata: abi.encodeWithSelector(DiamondInit.initialize.selector, initializeData) }); - vm.expectRevert(bytes.concat("vy")); + vm.expectRevert(ZeroAddress.selector); new DiamondProxy(block.chainid, diamondCutData); } @@ -51,7 +52,7 @@ contract InitializeTest is DiamondInitTest { initCalldata: abi.encodeWithSelector(DiamondInit.initialize.selector, initializeData) }); - vm.expectRevert(bytes.concat("hc")); + vm.expectRevert(ZeroAddress.selector); new DiamondProxy(block.chainid, diamondCutData); } @@ -65,7 +66,7 @@ contract InitializeTest is DiamondInitTest { initCalldata: abi.encodeWithSelector(DiamondInit.initialize.selector, initializeData) }); - vm.expectRevert(bytes.concat("vu")); + vm.expectRevert(TooMuchGas.selector); new DiamondProxy(block.chainid, diamondCutData); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondProxy/DiamondProxy.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondProxy/DiamondProxy.t.sol index ba1ece9db..4637faabd 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondProxy/DiamondProxy.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondProxy/DiamondProxy.t.sol @@ -12,6 +12,7 @@ import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {DiamondProxy} from "contracts/state-transition/chain-deps/DiamondProxy.sol"; import {ZkSyncHyperchainBase} from "contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol"; import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; +import {FacetIsFrozen, ValueMismatch, InvalidSelector} from "contracts/common/L1ContractErrors.sol"; contract TestFacet is ZkSyncHyperchainBase { function func() public pure returns (bool) { @@ -59,7 +60,7 @@ contract DiamondProxyTest is Test { initCalldata: abi.encodeWithSelector(DiamondInit.initialize.selector, initializeData) }); - vm.expectRevert(abi.encodePacked("pr")); + vm.expectRevert(bytes("pr")); new DiamondProxy(block.chainid + 1, diamondCutData); } @@ -107,7 +108,7 @@ contract DiamondProxyTest is Test { DiamondProxy diamondProxy = new DiamondProxy(block.chainid, diamondCutData); TestFacet testFacet = TestFacet(address(diamondProxy)); - vm.expectRevert(abi.encodePacked("F")); + vm.expectRevert(bytes("F")); testFacet.func(); } @@ -126,7 +127,7 @@ contract DiamondProxyTest is Test { utilsFacet.util_setIsFrozen(true); - vm.expectRevert(abi.encodePacked("q1")); + vm.expectRevert(bytes("q1")); testFacet.func(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/AcceptAdmin.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/AcceptAdmin.t.sol index fe8c99db6..ab85ecdb0 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/AcceptAdmin.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/AcceptAdmin.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract AcceptAdminTest is AdminTest { event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin); @@ -11,9 +12,8 @@ contract AcceptAdminTest is AdminTest { function test_revertWhen_calledByNonPendingAdmin() public { address nonPendingAdmin = makeAddr("nonPendingAdmin"); - vm.expectRevert(bytes.concat("n4")); - vm.startPrank(nonPendingAdmin); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonPendingAdmin)); adminFacet.acceptAdmin(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ChangeFeeParams.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ChangeFeeParams.t.sol index 1575af870..70324aabf 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ChangeFeeParams.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ChangeFeeParams.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; +import {Unauthorized, PriorityTxPubdataExceedsMaxPubDataPerBatch} from "contracts/common/L1ContractErrors.sol"; contract ChangeFeeParamsTest is AdminTest { event NewFeeParams(FeeParams oldFeeParams, FeeParams newFeeParams); @@ -37,7 +37,7 @@ contract ChangeFeeParamsTest is AdminTest { }); vm.startPrank(nonStateTransitionManager); - vm.expectRevert(ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); adminFacet.changeFeeParams(newFeeParams); } @@ -55,7 +55,7 @@ contract ChangeFeeParamsTest is AdminTest { minimalL2GasPrice: 250_000_000 }); - vm.expectRevert(bytes.concat("n6")); + vm.expectRevert(PriorityTxPubdataExceedsMaxPubDataPerBatch.selector); vm.startPrank(stateTransitionManager); adminFacet.changeFeeParams(newFeeParams); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol index 95c6f54af..d09b6f204 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; import {Utils} from "../../../../Utils/Utils.sol"; import {VerifierParams} from "contracts/state-transition/chain-interfaces/IVerifier.sol"; @@ -23,7 +23,7 @@ contract ExecuteUpgradeTest is AdminTest { initCalldata: new bytes(0) }); - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); vm.startPrank(nonStateTransitionManager); adminFacet.executeUpgrade(diamondCutData); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol index 8e79f4fc3..77baed0ef 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract FreezeDiamondTest is AdminTest { event Freeze(); @@ -11,7 +11,7 @@ contract FreezeDiamondTest is AdminTest { function test_revertWhen_calledByNonStateTransitionManager() public { address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); vm.startPrank(nonStateTransitionManager); adminFacet.freezeDiamond(); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPendingGovernor.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPendingGovernor.t.sol index 8dbc12bbd..359e9ce8c 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPendingGovernor.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPendingGovernor.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_ADMIN} from "../Base/_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract SetPendingAdminTest is AdminTest { event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin); @@ -12,8 +12,7 @@ contract SetPendingAdminTest is AdminTest { address nonAdmin = makeAddr("nonAdmin"); address newPendingAdmin = makeAddr("newPendingAdmin"); - vm.expectRevert(ERROR_ONLY_ADMIN); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonAdmin)); vm.startPrank(nonAdmin); adminFacet.setPendingAdmin(newPendingAdmin); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPorterAvailability.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPorterAvailability.t.sol index 94e209a15..ad0708f11 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPorterAvailability.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPorterAvailability.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract SetPorterAvailabilityTest is AdminTest { event IsPorterAvailableStatusUpdate(bool isPorterAvailable); @@ -12,9 +12,8 @@ contract SetPorterAvailabilityTest is AdminTest { address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); bool isPorterAvailable = true; - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - vm.startPrank(nonStateTransitionManager); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); adminFacet.setPorterAvailability(isPorterAvailable); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPriorityTxMaxGasLimit.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPriorityTxMaxGasLimit.t.sol index 8ce9e4092..5581420fe 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPriorityTxMaxGasLimit.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetPriorityTxMaxGasLimit.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; import {MAX_GAS_PER_TRANSACTION} from "contracts/common/Config.sol"; +import {Unauthorized, TooMuchGas} from "contracts/common/L1ContractErrors.sol"; contract SetPriorityTxMaxGasLimitTest is AdminTest { event NewPriorityTxMaxGasLimit(uint256 oldPriorityTxMaxGasLimit, uint256 newPriorityTxMaxGasLimit); @@ -15,8 +15,7 @@ contract SetPriorityTxMaxGasLimitTest is AdminTest { uint256 newPriorityTxMaxGasLimit = 100; vm.startPrank(nonStateTransitionManager); - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); adminFacet.setPriorityTxMaxGasLimit(newPriorityTxMaxGasLimit); } @@ -24,9 +23,8 @@ contract SetPriorityTxMaxGasLimitTest is AdminTest { address stateTransitionManager = utilsFacet.util_getStateTransitionManager(); uint256 newPriorityTxMaxGasLimit = MAX_GAS_PER_TRANSACTION + 1; - vm.expectRevert(bytes.concat("n5")); - vm.startPrank(stateTransitionManager); + vm.expectRevert(TooMuchGas.selector); adminFacet.setPriorityTxMaxGasLimit(newPriorityTxMaxGasLimit); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetTransactionFilterer.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetTransactionFilterer.t.sol index 5a8ac9a2b..8581ec6c4 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetTransactionFilterer.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetTransactionFilterer.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract SetTransactionFiltererTest is AdminTest { event NewTransactionFilterer(address oldTransactionFilterer, address newTransactionFilterer); @@ -34,10 +35,11 @@ contract SetTransactionFiltererTest is AdminTest { } function test_revertWhen_notAdmin() public { + address nonAdmin = makeAddr("nonAdmin"); address transactionFilterer = makeAddr("transactionFilterer"); - vm.expectRevert("Hyperchain: not admin"); - vm.startPrank(makeAddr("nonAdmin")); + vm.startPrank(nonAdmin); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonAdmin)); adminFacet.setTransactionFilterer(transactionFilterer); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetValidator.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetValidator.t.sol index 3452ed132..77990a285 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetValidator.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/SetValidator.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract SetValidatorTest is AdminTest { event ValidatorStatusUpdate(address indexed validatorAddress, bool isActive); @@ -13,9 +13,8 @@ contract SetValidatorTest is AdminTest { address validator = makeAddr("validator"); bool isActive = true; - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - vm.startPrank(nonStateTransitionManager); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); adminFacet.setValidator(validator, isActive); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol index b7f1fa124..e0da9d6dc 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {Unauthorized, DiamondFreezeIncorrectState, DiamondNotFrozen} from "contracts/common/L1ContractErrors.sol"; contract UnfreezeDiamondTest is AdminTest { event Unfreeze(); @@ -11,8 +11,7 @@ contract UnfreezeDiamondTest is AdminTest { function test_revertWhen_calledByNonStateTransitionManager() public { address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); vm.startPrank(nonStateTransitionManager); adminFacet.unfreezeDiamond(); } @@ -22,7 +21,7 @@ contract UnfreezeDiamondTest is AdminTest { utilsFacet.util_setIsFrozen(false); - vm.expectRevert(bytes.concat("a7")); + vm.expectRevert(DiamondNotFrozen.selector); vm.startPrank(admin); adminFacet.unfreezeDiamond(); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UpgradeChainFromVersion.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UpgradeChainFromVersion.t.sol index 3e2155995..9e6efc1e5 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UpgradeChainFromVersion.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UpgradeChainFromVersion.t.sol @@ -3,10 +3,10 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; +import {ProtocolIdMismatch, ProtocolIdNotGreater, InvalidProtocolVersion, ValueMismatch, Unauthorized, HashMismatch} from "contracts/common/L1ContractErrors.sol"; contract UpgradeChainFromVersionTest is AdminTest { event ExecuteUpgrade(Diamond.DiamondCutData diamondCut); @@ -20,9 +20,8 @@ contract UpgradeChainFromVersionTest is AdminTest { initCalldata: new bytes(0) }); - vm.expectRevert(ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER); - vm.startPrank(nonAdminOrStateTransitionManager); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonAdminOrStateTransitionManager)); adminFacet.upgradeChainFromVersion(oldProtocolVersion, diamondCutData); } @@ -46,9 +45,10 @@ contract UpgradeChainFromVersionTest is AdminTest { abi.encode(cutHashInput) ); - vm.expectRevert("AdminFacet: cutHash mismatch"); - vm.startPrank(admin); + vm.expectRevert( + abi.encodeWithSelector(HashMismatch.selector, cutHashInput, keccak256(abi.encode(diamondCutData))) + ); adminFacet.upgradeChainFromVersion(oldProtocolVersion, diamondCutData); } @@ -73,9 +73,8 @@ contract UpgradeChainFromVersionTest is AdminTest { abi.encode(cutHashInput) ); - vm.expectRevert("AdminFacet: protocolVersion mismatch in STC when upgrading"); - vm.startPrank(admin); + vm.expectRevert(abi.encodeWithSelector(ProtocolIdMismatch.selector, uint256(2), oldProtocolVersion)); adminFacet.upgradeChainFromVersion(oldProtocolVersion, diamondCutData); } @@ -100,8 +99,7 @@ contract UpgradeChainFromVersionTest is AdminTest { abi.encode(cutHashInput) ); - vm.expectRevert("AdminFacet: protocolVersion mismatch in STC after upgrading"); - + vm.expectRevert(ProtocolIdNotGreater.selector); // solhint-disable-next-line func-named-parameters vm.expectEmit(true, true, true, true, address(adminFacet)); emit ExecuteUpgrade(diamondCutData); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyBridgehub.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyBridgehub.t.sol index c484a38bb..af92cde5f 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyBridgehub.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyBridgehub.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.24; -import {ZkSyncHyperchainBaseTest, ERROR_ONLY_BRIDGEHUB} from "./_Base_Shared.t.sol"; +import {ZkSyncHyperchainBaseTest} from "./_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract OnlyBridgehubTest is ZkSyncHyperchainBaseTest { function test_revertWhen_calledByNonBridgehub() public { address nonBridgehub = makeAddr("nonBridgehub"); - vm.expectRevert(ERROR_ONLY_BRIDGEHUB); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonBridgehub)); vm.startPrank(nonBridgehub); testBaseFacet.functionWithOnlyBridgehubModifier(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernor.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernor.t.sol index ba5199f92..44c397c85 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernor.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernor.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.24; -import {ZkSyncHyperchainBaseTest, ERROR_ONLY_ADMIN} from "./_Base_Shared.t.sol"; +import {ZkSyncHyperchainBaseTest} from "./_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract OnlyAdminTest is ZkSyncHyperchainBaseTest { function test_revertWhen_calledByNonAdmin() public { address nonAdmin = makeAddr("nonAdmin"); - vm.expectRevert(ERROR_ONLY_ADMIN); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonAdmin)); vm.startPrank(nonAdmin); testBaseFacet.functionWithOnlyAdminModifier(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernorOrStateTransitionManager.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernorOrStateTransitionManager.t.sol index da2d6fccf..2c4062d5b 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernorOrStateTransitionManager.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyGovernorOrStateTransitionManager.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.24; -import {ZkSyncHyperchainBaseTest, ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER} from "./_Base_Shared.t.sol"; +import {ZkSyncHyperchainBaseTest} from "./_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract OnlyAdminOrStateTransitionManagerTest is ZkSyncHyperchainBaseTest { function test_revertWhen_calledByNonAdmin() public { address nonAdmin = makeAddr("nonAdmin"); - vm.expectRevert(ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonAdmin)); vm.startPrank(nonAdmin); testBaseFacet.functionWithOnlyAdminOrStateTransitionManagerModifier(); } @@ -17,8 +17,7 @@ contract OnlyAdminOrStateTransitionManagerTest is ZkSyncHyperchainBaseTest { function test_revertWhen_calledByNonStateTransitionManager() public { address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); - vm.expectRevert(ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); vm.startPrank(nonStateTransitionManager); testBaseFacet.functionWithOnlyAdminOrStateTransitionManagerModifier(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyStateTransitionManager.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyStateTransitionManager.t.sol index f6aafb661..a93032c90 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyStateTransitionManager.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyStateTransitionManager.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.24; -import {ZkSyncHyperchainBaseTest, ERROR_ONLY_STATE_TRANSITION_MANAGER} from "./_Base_Shared.t.sol"; +import {ZkSyncHyperchainBaseTest} from "./_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract OnlyStateTransitionManagerTest is ZkSyncHyperchainBaseTest { function test_revertWhen_calledByNonStateTransitionManager() public { address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); - vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonStateTransitionManager)); vm.startPrank(nonStateTransitionManager); testBaseFacet.functionWithOnlyStateTransitionManagerModifier(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyValidator.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyValidator.t.sol index c834dd982..c002fec59 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyValidator.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Base/OnlyValidator.t.sol @@ -2,7 +2,8 @@ pragma solidity 0.8.24; -import {ZkSyncHyperchainBaseTest, ERROR_ONLY_VALIDATOR} from "./_Base_Shared.t.sol"; +import {ZkSyncHyperchainBaseTest} from "./_Base_Shared.t.sol"; +import {Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract OnlyValidatorTest is ZkSyncHyperchainBaseTest { function test_revertWhen_calledByNonValidator() public { @@ -10,8 +11,7 @@ contract OnlyValidatorTest is ZkSyncHyperchainBaseTest { utilsFacet.util_setValidator(nonValidator, false); - vm.expectRevert(ERROR_ONLY_VALIDATOR); - + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, nonValidator)); vm.startPrank(nonValidator); testBaseFacet.functionWithOnlyValidatorModifier(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/IsFunctionFreezable.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/IsFunctionFreezable.t.sol index 0b257db68..4af9875e2 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/IsFunctionFreezable.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/IsFunctionFreezable.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {GettersFacetTest} from "./_Getters_Shared.t.sol"; +import {InvalidSelector} from "contracts/common/L1ContractErrors.sol"; contract IsFunctionFreezableTest is GettersFacetTest { function test_revertWhen_facetAddressIzZero() public { @@ -11,8 +12,7 @@ contract IsFunctionFreezableTest is GettersFacetTest { gettersFacetWrapper.util_setFacetAddress(selector, address(0)); - vm.expectRevert(bytes.concat("g2")); - + vm.expectRevert(abi.encodeWithSelector(InvalidSelector.selector, selector)); gettersFacet.isFunctionFreezable(selector); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/PriorityQueueFrontOperation.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/PriorityQueueFrontOperation.t.sol index d17577afc..ac8ccfeaa 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/PriorityQueueFrontOperation.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/PriorityQueueFrontOperation.t.sol @@ -4,10 +4,11 @@ pragma solidity 0.8.24; import {GettersFacetTest} from "./_Getters_Shared.t.sol"; import {PriorityOperation} from "contracts/state-transition/libraries/PriorityQueue.sol"; +import {QueueIsEmpty} from "contracts/common/L1ContractErrors.sol"; contract GetPriorityQueueFrontOperationTest is GettersFacetTest { function test_revertWhen_queueIsEmpty() public { - vm.expectRevert(bytes.concat("D")); + vm.expectRevert(QueueIsEmpty.selector); gettersFacet.priorityQueueFrontOperation(); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol index 0a484d366..54ab2a135 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BaseMailboxTests.t.sol @@ -6,6 +6,7 @@ import {MailboxTest} from "./_Mailbox_Shared.t.sol"; import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; import {DummyHyperchain} from "contracts/dev-contracts/test/DummyHyperchain.sol"; +import {BaseTokenGasPriceDenominatorNotSet} from "contracts/common/L1ContractErrors.sol"; contract MailboxBaseTests is MailboxTest { function setUp() public virtual { @@ -21,7 +22,7 @@ contract MailboxBaseTests is MailboxTest { function test_RevertWhen_badDenominatorInL2TransactionBaseCost() public { utilsFacet.util_setBaseTokenGasPriceMultiplierDenominator(0); - vm.expectRevert("Mailbox: baseTokenGasPriceDenominator not set"); + vm.expectRevert(BaseTokenGasPriceDenominatorNotSet.selector); mailboxFacet.l2TransactionBaseCost(100, 10000, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol index 73ffff2bf..580da9a58 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/BridgehubRequestL2Transaction.t.sol @@ -7,6 +7,7 @@ import {BridgehubL2TransactionRequest} from "contracts/common/Messaging.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, MAX_NEW_FACTORY_DEPS} from "contracts/common/Config.sol"; import {TransactionFiltererTrue} from "contracts/dev-contracts/test/DummyTransactionFiltererTrue.sol"; import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransactionFiltererFalse.sol"; +import {TransactionNotAllowed, Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { function setUp() public virtual { @@ -58,7 +59,7 @@ contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { vm.deal(bridgehub, 100 ether); vm.prank(address(bridgehub)); - vm.expectRevert(bytes("tf")); + vm.expectRevert(TransactionNotAllowed.selector); mailboxFacet.bridgehubRequestL2Transaction(req); } @@ -68,7 +69,7 @@ contract MailboxBridgehubRequestL2TransactionTest is MailboxTest { BridgehubL2TransactionRequest memory req = getBridgehubRequestL2TransactionRequest(); vm.deal(bridgehub, 100 ether); vm.prank(address(sender)); - vm.expectRevert("Hyperchain: not bridgehub"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, sender)); mailboxFacet.bridgehubRequestL2Transaction(req); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol index 14fe3130e..e561f4e3b 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/FinalizeWithdrawal.t.sol @@ -8,6 +8,7 @@ import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; +import {OnlyEraSupported} from "contracts/common/L1ContractErrors.sol"; contract MailboxFinalizeWithdrawal is MailboxTest { bytes32[] proof; @@ -28,7 +29,7 @@ contract MailboxFinalizeWithdrawal is MailboxTest { function test_RevertWhen_notEra() public { utilsFacet.util_setChainId(eraChainId + 1); - vm.expectRevert("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + vm.expectRevert(OnlyEraSupported.selector); mailboxFacet.finalizeEthWithdrawal({ _l2BatchNumber: 0, _l2MessageIndex: 0, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol index 7fa5d8c3c..b80409234 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/ProvingL2LogsInclusion.t.sol @@ -7,6 +7,7 @@ import {L2Message, L2Log} from "contracts/common/Messaging.sol"; import "forge-std/Test.sol"; import {L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L1_GAS_PER_PUBDATA_BYTE, L2_TO_L1_LOG_SERIALIZE_SIZE} from "contracts/common/Config.sol"; import {L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_BOOTLOADER_ADDRESS} from "contracts/common/L2ContractAddresses.sol"; +import {BatchNotExecuted, HashedLogIsDefault} from "contracts/common/L1ContractErrors.sol"; import {Merkle} from "contracts/state-transition/libraries/Merkle.sol"; import {MurkyBase} from "murky/common/MurkyBase.sol"; import {MerkleTest} from "contracts/dev-contracts/test/MerkleTest.sol"; @@ -51,7 +52,7 @@ contract MailboxL2LogsProve is MailboxTest { L2Message memory message = L2Message({txNumberInBatch: 0, sender: sender, data: data}); bytes32[] memory proof = new bytes32[](0); - vm.expectRevert(bytes("xx")); + vm.expectRevert(abi.encodeWithSelector(BatchNotExecuted.selector, batchNumber + 1)); mailboxFacet.proveL2MessageInclusion({ _batchNumber: batchNumber + 1, _index: 0, @@ -221,7 +222,7 @@ contract MailboxL2LogsProve is MailboxTest { } // Prove log inclusion reverts - vm.expectRevert(bytes("tw")); + vm.expectRevert(HashedLogIsDefault.selector); mailboxFacet.proveL2LogInclusion({ _batchNumber: batchNumber, _index: secondLogIndex, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol index 2eee1eefb..76c501013 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/RequestL2Transaction.t.sol @@ -10,6 +10,7 @@ import {TransactionFiltererFalse} from "contracts/dev-contracts/test/DummyTransa import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; +import {OnlyEraSupported, TooManyFactoryDeps, MsgValueTooLow, GasPerPubdataMismatch} from "contracts/common/L1ContractErrors.sol"; contract MailboxRequestL2TransactionTest is MailboxTest { address tempAddress; @@ -35,7 +36,7 @@ contract MailboxRequestL2TransactionTest is MailboxTest { utilsFacet.util_setChainId(randomChainId); - vm.expectRevert("Mailbox: legacy interface only available for Era"); + vm.expectRevert(OnlyEraSupported.selector); mailboxFacet.requestL2Transaction({ _contractL2: tempAddress, _l2Value: 0, @@ -48,7 +49,7 @@ contract MailboxRequestL2TransactionTest is MailboxTest { } function test_RevertWhen_wrongL2GasPerPubdataByteLimit() public { - vm.expectRevert(bytes("qp")); + vm.expectRevert(GasPerPubdataMismatch.selector); mailboxFacet.requestL2Transaction({ _contractL2: tempAddress, _l2Value: 0, @@ -68,7 +69,7 @@ contract MailboxRequestL2TransactionTest is MailboxTest { uint256 l2Value = 1 ether; uint256 mintValue = baseCost + l2Value; - vm.expectRevert(bytes("mv")); + vm.expectRevert(abi.encodeWithSelector(MsgValueTooLow.selector, mintValue, mintValue - 1)); mailboxFacet.requestL2Transaction{value: mintValue - 1}({ _contractL2: tempAddress, _l2Value: l2Value, @@ -83,7 +84,7 @@ contract MailboxRequestL2TransactionTest is MailboxTest { function test_RevertWhen_factoryDepsLengthExceeded() public { tempBytesArr = new bytes[](MAX_NEW_FACTORY_DEPS + 1); - vm.expectRevert(bytes("uj")); + vm.expectRevert(TooManyFactoryDeps.selector); mailboxFacet.requestL2Transaction({ _contractL2: tempAddress, _l2Value: 0, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol index 90e5068b6..2bba6bda1 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Mailbox/TransferEthToSharedBridge.t.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.24; import {MailboxTest} from "./_Mailbox_Shared.t.sol"; import {IL1SharedBridge} from "contracts/bridge/interfaces/IL1SharedBridge.sol"; import {DummySharedBridge} from "contracts/dev-contracts/test/DummySharedBridge.sol"; +import {OnlyEraSupported, Unauthorized} from "contracts/common/L1ContractErrors.sol"; contract MailboxTransferEthToSharedBridge is MailboxTest { address baseTokenBridgeAddress; @@ -37,7 +38,7 @@ contract MailboxTransferEthToSharedBridge is MailboxTest { } function test_RevertWhen_wrongCaller() public { - vm.expectRevert("Hyperchain: Only base token bridge can call this function"); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, sender)); vm.prank(sender); mailboxFacet.transferEthToSharedBridge(); } @@ -46,7 +47,7 @@ contract MailboxTransferEthToSharedBridge is MailboxTest { vm.assume(eraChainId != randomChainId); utilsFacet.util_setChainId(randomChainId); - vm.expectRevert("Mailbox: transferEthToSharedBridge only available for Era on mailbox"); + vm.expectRevert(OnlyEraSupported.selector); mailboxFacet.transferEthToSharedBridge(); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/Merkle/Merkle.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/Merkle/Merkle.t.sol index 492d489c2..89514fc99 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/Merkle/Merkle.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/Merkle/Merkle.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {Test} from "forge-std/Test.sol"; import {MerkleTest} from "contracts/dev-contracts/test/MerkleTest.sol"; import {MerkleTreeNoSort} from "./MerkleTreeNoSort.sol"; +import {MerklePathEmpty, MerkleIndexOutOfBounds, MerklePathOutOfBounds} from "contracts/common/L1ContractErrors.sol"; contract MerkleTestTest is Test { MerkleTreeNoSort merkleTree; @@ -44,7 +45,7 @@ contract MerkleTestTest is Test { bytes32 leaf = elements[0]; bytes32[] memory proof; - vm.expectRevert(bytes("xc")); + vm.expectRevert(MerklePathEmpty.selector); merkleTest.calculateRoot(proof, 0, leaf); } @@ -52,7 +53,7 @@ contract MerkleTestTest is Test { bytes32 leaf = elements[0]; bytes32[] memory proof = merkleTree.getProof(elements, 0); - vm.expectRevert(bytes("px")); + vm.expectRevert(MerkleIndexOutOfBounds.selector); merkleTest.calculateRoot(proof, 2 ** 255, leaf); } @@ -60,7 +61,7 @@ contract MerkleTestTest is Test { bytes32 leaf = elements[0]; bytes32[] memory proof = new bytes32[](256); - vm.expectRevert(bytes("bt")); + vm.expectRevert(MerklePathOutOfBounds.selector); merkleTest.calculateRoot(proof, 0, leaf); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/OnEmptyQueue.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/OnEmptyQueue.sol index 7881409fc..753d5e33c 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/OnEmptyQueue.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/OnEmptyQueue.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {PriorityQueueSharedTest} from "./_PriorityQueue_Shared.t.sol"; +import {QueueIsEmpty} from "contracts/common/L1ContractErrors.sol"; contract OnEmptyQueueTest is PriorityQueueSharedTest { function test_gets() public { @@ -13,12 +14,12 @@ contract OnEmptyQueueTest is PriorityQueueSharedTest { } function test_failGetFront() public { - vm.expectRevert(bytes("D")); + vm.expectRevert(QueueIsEmpty.selector); priorityQueue.front(); } function test_failPopFront() public { - vm.expectRevert(bytes("s")); + vm.expectRevert(QueueIsEmpty.selector); priorityQueue.popFront(); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/PopOperations.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/PopOperations.sol index f2f7d73ba..5e43f6284 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/PopOperations.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/PriorityQueue/PopOperations.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {PriorityQueueSharedTest} from "./_PriorityQueue_Shared.t.sol"; import {PriorityOperation} from "contracts/dev-contracts/test/PriorityQueueTest.sol"; +import {QueueIsEmpty} from "contracts/common/L1ContractErrors.sol"; contract PopOperationsTest is PriorityQueueSharedTest { uint256 public constant NUMBER_OPERATIONS = 10; @@ -67,7 +68,7 @@ contract PopOperationsTest is PriorityQueueSharedTest { assertTrue(priorityQueue.isEmpty()); // And now let's go over the limit and fail. - vm.expectRevert(bytes.concat("s")); + vm.expectRevert(QueueIsEmpty.selector); priorityQueue.popFront(); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateL1L2Tx.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateL1L2Tx.t.sol index bb78a71b5..dbba8ca2e 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateL1L2Tx.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateL1L2Tx.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {TransactionValidatorSharedTest} from "./_TransactionValidator_Shared.t.sol"; import {L2CanonicalTransaction} from "contracts/common/Messaging.sol"; +import {PubdataGreaterThanLimit, TxnBodyGasLimitNotEnoughGas, ValidateTxnNotEnoughGas, NotEnoughGas, TooMuchGas, InvalidPubdataLength} from "contracts/common/L1ContractErrors.sol"; contract ValidateL1L2TxTest is TransactionValidatorSharedTest { function test_BasicRequestL1L2() public pure { @@ -16,7 +17,7 @@ contract ValidateL1L2TxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createTestTransaction(); // The limit is so low, that it doesn't even cover the overhead testTx.gasLimit = 0; - vm.expectRevert(bytes("my")); + vm.expectRevert(TxnBodyGasLimitNotEnoughGas.selector); validateL1ToL2Transaction(testTx, 500000, 100000); } @@ -27,7 +28,7 @@ contract ValidateL1L2TxTest is TransactionValidatorSharedTest { // before checking that it is below the max gas limit. uint256 priorityTxMaxGasLimit = 500000; testTx.gasLimit = priorityTxMaxGasLimit + 1000000; - vm.expectRevert(bytes("ui")); + vm.expectRevert(TooMuchGas.selector); validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit, 100000); } @@ -41,7 +42,7 @@ contract ValidateL1L2TxTest is TransactionValidatorSharedTest { // So if the pubdata costs per byte is 1 - then this transaction could produce 500k of pubdata. // (hypothetically, assuming all the gas was spent on writing). testTx.gasPerPubdataByteLimit = 1; - vm.expectRevert(bytes("uk")); + vm.expectRevert(abi.encodeWithSelector(PubdataGreaterThanLimit.selector, 100000, 490000)); validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit, 100000); } @@ -49,7 +50,7 @@ contract ValidateL1L2TxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createTestTransaction(); uint256 priorityTxMaxGasLimit = 500000; testTx.gasLimit = 200000; - vm.expectRevert(bytes("up")); + vm.expectRevert(ValidateTxnNotEnoughGas.selector); validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit, 100000); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateUpgradeTransaction.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateUpgradeTransaction.t.sol index df9a8f7eb..f3ac8238c 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateUpgradeTransaction.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/libraries/TransactionValidator/ValidateUpgradeTransaction.t.sol @@ -5,6 +5,7 @@ import {TransactionValidatorSharedTest} from "./_TransactionValidator_Shared.t.s import {L2CanonicalTransaction} from "contracts/common/Messaging.sol"; import {TransactionValidator} from "contracts/state-transition/libraries/TransactionValidator.sol"; +import {InvalidUpgradeTxn, UpgradeTxVerifyParam} from "contracts/common/L1ContractErrors.sol"; contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { function test_BasicRequest() public pure { @@ -16,7 +17,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // only system contracts (address < 2^16) are allowed to send upgrade transactions. testTx.from = uint256(1000000000); - vm.expectRevert(bytes("ua")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.From)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -24,7 +25,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // Now the 'to' address it too large. testTx.to = uint256(type(uint160).max) + 100; - vm.expectRevert(bytes("ub")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.To)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -32,7 +33,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // Paymaster must be 0 - otherwise we revert. testTx.paymaster = 1; - vm.expectRevert(bytes("uc")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Paymaster)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -40,7 +41,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // Value must be 0 - otherwise we revert. testTx.value = 1; - vm.expectRevert(bytes("ud")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Value)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -48,7 +49,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // reserved 0 must be 0 - otherwise we revert. testTx.reserved[0] = 1; - vm.expectRevert(bytes("ue")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Reserved0)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -56,7 +57,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // reserved 1 must be a valid address testTx.reserved[1] = uint256(type(uint160).max) + 100; - vm.expectRevert(bytes("uf")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Reserved1)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -64,7 +65,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // reserved 2 must be 0 - otherwise we revert. testTx.reserved[2] = 1; - vm.expectRevert(bytes("ug")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Reserved2)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -72,7 +73,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // reserved 3 be 0 - otherwise we revert. testTx.reserved[3] = 1; - vm.expectRevert(bytes("uo")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Reserved3)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -80,7 +81,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // Signature must be 0 - otherwise we revert. testTx.signature = bytes("hello"); - vm.expectRevert(bytes("uh")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.Signature)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -88,7 +89,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // PaymasterInput must be 0 - otherwise we revert. testTx.paymasterInput = bytes("hi"); - vm.expectRevert(bytes("ul1")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.PaymasterInput)); TransactionValidator.validateUpgradeTransaction(testTx); } @@ -96,7 +97,7 @@ contract ValidateUpgradeTxTest is TransactionValidatorSharedTest { L2CanonicalTransaction memory testTx = createUpgradeTransaction(); // ReservedDynamic must be 0 - otherwise we revert. testTx.reservedDynamic = bytes("something"); - vm.expectRevert(bytes("um")); + vm.expectRevert(abi.encodeWithSelector(InvalidUpgradeTxn.selector, UpgradeTxVerifyParam.ReservedDynamic)); TransactionValidator.validateUpgradeTransaction(testTx); } } diff --git a/l1-contracts/test/unit_tests/custom_base_token.spec.ts b/l1-contracts/test/unit_tests/custom_base_token.spec.ts index b0e9733a3..464298482 100644 --- a/l1-contracts/test/unit_tests/custom_base_token.spec.ts +++ b/l1-contracts/test/unit_tests/custom_base_token.spec.ts @@ -97,7 +97,7 @@ describe("Custom base token chain and bridge tests", () => { ) ); - expect(revertReason).equal("ShB not legacy bridge"); + expect(revertReason).contains("Unauthorized"); }); it("Should deposit base token successfully direct via bridgehub", async () => { @@ -147,13 +147,13 @@ describe("Custom base token chain and bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", []) ); - expect(revertReason).equal("ShB wrong msg len"); + expect(revertReason).contains("MalformedMessage"); }); it("Should revert on finalizing a withdrawal with wrong function selector", async () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, ethers.utils.randomBytes(96), []) ); - expect(revertReason).equal("ShB Incorrect message function selector"); + expect(revertReason).contains("InvalidSelector"); }); }); diff --git a/l1-contracts/test/unit_tests/governance_test.spec.ts b/l1-contracts/test/unit_tests/governance_test.spec.ts index 4ab11f266..444e70846 100644 --- a/l1-contracts/test/unit_tests/governance_test.spec.ts +++ b/l1-contracts/test/unit_tests/governance_test.spec.ts @@ -36,7 +36,7 @@ describe("Admin facet tests", function () { const revertReason = await getCallRevertReason( adminFacetTest.connect(randomSigner).setValidator(validatorAddress, true) ); - expect(revertReason).equal("Hyperchain: not state transition manager"); + expect(revertReason).contains("Unauthorized"); }); it("StateTransitionManager successfully set porter availability", async () => { @@ -48,7 +48,7 @@ describe("Admin facet tests", function () { it("random account fails to set porter availability", async () => { const revertReason = await getCallRevertReason(adminFacetTest.connect(randomSigner).setPorterAvailability(false)); - expect(revertReason).equal("Hyperchain: not state transition manager"); + expect(revertReason).contains("Unauthorized"); }); it("StateTransitionManager successfully set priority transaction max gas limit", async () => { @@ -64,7 +64,7 @@ describe("Admin facet tests", function () { const revertReason = await getCallRevertReason( adminFacetTest.connect(randomSigner).setPriorityTxMaxGasLimit(gasLimit) ); - expect(revertReason).equal("Hyperchain: not state transition manager"); + expect(revertReason).contains("Unauthorized"); }); describe("change admin", function () { @@ -92,7 +92,7 @@ describe("Admin facet tests", function () { it("failed to accept admin from not proposed account", async () => { const revertReason = await getCallRevertReason(adminFacetTest.connect(randomSigner).acceptAdmin()); - expect(revertReason).equal("n4"); + expect(revertReason).contains("Unauthorized"); }); it("accept admin from proposed account", async () => { diff --git a/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts b/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts index b53b12175..31475e241 100644 --- a/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts +++ b/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts @@ -98,7 +98,7 @@ describe("Shared Bridge tests", () => { { value: mintValue } ) ); - expect(revertReason).equal("6T"); + expect(revertReason).contains("EmptyDeposit"); }); it("Should deposit successfully", async () => { @@ -129,7 +129,7 @@ describe("Shared Bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [ethers.constants.HashZero]) ); - expect(revertReason).equal("ShB wrong msg len"); + expect(revertReason).contains("MalformedMessage"); }); it("Should revert on finalizing a withdrawal with wrong message length", async () => { @@ -145,14 +145,14 @@ describe("Shared Bridge tests", () => { [ethers.constants.HashZero] ) ); - expect(revertReason).equal("ShB wrong msg len 2"); + expect(revertReason).contains("MalformedMessage"); }); it("Should revert on finalizing a withdrawal with wrong function selector", async () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, ethers.utils.randomBytes(96), []) ); - expect(revertReason).equal("ShB Incorrect message function selector"); + expect(revertReason).contains("InvalidSelector"); }); it("Should deposit erc20 token successfully", async () => { @@ -183,7 +183,7 @@ describe("Shared Bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [ethers.constants.HashZero]) ); - expect(revertReason).equal("ShB wrong msg len"); + expect(revertReason).contains("MalformedMessage"); }); it("Should revert on finalizing a withdrawal with wrong function signature", async () => { @@ -192,7 +192,7 @@ describe("Shared Bridge tests", () => { .connect(randomSigner) .finalizeWithdrawal(chainId, 0, 0, 0, ethers.utils.randomBytes(76), [ethers.constants.HashZero]) ); - expect(revertReason).equal("ShB Incorrect message function selector"); + expect(revertReason).contains("InvalidSelector"); }); it("Should revert on finalizing a withdrawal with wrong batch number", async () => { @@ -206,7 +206,7 @@ describe("Shared Bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 10, 0, 0, l2ToL1message, []) ); - expect(revertReason).equal("xx"); + expect(revertReason).contains("BatchNotExecuted"); }); it("Should revert on finalizing a withdrawal with wrong length of proof", async () => { @@ -220,7 +220,7 @@ describe("Shared Bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, l2ToL1message, []) ); - expect(revertReason).equal("xc"); + expect(revertReason).contains("MerklePathEmpty"); }); it("Should revert on finalizing a withdrawal with wrong proof", async () => { @@ -236,6 +236,6 @@ describe("Shared Bridge tests", () => { .connect(randomSigner) .finalizeWithdrawal(chainId, 0, 0, 0, l2ToL1message, Array(9).fill(ethers.constants.HashZero)) ); - expect(revertReason).equal("ShB withd w proof"); + expect(revertReason).contains("InvalidProof"); }); }); diff --git a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts index 4ea71d99d..b5d97bf7d 100644 --- a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts +++ b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts @@ -179,7 +179,7 @@ describe.only("L2 upgrade test", function () { l2ProtocolUpgradeTx: noopUpgradeTransaction, }) ); - expect(bootloaderRevertReason).to.equal("Patch only upgrade can not set new bootloader"); + expect(bootloaderRevertReason).to.contain("PatchUpgradeCantSetBootloader"); const defaultAccountRevertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { @@ -188,7 +188,7 @@ describe.only("L2 upgrade test", function () { l2ProtocolUpgradeTx: noopUpgradeTransaction, }) ); - expect(defaultAccountRevertReason).to.equal("Patch only upgrade can not set new default account"); + expect(defaultAccountRevertReason).to.contain("PatchUpgradeCantSetDefaultAccount"); }); it("Should not allow upgrade transaction during patch upgrade", async () => { @@ -205,7 +205,7 @@ describe.only("L2 upgrade test", function () { l2ProtocolUpgradeTx: someTx, }) ); - expect(bootloaderRevertReason).to.equal("Patch only upgrade can not set upgrade transaction"); + expect(bootloaderRevertReason).to.contain("PatchCantSetUpgradeTxn"); }); it("Should not allow major version change", async () => { @@ -223,7 +223,7 @@ describe.only("L2 upgrade test", function () { l2ProtocolUpgradeTx: someTx, }) ); - expect(bootloaderRevertReason).to.equal("Major must always be 0"); + expect(bootloaderRevertReason).to.contain("NewProtocolMajorVersionNotZero"); }); it("Timestamp should behave correctly", async () => { @@ -241,7 +241,7 @@ describe.only("L2 upgrade test", function () { l2ProtocolUpgradeTx: noopUpgradeTransaction, }) ); - expect(revertReason).to.equal("Upgrade is not ready yet"); + expect(revertReason).contains("TimeNotReached"); }); it("Should require correct tx type for upgrade tx", async () => { @@ -255,7 +255,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("L2 system upgrade tx type is wrong"); + expect(revertReason).contains("InvalidTxType"); }); it("Should include the new protocol version as part of nonce", async () => { @@ -271,7 +271,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("The new protocol version should be included in the L2 system upgrade tx"); + expect(revertReason).contains("L2UpgradeNonceNotEqualToNewProtocolVersion"); }); it("Should ensure monotonic protocol version", async () => { @@ -287,7 +287,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("New protocol version is not greater than the current one"); + expect(revertReason).contains("ProtocolVersionTooSmall"); }); it("Should ensure protocol version not increasing too much", async () => { @@ -303,7 +303,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("Too big protocol version difference"); + expect(revertReason).contains("ProtocolVersionMinorDeltaTooBig"); }); it("Should validate upgrade transaction overhead", async () => { @@ -319,7 +319,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("my"); + expect(revertReason).contains("NotEnoughGas"); }); it("Should validate upgrade transaction gas max", async () => { @@ -335,7 +335,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("ui"); + expect(revertReason).contains("TooMuchGas"); }); it("Should validate upgrade transaction cannot output more pubdata than processable", async () => { @@ -352,7 +352,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("uk"); + expect(revertReason).contains("PubdataGreaterThanLimit"); }); it("Should validate factory deps", async () => { @@ -371,7 +371,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("Wrong factory dep hash"); + expect(revertReason).contains("L2BytecodeHashMismatch"); }); it("Should validate factory deps length match", async () => { @@ -389,7 +389,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("Wrong number of factory deps"); + expect(revertReason).contains("UnexpectedNumberOfFactoryDeps"); }); it("Should validate factory deps length isn't too large", async () => { @@ -409,7 +409,7 @@ describe.only("L2 upgrade test", function () { }) ); - expect(revertReason).to.equal("Factory deps can be at most 32"); + expect(revertReason).contains("TooManyFactoryDeps"); }); let l2UpgradeTxHash: string; @@ -616,7 +616,7 @@ describe.only("L2 upgrade test", function () { stateTransitionManager, upgrade ); - expect(revertReason).to.equal("Previous upgrade has not been finalized"); + expect(revertReason).to.contains("PreviousUpgradeNotFinalized"); }); it("Should require that the next commit batches contains an upgrade tx", async () => { @@ -630,7 +630,7 @@ describe.only("L2 upgrade test", function () { const revertReason = await getCallRevertReason( proxyExecutor.commitBatches(storedBatch2Info, [batch3InfoNoUpgradeTx]) ); - expect(revertReason).to.equal("b8"); + expect(revertReason).to.contains("MissingSystemLogs"); }); it("Should ensure any additional upgrade logs go to the priority ops hash", async () => { @@ -672,7 +672,7 @@ describe.only("L2 upgrade test", function () { const revertReason = await getCallRevertReason( proxyExecutor.commitBatches(storedBatch2Info, [batch3InfoNoUpgradeTx]) ); - expect(revertReason).to.equal("kp"); + expect(revertReason).to.contains("LogAlreadyProcessed"); }); it("Should fail to commit when upgrade tx hash does not match", async () => { @@ -705,7 +705,7 @@ describe.only("L2 upgrade test", function () { const revertReason = await getCallRevertReason( proxyExecutor.commitBatches(storedBatch2Info, [batch3InfoTwoUpgradeTx]) ); - expect(revertReason).to.equal("ut"); + expect(revertReason).to.contains("TxHashMismatch"); }); it("Should commit successfully when the upgrade tx is present", async () => { diff --git a/l1-contracts/test/unit_tests/legacy_era_test.spec.ts b/l1-contracts/test/unit_tests/legacy_era_test.spec.ts index 92a86dc7d..0f4f26bd9 100644 --- a/l1-contracts/test/unit_tests/legacy_era_test.spec.ts +++ b/l1-contracts/test/unit_tests/legacy_era_test.spec.ts @@ -103,7 +103,9 @@ describe("Legacy Era tests", function () { deployer.addresses.StateTransition.DiamondProxy ); - const proxyAdminInterface = new Interface(hardhat.artifacts.readArtifactSync("ProxyAdmin").abi); + const proxyAdminInterface = new Interface( + hardhat.artifacts.readArtifactSync("@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol:ProxyAdmin").abi + ); const calldata = proxyAdminInterface.encodeFunctionData("upgrade(address,address)", [ deployer.addresses.Bridges.SharedBridgeProxy, sharedBridge.address, @@ -142,7 +144,7 @@ describe("Legacy Era tests", function () { "deposit(address,address,uint256,uint256,uint256,address)" ](await randomSigner.getAddress(), erc20TestToken.address, 0, 0, 0, ethers.constants.AddressZero) ); - expect(revertReason).equal("0T"); + expect(revertReason).contains("EmptyDeposit"); }); it("Should deposit successfully", async () => { @@ -162,7 +164,7 @@ describe("Legacy Era tests", function () { const revertReason = await getCallRevertReason( l1ERC20Bridge.connect(randomSigner).finalizeWithdrawal(0, 0, 0, "0x", [ethers.constants.HashZero]) ); - expect(revertReason).equal("ShB wrong msg len"); + expect(revertReason).contains("MalformedMessage"); }); it("Should revert on finalizing a withdrawal with wrong function signature", async () => { @@ -171,7 +173,7 @@ describe("Legacy Era tests", function () { .connect(randomSigner) .finalizeWithdrawal(0, 0, 0, ethers.utils.randomBytes(76), [ethers.constants.HashZero]) ); - expect(revertReason).equal("ShB Incorrect message function selector"); + expect(revertReason).contains("InvalidSelector"); }); it("Should revert on finalizing a withdrawal with wrong batch number", async () => { @@ -185,7 +187,7 @@ describe("Legacy Era tests", function () { const revertReason = await getCallRevertReason( l1ERC20Bridge.connect(randomSigner).finalizeWithdrawal(10, 0, 0, l2ToL1message, []) ); - expect(revertReason).equal("xx"); + expect(revertReason).contains("BatchNotExecuted"); }); it("Should revert on finalizing a withdrawal with wrong length of proof", async () => { @@ -199,7 +201,7 @@ describe("Legacy Era tests", function () { const revertReason = await getCallRevertReason( l1ERC20Bridge.connect(randomSigner).finalizeWithdrawal(0, 0, 0, l2ToL1message, []) ); - expect(revertReason).equal("xc"); + expect(revertReason).contains("MerklePathEmpty"); }); it("Should revert on finalizing a withdrawal with wrong proof", async () => { @@ -215,7 +217,7 @@ describe("Legacy Era tests", function () { .connect(randomSigner) .finalizeWithdrawal(0, 0, 0, l2ToL1message, Array(9).fill(ethers.constants.HashZero)) ); - expect(revertReason).equal("ShB withd w proof"); + expect(revertReason).contains("InvalidProof"); }); /////////// Mailbox. Note we have these two together because we need to fix ERA Diamond proxy Address @@ -237,7 +239,7 @@ describe("Legacy Era tests", function () { ) ); - expect(revertReason).equal("pp"); + expect(revertReason).contains("MalformedBytecode"); }); describe("finalizeEthWithdrawal", function () { @@ -284,7 +286,7 @@ describe("Legacy Era tests", function () { const revertReason = await getCallRevertReason( mailbox.finalizeEthWithdrawal(BLOCK_NUMBER, MESSAGE_INDEX, TX_NUMBER_IN_BLOCK, MESSAGE, invalidProof) ); - expect(revertReason).equal("ShB withd w proof"); + expect(revertReason).contains("InvalidProof"); }); it("Successful deposit", async () => { @@ -316,7 +318,7 @@ describe("Legacy Era tests", function () { const revertReason = await getCallRevertReason( mailbox.finalizeEthWithdrawal(BLOCK_NUMBER, MESSAGE_INDEX, TX_NUMBER_IN_BLOCK, MESSAGE, MERKLE_PROOF) ); - expect(revertReason).equal("Withdrawal is already finalized"); + expect(revertReason).contains("WithdrawalAlreadyFinalized"); }); }); }); diff --git a/l1-contracts/test/unit_tests/mailbox_test.spec.ts b/l1-contracts/test/unit_tests/mailbox_test.spec.ts index 7210ccc44..5bb874381 100644 --- a/l1-contracts/test/unit_tests/mailbox_test.spec.ts +++ b/l1-contracts/test/unit_tests/mailbox_test.spec.ts @@ -105,7 +105,7 @@ describe("Mailbox tests", function () { ) ); - expect(revertReason).equal("pq"); + expect(revertReason).contains("MalformedBytecode"); }); it("Should not accept bytecode of even length in words", async () => { @@ -122,7 +122,7 @@ describe("Mailbox tests", function () { ) ); - expect(revertReason).equal("ps"); + expect(revertReason).contains("MalformedBytecode"); }); describe("finalizeEthWithdrawal", function () { @@ -167,21 +167,21 @@ describe("Mailbox tests", function () { const revertReason = await getCallRevertReason( mailbox.finalizeEthWithdrawal(BLOCK_NUMBER, MESSAGE_INDEX, TX_NUMBER_IN_BLOCK, MESSAGE, invalidProof) ); - expect(revertReason).equal("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + expect(revertReason).contains("OnlyEraSupported"); }); it("Successful withdrawal", async () => { const revertReason = await getCallRevertReason( mailbox.finalizeEthWithdrawal(BLOCK_NUMBER, MESSAGE_INDEX, TX_NUMBER_IN_BLOCK, MESSAGE, MERKLE_PROOF) ); - expect(revertReason).equal("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + expect(revertReason).contains("OnlyEraSupported"); }); it("Reverts when withdrawal is already finalized", async () => { const revertReason = await getCallRevertReason( mailbox.finalizeEthWithdrawal(BLOCK_NUMBER, MESSAGE_INDEX, TX_NUMBER_IN_BLOCK, MESSAGE, MERKLE_PROOF) ); - expect(revertReason).equal("Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + expect(revertReason).contains("OnlyEraSupported"); }); }); diff --git a/l1-contracts/test/unit_tests/proxy_test.spec.ts b/l1-contracts/test/unit_tests/proxy_test.spec.ts index 3c3ae6429..e63abe0bb 100644 --- a/l1-contracts/test/unit_tests/proxy_test.spec.ts +++ b/l1-contracts/test/unit_tests/proxy_test.spec.ts @@ -134,14 +134,14 @@ describe("Diamond proxy tests", function () { const proxyAsERC20 = TestnetERC20TokenFactory.connect(proxy.address, proxy.signer); const revertReason = await getCallRevertReason(proxyAsERC20.transfer(proxyAsERC20.address, 0)); - expect(revertReason).equal("F"); + expect(revertReason).contains("InvalidSelector"); }); it("check that proxy reject data with no selector", async () => { const dataWithoutSelector = "0x1122"; const revertReason = await getCallRevertReason(proxy.fallback({ data: dataWithoutSelector })); - expect(revertReason).equal("Ut"); + expect(revertReason).contains("MalformedCalldata"); }); it("should freeze the diamond storage", async () => { @@ -178,7 +178,7 @@ describe("Diamond proxy tests", function () { data: executorFacetSelector3 + "0000000000000000000000000000000000000000000000000000000000000000", }) ); - expect(revertReason).equal("q1"); + expect(revertReason).contains("FacetIsFrozen"); }); it("should be able to call an unfreezable facet when diamondStorage is frozen", async () => { diff --git a/l1-contracts/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts index 2bbf51733..3e21d3c81 100644 --- a/l1-contracts/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -16,7 +16,7 @@ import { packSemver } from "../../scripts/utils"; export const CONTRACTS_GENESIS_PROTOCOL_VERSION = packSemver(0, 21, 0).toString(); // eslint-disable-next-line @typescript-eslint/no-var-requires -export const IERC20_INTERFACE = require("@openzeppelin/contracts/build/contracts/IERC20"); +export const IERC20_INTERFACE = require("@openzeppelin/contracts-v4/build/contracts/IERC20"); export const DEFAULT_REVERT_REASON = "VM did not revert"; export const DEFAULT_L2_LOGS_TREE_ROOT_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000"; @@ -98,7 +98,21 @@ export async function getCallRevertReason(promise) { } } } catch (_) { - throw e; + try { + if ( + revertReason === "cannot estimate gas; transaction may fail or may require manual gas limit" || + revertReason === DEFAULT_REVERT_REASON + ) { + if (e.error) { + revertReason = + e.error.toString().match(/reverted with custom error '([^']*)'/)[1] || "PLACEHOLDER_STRING"; + } else { + revertReason = e.toString().match(/reverted with custom error '([^']*)'/)[1] || "PLACEHOLDER_STRING"; + } + } + } catch (_) { + throw e; + } } } } diff --git a/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts b/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts index 119cae7cc..af3c951ff 100644 --- a/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts +++ b/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts @@ -90,7 +90,7 @@ describe("ValidatorTimelock tests", function () { validatorTimelock.connect(randomSigner).commitBatches(getMockStoredBatchInfo(0), [getMockCommitBatchInfo(1)]) ); - expect(revertReason).equal("ValidatorTimelock: only validator"); + expect(revertReason).contains("Unauthorized"); }); it("Should revert if non-validator proves batches", async () => { @@ -100,13 +100,13 @@ describe("ValidatorTimelock tests", function () { .proveBatches(getMockStoredBatchInfo(0), [getMockStoredBatchInfo(1)], MOCK_PROOF_INPUT) ); - expect(revertReason).equal("ValidatorTimelock: only validator"); + expect(revertReason).contains("Unauthorized"); }); it("Should revert if non-validator revert batches", async () => { const revertReason = await getCallRevertReason(validatorTimelock.connect(randomSigner).revertBatches(1)); - expect(revertReason).equal("ValidatorTimelock: only validator"); + expect(revertReason).contains("Unauthorized"); }); it("Should revert if non-validator executes batches", async () => { @@ -114,7 +114,7 @@ describe("ValidatorTimelock tests", function () { validatorTimelock.connect(randomSigner).executeBatches([getMockStoredBatchInfo(1)]) ); - expect(revertReason).equal("ValidatorTimelock: only validator"); + expect(revertReason).contains("Unauthorized"); }); it("Should revert if not chain governor sets validator", async () => { @@ -122,7 +122,7 @@ describe("ValidatorTimelock tests", function () { validatorTimelock.connect(randomSigner).addValidator(chainId, await randomSigner.getAddress()) ); - expect(revertReason).equal("ValidatorTimelock: only chain admin"); + expect(revertReason).contains("Unauthorized"); }); it("Should revert if non-owner sets execution delay", async () => { @@ -165,7 +165,7 @@ describe("ValidatorTimelock tests", function () { validatorTimelock.connect(validator).executeBatchesSharedBridge(chainId, [getMockStoredBatchInfo(1)]) ); - expect(revertReason).equal("5c"); + expect(revertReason).contains("TimeNotReached"); }); it("Should successfully revert batches", async () => { diff --git a/l2-contracts/contracts/Dependencies.sol b/l2-contracts/contracts/Dependencies.sol index bb8adf1f5..591cb9fd9 100644 --- a/l2-contracts/contracts/Dependencies.sol +++ b/l2-contracts/contracts/Dependencies.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /* solhint-disable-next-line no-unused-import */ -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; /* solhint-disable-next-line no-unused-import */ -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol"; diff --git a/l2-contracts/contracts/L2ContractHelper.sol b/l2-contracts/contracts/L2ContractHelper.sol index 79090a3a9..60442bad0 100644 --- a/l2-contracts/contracts/L2ContractHelper.sol +++ b/l2-contracts/contracts/L2ContractHelper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/l2-contracts/contracts/SystemContractsCaller.sol b/l2-contracts/contracts/SystemContractsCaller.sol index 97753cbac..79161eaaf 100644 --- a/l2-contracts/contracts/SystemContractsCaller.sol +++ b/l2-contracts/contracts/SystemContractsCaller.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT // solhint-disable one-contract-per-file - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {MSG_VALUE_SYSTEM_CONTRACT} from "./L2ContractHelper.sol"; @@ -48,7 +48,7 @@ library SystemContractsCaller { assembly { dataStart := add(data, 0x20) } - uint32 dataLength = uint32(Utils.safeCastToU32(data.length)); + uint32 dataLength = Utils.safeCastToU32(data.length); uint256 farCallAbi = getFarCallABI({ dataOffset: 0, diff --git a/l2-contracts/contracts/TestnetPaymaster.sol b/l2-contracts/contracts/TestnetPaymaster.sol index 6a85ff84c..36087352d 100644 --- a/l2-contracts/contracts/TestnetPaymaster.sol +++ b/l2-contracts/contracts/TestnetPaymaster.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; -pragma solidity 0.8.20; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import {IPaymaster, ExecutionResult, PAYMASTER_VALIDATION_SUCCESS_MAGIC} from "./interfaces/IPaymaster.sol"; import {IPaymasterFlow} from "./interfaces/IPaymasterFlow.sol"; import {Transaction, BOOTLOADER_ADDRESS} from "./L2ContractHelper.sol"; -import {InvalidCaller, InvalidInput, InsufficientAllowance, FailedToTransferTokens, UnsupportedPaymasterFlow} from "./L2ContractErrors.sol"; +import {Unauthorized, InvalidInput, InsufficientAllowance, FailedToTransferTokens, UnsupportedPaymasterFlow} from "./errors/L2ContractErrors.sol"; // This is a dummy paymaster. It expects the paymasterInput to contain its "signature" as well as the needed exchange rate. // It supports only approval-based paymaster flow. @@ -16,12 +16,12 @@ contract TestnetPaymaster is IPaymaster { bytes32, bytes32, Transaction calldata _transaction - ) external payable returns (bytes4 magic, bytes memory context) { + ) external payable returns (bytes4 magic, bytes memory) { // By default we consider the transaction as accepted. magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; if (msg.sender != BOOTLOADER_ADDRESS) { - revert InvalidCaller(msg.sender); + revert Unauthorized(msg.sender); } if (_transaction.paymasterInput.length < 4) { diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index a96b45252..1db972714 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.20; -import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; -import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; +import {Initializable} from "@openzeppelin/contracts-v4/proxy/utils/Initializable.sol"; +import {BeaconProxy} from "@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol"; import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; import {IL2SharedBridge} from "./interfaces/IL2SharedBridge.sol"; @@ -15,7 +15,7 @@ import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; import {L2ContractHelper, DEPLOYER_SYSTEM_CONTRACT, IContractDeployer} from "../L2ContractHelper.sol"; import {SystemContractsCaller} from "../SystemContractsCaller.sol"; -import {EmptyAddress, EmptyBytes32, InvalidCaller, AddressMismatch, AmountMustBeGreaterThanZero, DeployFailed} from "../L2ContractErrors.sol"; +import {ZeroAddress, EmptyBytes32, Unauthorized, AddressMismatch, AmountMustBeGreaterThanZero, DeployFailed} from "../errors/L2ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -60,7 +60,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { address _aliasedOwner ) external reinitializer(2) { if (_l1SharedBridge == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } if (_l2TokenProxyBytecodeHash == bytes32(0)) { @@ -68,7 +68,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { } if (_aliasedOwner == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } l1SharedBridge = _l1SharedBridge; @@ -80,7 +80,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { l2TokenBeacon.transferOwnership(_aliasedOwner); } else { if (_l1Bridge == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } l1Bridge = _l1Bridge; // l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy @@ -105,7 +105,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1Bridge && AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1SharedBridge ) { - revert InvalidCaller(msg.sender); + revert Unauthorized(msg.sender); } address expectedL2Token = l2TokenAddress(_l1Token); @@ -151,7 +151,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { address l1Token = l1TokenAddress[_l2Token]; if (l1Token == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } bytes memory message = _getL1WithdrawMessage(_l1Receiver, l1Token, _amount); diff --git a/l2-contracts/contracts/bridge/L2StandardERC20.sol b/l2-contracts/contracts/bridge/L2StandardERC20.sol index 2104629f4..e28cf41b5 100644 --- a/l2-contracts/contracts/bridge/L2StandardERC20.sol +++ b/l2-contracts/contracts/bridge/L2StandardERC20.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.20; -import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; -import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; -import {ERC1967Upgrade} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; +import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol"; +import {ERC1967Upgrade} from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Upgrade.sol"; import {IL2StandardToken} from "./interfaces/IL2StandardToken.sol"; -import {EmptyAddress, Unauthorized, NonSequentialVersion, Unimplemented} from "../L2ContractErrors.sol"; +import {ZeroAddress, Unauthorized, NonSequentialVersion} from "../errors/L2ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -50,7 +50,7 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg /// In this case, it is packed `name`/`symbol`/`decimals` of the L1 token. function bridgeInitialize(address _l1Address, bytes calldata _data) external initializer { if (_l1Address == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } l1Address = _l1Address; @@ -121,7 +121,7 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg // allow the governor of the beacon to reinitialize the token. address beaconAddress = _getBeacon(); if (msg.sender != UpgradeableBeacon(beaconAddress).owner()) { - revert Unauthorized(); + revert Unauthorized(msg.sender); } __ERC20_init_unchained(_newName, _newSymbol); @@ -133,7 +133,7 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg modifier onlyBridge() { if (msg.sender != l2Bridge) { - revert Unauthorized(); + revert Unauthorized(msg.sender); } _; } @@ -167,19 +167,22 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg function name() public view override returns (string memory) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreName) revert Unimplemented(); + // solhint-disable-next-line reason-string, gas-custom-errors + if (availableGetters.ignoreName) revert(); return super.name(); } function symbol() public view override returns (string memory) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreSymbol) revert Unimplemented(); + // solhint-disable-next-line reason-string, gas-custom-errors + if (availableGetters.ignoreSymbol) revert(); return super.symbol(); } function decimals() public view override returns (uint8) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreDecimals) revert Unimplemented(); + // solhint-disable-next-line reason-string, gas-custom-errors + if (availableGetters.ignoreDecimals) revert(); return decimals_; } diff --git a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol index 8fc3b05b9..1166fa008 100644 --- a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol +++ b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.20; -import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; +import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; import {IL2WrappedBaseToken} from "./interfaces/IL2WrappedBaseToken.sol"; import {IL2StandardToken} from "./interfaces/IL2StandardToken.sol"; -import {EmptyAddress, Unauthorized, UnimplementedMessage, BRIDGE_MINT_NOT_IMPLEMENTED, WithdrawFailed} from "../L2ContractErrors.sol"; +import {ZeroAddress, Unauthorized, UnimplementedMessage, BRIDGE_MINT_NOT_IMPLEMENTED, WithdrawFailed} from "../errors/L2ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -50,11 +50,11 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S address _l1Address ) external reinitializer(2) { if (_l2Bridge == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } if (_l1Address == address(0)) { - revert EmptyAddress(); + revert ZeroAddress(); } l2Bridge = _l2Bridge; l1Address = _l1Address; @@ -70,7 +70,7 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S modifier onlyBridge() { if (msg.sender != l2Bridge) { - revert Unauthorized(); + revert Unauthorized(msg.sender); } _; } diff --git a/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol b/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol index 407669613..02a16b990 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /// @author Matter Labs // note we use the IL1ERC20Bridge only to send L1<>L2 messages, diff --git a/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol b/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol index 8ec1ff757..5f196f1a5 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /// @title L1 Bridge contract interface /// @author Matter Labs diff --git a/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol b/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol index c1aa05102..71e569795 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /// @author Matter Labs interface IL2SharedBridge { diff --git a/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol b/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol index 6ceb1ae80..4c2aaa323 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IL2StandardToken { event BridgeInitialize(address indexed l1Token, string name, string symbol, uint8 decimals); diff --git a/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol b/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol index 693aa139a..df447e0f8 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IL2WrappedBaseToken { event Initialize(string name, string symbol, uint8 decimals); diff --git a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol index 12a6a187f..e383d83c3 100644 --- a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol +++ b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.20; import {L2SharedBridge} from "../bridge/L2SharedBridge.sol"; import {L2StandardERC20} from "../bridge/L2StandardERC20.sol"; -import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol"; /// @author Matter Labs /// @notice The implementation of the shared bridge that allows setting legacy bridge. Must only be used in local testing environments. diff --git a/l2-contracts/contracts/L2ContractErrors.sol b/l2-contracts/contracts/errors/L2ContractErrors.sol similarity index 56% rename from l2-contracts/contracts/L2ContractErrors.sol rename to l2-contracts/contracts/errors/L2ContractErrors.sol index 98b5048b3..59fc9eaaa 100644 --- a/l2-contracts/contracts/L2ContractErrors.sol +++ b/l2-contracts/contracts/errors/L2ContractErrors.sol @@ -1,20 +1,38 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; -error InvalidCaller(address); -error InvalidInput(); -error InsufficientAllowance(uint256 providedAllowance, uint256 requiredAmount); -error FailedToTransferTokens(address tokenContract, address to, uint256 amount); -error UnsupportedPaymasterFlow(); -error EmptyAddress(); -error EmptyBytes32(); +// 0x1f73225f error AddressMismatch(address expected, address supplied); +// 0x5e85ae73 error AmountMustBeGreaterThanZero(); +// 0xb4f54111 error DeployFailed(); -error Unauthorized(); +// 0x7138356f +error EmptyAddress(); +// 0x1c25715b +error EmptyBytes32(); +// 0x1bdfd505 +error FailedToTransferTokens(address tokenContract, address to, uint256 amount); +// 0x2a1b2dd8 +error InsufficientAllowance(uint256 providedAllowance, uint256 requiredAmount); +// 0xcbd9d2e0 +error InvalidCaller(address); +// 0xb4fa3fb3 +error InvalidInput(); +// 0x0ac76f01 error NonSequentialVersion(); +// 0x8e4a23d6 +error Unauthorized(address); +// 0x6e128399 error Unimplemented(); -error UnimplementedMessage(string); +// 0xa4dde386 +error UnimplementedMessage(string message); +// 0xff15b069 +error UnsupportedPaymasterFlow(); +// 0x750b219c error WithdrawFailed(); +// 0xd92e233d +error ZeroAddress(); string constant BRIDGE_MINT_NOT_IMPLEMENTED = "bridgeMint is not implemented! Use deposit/depositTo methods instead."; diff --git a/l2-contracts/contracts/interfaces/IPaymaster.sol b/l2-contracts/contracts/interfaces/IPaymaster.sol index 8ba4bc694..f7246457c 100644 --- a/l2-contracts/contracts/interfaces/IPaymaster.sol +++ b/l2-contracts/contracts/interfaces/IPaymaster.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {Transaction} from "../L2ContractHelper.sol"; diff --git a/l2-contracts/contracts/interfaces/IPaymasterFlow.sol b/l2-contracts/contracts/interfaces/IPaymasterFlow.sol index 2ee4f64f7..75e94a323 100644 --- a/l2-contracts/contracts/interfaces/IPaymasterFlow.sol +++ b/l2-contracts/contracts/interfaces/IPaymasterFlow.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/l2-contracts/contracts/vendor/AddressAliasHelper.sol b/l2-contracts/contracts/vendor/AddressAliasHelper.sol index 33b5e95e8..0dec0b9ee 100644 --- a/l2-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l2-contracts/contracts/vendor/AddressAliasHelper.sol @@ -15,8 +15,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; library AddressAliasHelper { uint160 internal constant offset = uint160(0x1111000000000000000000000000000000001111); diff --git a/l2-contracts/package.json b/l2-contracts/package.json index a9dfc2779..474a5a25a 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -11,8 +11,8 @@ "@nomicfoundation/hardhat-verify": "^1.1.0", "@nomiclabs/hardhat-ethers": "^2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.7", - "@openzeppelin/contracts": "4.9.5", - "@openzeppelin/contracts-upgradeable": "4.9.5", + "@openzeppelin/contracts-upgradeable-v4": "npm:@openzeppelin/contracts-upgradeable@4.9.5", + "@openzeppelin/contracts-v4": "npm:@openzeppelin/contracts@4.9.5", "@typechain/ethers-v5": "^2.0.0", "@types/chai": "^4.2.21", "@types/chai-as-promised": "^7.1.4", diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index 5bf18af74..613fcaf8c 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -148,7 +148,9 @@ export async function deploySharedBridgeProxyOnL2ThroughL1( ); /// loading TransparentUpgradeableProxy bytecode - const L2_SHARED_BRIDGE_PROXY_BYTECODE = hre.artifacts.readArtifactSync("TransparentUpgradeableProxy").bytecode; + const L2_SHARED_BRIDGE_PROXY_BYTECODE = hre.artifacts.readArtifactSync( + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy" + ).bytecode; /// compute L2SharedBridgeProxy address const l2SharedBridgeProxyAddress = computeL2Create2Address( diff --git a/l2-contracts/test/erc20.test.ts b/l2-contracts/test/erc20.test.ts index afc5a2ed8..5f1f21a30 100644 --- a/l2-contracts/test/erc20.test.ts +++ b/l2-contracts/test/erc20.test.ts @@ -45,12 +45,18 @@ describe("ERC20Bridge", function () { // While we formally don't need to deploy the token and the beacon proxy, it is a neat way to have the bytecode published const l2TokenImplAddress = await deployer.deploy(await deployer.loadArtifact("L2StandardERC20")); - const l2Erc20TokenBeacon = await deployer.deploy(await deployer.loadArtifact("UpgradeableBeacon"), [ - l2TokenImplAddress.address, - ]); - await deployer.deploy(await deployer.loadArtifact("BeaconProxy"), [l2Erc20TokenBeacon.address, "0x"]); - - const beaconProxyBytecodeHash = hashBytecode((await deployer.loadArtifact("BeaconProxy")).bytecode); + const l2Erc20TokenBeacon = await deployer.deploy( + await deployer.loadArtifact("@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol:UpgradeableBeacon"), + [l2TokenImplAddress.address] + ); + await deployer.deploy( + await deployer.loadArtifact("@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol:BeaconProxy"), + [l2Erc20TokenBeacon.address, "0x"] + ); + + const beaconProxyBytecodeHash = hashBytecode( + (await deployer.loadArtifact("@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol:BeaconProxy")).bytecode + ); const erc20BridgeImpl = await deployer.deploy(await deployer.loadArtifact("L2SharedBridge"), [testChainId]); const bridgeInitializeData = erc20BridgeImpl.interface.encodeFunctionData("initialize", [ @@ -60,11 +66,12 @@ describe("ERC20Bridge", function () { governorWallet.address, ]); - const erc20BridgeProxy = await deployer.deploy(await deployer.loadArtifact("TransparentUpgradeableProxy"), [ - erc20BridgeImpl.address, - governorWallet.address, - bridgeInitializeData, - ]); + const erc20BridgeProxy = await deployer.deploy( + await deployer.loadArtifact( + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy" + ), + [erc20BridgeImpl.address, governorWallet.address, bridgeInitializeData] + ); erc20Bridge = L2SharedBridgeFactory.connect(erc20BridgeProxy.address, deployerWallet); }); diff --git a/l2-contracts/test/weth.test.ts b/l2-contracts/test/weth.test.ts index 5337b8ae2..3e8489077 100644 --- a/l2-contracts/test/weth.test.ts +++ b/l2-contracts/test/weth.test.ts @@ -28,16 +28,18 @@ describe("WETH token & WETH bridge", function () { const wethBridgeImpl = await deployer.deploy(await deployer.loadArtifact("L2SharedBridge"), [testChainId]); const randomAddress = ethers.utils.hexlify(ethers.utils.randomBytes(20)); - const wethTokenProxy = await deployer.deploy(await deployer.loadArtifact("TransparentUpgradeableProxy"), [ - wethTokenImpl.address, - randomAddress, - "0x", - ]); - const wethBridgeProxy = await deployer.deploy(await deployer.loadArtifact("TransparentUpgradeableProxy"), [ - wethBridgeImpl.address, - randomAddress, - "0x", - ]); + const wethTokenProxy = await deployer.deploy( + await deployer.loadArtifact( + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy" + ), + [wethTokenImpl.address, randomAddress, "0x"] + ); + const wethBridgeProxy = await deployer.deploy( + await deployer.loadArtifact( + "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy" + ), + [wethBridgeImpl.address, randomAddress, "0x"] + ); wethToken = L2WrappedBaseTokenFactory.connect(wethTokenProxy.address, wallet); wethBridge = L2SharedBridgeFactory.connect(wethBridgeProxy.address, wallet); diff --git a/lib/forge-std b/lib/forge-std index 52715a217..bf6606142 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 +Subproject commit bf6606142994b1e47e2882ce0cd477c020d77623 diff --git a/lib/murky b/lib/murky index 40de6e801..5feccd125 160000 --- a/lib/murky +++ b/lib/murky @@ -1 +1 @@ -Subproject commit 40de6e80117f39cda69d71b07b7c824adac91b29 +Subproject commit 5feccd1253d7da820f7cccccdedf64471025455d diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable-v4 similarity index 100% rename from lib/openzeppelin-contracts-upgradeable rename to lib/openzeppelin-contracts-upgradeable-v4 diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts-v4 similarity index 100% rename from lib/openzeppelin-contracts rename to lib/openzeppelin-contracts-v4 diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index f45ca6844..ab97cd3fe 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,49 +3,49 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x0100005db7d0621192834d201f8bcd14c6ac987b95f422ca8bb28d500748f1fa", - "sourceCodeHash": "0x69d2533e5481ff13e65f4442e650f4b90c46a48ac643cac9798bbbf421194353" + "bytecodeHash": "0x0100005d64619baff70736b321ae7fc72e6d9f724347b8f122c73ef89d159863", + "sourceCodeHash": "0x5d544ebe1b1d4f99fe4410c9be644cd0b407109e30f632e968b484bf2d456994" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007c7e006453f3693c1f1c7500b74c594e7a627076be9d2dcb35c1c268dc3", + "bytecodeHash": "0x010007c7288dc176003cc849cf9f416a3044acfb8dc5a765f913aeddeeaa9049", "sourceCodeHash": "0x26060f33c7c63bd1f8a1a2f3b368b97ef8dd939bc53e95090f2c556248b99dce" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x0100004db8b96797e7d854f2c67c2f13d3920dcf82602f77a6ce0e2353304b37", + "bytecodeHash": "0x0100004d0baa3ea2154890efb215a755bb7dc83b1d4ce3d006b7ee915fb3a69c", "sourceCodeHash": "0xdde7c49a94cc3cd34c3e7ced1b5ba45e4740df68d26243871edbe393e7298f7a" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x0100014387fd8393671b5edd2cc5bb58f72d357c033a44c6274fe92abf19f96d", - "sourceCodeHash": "0x63f5f3a541ac5b59736f9117b15f293346d1842fbfe75219f7961e73185315c5" + "bytecodeHash": "0x0100014f56e04fc62384e7b4fcd95886169e81e0baeecb53fd1ed9220302dcf5", + "sourceCodeHash": "0x11646629bb325ba0f343b8d9c99ee60ac847db28841e25e16df8f3d1dd442c7e" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010004e5b06e78c8ffbdf6c578ce9d101d8d852e62e71f79ff8f845e7ada7fc9", - "sourceCodeHash": "0xdc95cb75554260ef8793c7899dbbc681165a441109458b3d058b03a0857d00e3" + "bytecodeHash": "0x010004e5ae40ac1d3e2a5341f3e9ff1e6f389cc318d34bf6cd3ddb8f24db7b96", + "sourceCodeHash": "0x73056341b4db6b90b6486b36a67b775f857d75641d5759ef7cfa549e1eef5569" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x01000049cd4b556f8ebc05b0bd35d9996e0b65412343bcc8eb6ce14d958dd21f", + "bytecodeHash": "0x010000494b831ba9201da08e9996cb88bc85cec3344ff9b17c0d374921cb393e", "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x0100055dbcf921fb36006fa42209bda58bc468eb33257b1782e854ed29273e64", + "bytecodeHash": "0x0100055d5f308aa35d8b308207f095412dbeac7b09c8bb1845640b1069391255", "sourceCodeHash": "0xeb5ac8fc83e1c8619db058a9b6973958bd6ed1b6f4938f8f4541d702f12e085d" }, { @@ -59,57 +59,57 @@ "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003b91f0ceda986543b6b45811b72cb492cdcb80c42d8600185e33f72251", + "bytecodeHash": "0x0100003b4921070b396b98a09369b50a1885e964bcd7bd472954ade597435df9", "sourceCodeHash": "0x4212e99cbc1722887cfb5b4cb967f278ac8642834786f0e3c6f3b324a9316815" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100006f8342acd40c21d8e535e8ceb65d370ad76a116f3a893fa67452bb616f", - "sourceCodeHash": "0x8da495a9fc5aa0d7d20a165a4fc8bc77012bec29c472015ea5ecc0a2bd706137" + "bytecodeHash": "0x0100006f7cae202a327bc851d670b261ccb186f8914551d3faea3b9f9bf673ba", + "sourceCodeHash": "0x579950be3bcde43a5a4b1f62d8083b10b974bb3e29a3d0108c0bb65235fb15e9" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x0100029361cc1606b2e55c12bef0a9ccbb36f70f6a12b41593b34053ea93f433", - "sourceCodeHash": "0x3e4c749b52c9fd8e6040b836dac10df29305ee0fc4fc9418326d3197e1630c38" + "bytecodeHash": "0x01000295b3a3343d055aefa650a194f3b8463226d71824c5e46fa3ab0c03b09b", + "sourceCodeHash": "0xf54fae4c1a4bcd0c59e86e3138a5bc3607c9475e14abd0bdc3fcac9ff6b193c5" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x010001055346ab8d4eb1b48ef7e768a95930d4ef6300c57ca173f4a76d1a9258", - "sourceCodeHash": "0x4cdafafd4cfdf410b31641e14487ea657be3af25e5ec1754fcd7ad67ec23d8be" + "bytecodeHash": "0x01000105ed9165628c35526f34a6849d4d292fb49ce0747fea77049e5af7aa8d", + "sourceCodeHash": "0xc9211efcd2b050fbd8a1b6f119eadb61e9a861eea680acc3bbbcae4273f38877" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x0100005d606dc17844411ee44a09b08e574347fd92fb4df7d1739fe02ebae2cc", - "sourceCodeHash": "0x4834adf62dbaefa1a1c15d36b5ad1bf2826e7d888a17be495f7ed4e4ea381aa8" + "bytecodeHash": "0x0100005dabca233a79399af9da2828d2f37cfd1af346aa34904aefeb93142977", + "sourceCodeHash": "0x2f1ff8df1edb1d3240b62e8ae0e21ed3cce0be12940464d2dbe051d09645ff5f" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000dbe03a15e6478090c69b0565c273a9cb034c8af48b70d8e71baf5ecf94", - "sourceCodeHash": "0xaa2ed3a26af30032c00a612ac327e0cdf5288b7c932ae903462355f863f950cb" + "bytecodeHash": "0x010000db81f4d732c5f4ca60920dff4b849f330d7f4a61ec61f35df5849d417e", + "sourceCodeHash": "0x32f2f4794ded4d9756b460213d3aea39afece6f4f10e10e2b524c4a5bd92497d" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x01000047abbd0db8bc506c1cb48e3aab878da3e5ea1bbacf1d4b5f46391f2493", - "sourceCodeHash": "0x0568a9a12bdac94c9e055ca303824a6bf4dc4aa503cfe9a2586c7d3dda8d45da" + "bytecodeHash": "0x0100004772e57643de06b7513a4a823ca2996f954544fc5351feb161f1cd9039", + "sourceCodeHash": "0xc4d42950e01529cb4594ec4637b4b07c993a7f4be17e2afe209439b8511d3de3" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001a55d8778874657090f2db3a8aeabd491a5f3352f04c89eadabdd92e6ba", - "sourceCodeHash": "0xf23d12ad2f17ad3b26e909fabfdcfaf4e1d158923e7cb8eeb9b5965a0b464406" + "bytecodeHash": "0x010001a57a8eb66307a7f54e37a90a83b54b8776a5c1ccd503bb6474aa3de620", + "sourceCodeHash": "0x2d075dace38e50e046c723a1bd71b7cc4b8cd3fba20dccdcf3c4ed26b0bcb7b2" }, { "contractName": "EventWriter", @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb92f46b717a3351f085b9d0d7cf1b6c164f390487f29da5c3b1f272a1", - "sourceCodeHash": "0xbf798f55f3b5c3d4d29423278bd68c6bb6428f0290f6791b2e20963166b3b21a" + "bytecodeHash": "0x010003cb3b017071d5d91d0ad424d9e5a31fa6199e80282fa6c85c8af1de0cef", + "sourceCodeHash": "0xeb3ae62b4739a5275c2459336923b005e367eb4292583fc20bde95fc08fea585" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x01000951d5e14249434340fe5e6be707157f16d66ca10d0e5fcc110cc674def4", - "sourceCodeHash": "0xc7cd680273e89b1dfc3c6941f69611894c885e26656adfc4586c4eb149285d9d" + "bytecodeHash": "0x0100094f3e9b6fdb0b38fce9c15d336e2e4c9896608562978026ce20faa26d4c", + "sourceCodeHash": "0x2ee776cfab86d04d8d847b2e592b6ef6b2fb8ca39e369848d552490aa5a12ece" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d7db21670fda613a703321bb109f192ef92a6cef40b07a35a661c4d563", - "sourceCodeHash": "0xaf85e223e2156440f007fed14c9fe8899d33ad2f0aeb7feab3f4fd81d759bfb6" + "bytecodeHash": "0x010008d53b584b41e2cb3aa15f79a6eb4273280ce19a7fd5127c0d79c14890f9", + "sourceCodeHash": "0xb85c3e6c03b00d751c328cb9447d56b29bf030ae7e2064c35cc2d0cbc4610997" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x0100095722e18e6831abbece78d3bbaac4fe187db091d6be75d0c6f59aff0f7f", - "sourceCodeHash": "0xac0a99374868ffafa2427f23a7fd1f5f8551402904efbdf84f38638cad00ec14" + "bytecodeHash": "0x010009558349dded3878c1aa4ba39f63b93757abce048d43dde53e732f5d6568", + "sourceCodeHash": "0xbb36c241de8fd9e15b9f3225c42122c3f15b11a4b320fdc0ea69e5b1e108f151" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e75c912d19d915dc90467be59c81c8004271b03639354806f669f14ad3", - "sourceCodeHash": "0x25e4cdb4020792f534611de304297e7e0230ed7ea0510bc049862c2540cc458e" + "bytecodeHash": "0x010008e5dbc05eb7cc68eb07d04f104fec42b84bdecb78bd985c2d361d359817", + "sourceCodeHash": "0x6d8bf101d643f47d98fb2ebf895e5beb378a4ae510a99b3687d3ac2f1fc9763c" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index 85cc33dda..7d080009b 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -11,14 +11,15 @@ object "Bootloader" { // While we definitely cannot control the pubdata price on L1, // we need to check the operator does not provide any absurd numbers there + // These number were chosen to allow for base tokens with low token/eth conversion. function MAX_ALLOWED_FAIR_PUBDATA_PRICE() -> ret { - // 1M gwei - ret := 1000000000000000 + // 2^64 - 1 wei + ret := 18446744073709551615 } function MAX_ALLOWED_FAIR_L2_GAS_PRICE() -> ret { - // 10k gwei - ret := 10000000000000 + // 2^64 - 1 wei + ret := 18446744073709551615 } /// @dev This method ensures that the prices provided by the operator diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 5df2fdd8b..747e79380 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -21,7 +21,7 @@ import {Unauthorized, InvalidCodeHash, CodeHashReason} from "./SystemContractErr * system contracts to enforce the invariants mentioned above. */ contract AccountCodeStorage is IAccountCodeStorage { - bytes32 internal constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + bytes32 private constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; modifier onlyDeployer() { if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { diff --git a/system-contracts/contracts/Compressor.sol b/system-contracts/contracts/Compressor.sol index 73582f639..3cb41b17e 100644 --- a/system-contracts/contracts/Compressor.sol +++ b/system-contracts/contracts/Compressor.sol @@ -3,12 +3,12 @@ pragma solidity 0.8.20; import {ICompressor, OPERATION_BITMASK, LENGTH_BITS_OFFSET, MAX_ENUMERATION_INDEX_SIZE} from "./interfaces/ICompressor.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {Utils} from "./libraries/Utils.sol"; import {UnsafeBytesCalldata} from "./libraries/UnsafeBytesCalldata.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {L1_MESSENGER_CONTRACT, STATE_DIFF_ENTRY_SIZE, KNOWN_CODE_STORAGE_CONTRACT} from "./Constants.sol"; -import {MalformedBytecode, BytecodeError, IndexOutOfBounds, IndexSizeError, ValuesNotEqual, UnsupportedOperation} from "./SystemContractErrors.sol"; +import {DerivedKeyNotEqualToCompressedValue, EncodedAndRealBytecodeChunkNotEqual, DictionaryDividedByEightNotGreaterThanEncodedDividedByTwo, EncodedLengthNotFourTimesSmallerThanOriginal, IndexOutOfBounds, IndexSizeError, UnsupportedOperation, CompressorInitialWritesProcessedNotEqual, CompressorEnumIndexNotEqual, StateDiffLengthMismatch, CompressionValueTransformError, CompressionValueAddError, CompressionValueSubError} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -20,7 +20,7 @@ import {MalformedBytecode, BytecodeError, IndexOutOfBounds, IndexSizeError, Valu * Or the user may compress the bytecode and publish it instead (fewer data onchain!). At the end of every L1 Batch * we publish pubdata, part of which contains the state diffs that occurred within the batch. */ -contract Compressor is ICompressor, ISystemContract { +contract Compressor is ICompressor, SystemContractBase { using UnsafeBytesCalldata for bytes; /// @notice Verify the compressed bytecode and publish it on the L1. @@ -50,13 +50,14 @@ contract Compressor is ICompressor, ISystemContract { (bytes calldata dictionary, bytes calldata encodedData) = _decodeRawBytecode(_rawCompressedData); if (encodedData.length * 4 != _bytecode.length) { - revert MalformedBytecode(BytecodeError.Length); + revert EncodedLengthNotFourTimesSmallerThanOriginal(); } if (dictionary.length / 8 > encodedData.length / 2) { - revert MalformedBytecode(BytecodeError.DictionaryLength); + revert DictionaryDividedByEightNotGreaterThanEncodedDividedByTwo(); } + // We disable this check because calldata array length is cheap. // solhint-disable-next-line gas-length-in-loops for (uint256 encodedDataPointer = 0; encodedDataPointer < encodedData.length; encodedDataPointer += 2) { uint256 indexOfEncodedChunk = uint256(encodedData.readUint16(encodedDataPointer)) * 8; @@ -68,7 +69,7 @@ contract Compressor is ICompressor, ISystemContract { uint64 realChunk = _bytecode.readUint64(encodedDataPointer * 4); if (encodedChunk != realChunk) { - revert ValuesNotEqual(realChunk, encodedChunk); + revert EncodedAndRealBytecodeChunkNotEqual(realChunk, encodedChunk); } } } @@ -143,8 +144,9 @@ contract Compressor is ICompressor, ISystemContract { bytes32 derivedKey = stateDiff.readBytes32(52); uint256 initValue = stateDiff.readUint256(92); uint256 finalValue = stateDiff.readUint256(124); - if (derivedKey != _compressedStateDiffs.readBytes32(stateDiffPtr)) { - revert ValuesNotEqual(uint256(derivedKey), _compressedStateDiffs.readUint256(stateDiffPtr)); + bytes32 compressedDerivedKey = _compressedStateDiffs.readBytes32(stateDiffPtr); + if (derivedKey != compressedDerivedKey) { + revert DerivedKeyNotEqualToCompressedValue(derivedKey, compressedDerivedKey); } stateDiffPtr += 32; @@ -162,7 +164,7 @@ contract Compressor is ICompressor, ISystemContract { } if (numInitialWritesProcessed != numberOfInitialWrites) { - revert ValuesNotEqual(numberOfInitialWrites, numInitialWritesProcessed); + revert CompressorInitialWritesProcessedNotEqual(numberOfInitialWrites, numInitialWritesProcessed); } // Process repeated writes @@ -179,7 +181,7 @@ contract Compressor is ICompressor, ISystemContract { _compressedStateDiffs[stateDiffPtr:stateDiffPtr + _enumerationIndexSize] ); if (enumIndex != compressedEnumIndex) { - revert ValuesNotEqual(enumIndex, compressedEnumIndex); + revert CompressorEnumIndexNotEqual(enumIndex, compressedEnumIndex); } stateDiffPtr += _enumerationIndexSize; @@ -197,7 +199,7 @@ contract Compressor is ICompressor, ISystemContract { } if (stateDiffPtr != _compressedStateDiffs.length) { - revert ValuesNotEqual(stateDiffPtr, _compressedStateDiffs.length); + revert StateDiffLengthMismatch(); } stateDiffHash = EfficientCall.keccak(_stateDiffs); @@ -242,15 +244,15 @@ contract Compressor is ICompressor, ISystemContract { unchecked { if (_operation == 0 || _operation == 3) { if (convertedValue != _finalValue) { - revert ValuesNotEqual(_finalValue, convertedValue); + revert CompressionValueTransformError(_finalValue, convertedValue); } } else if (_operation == 1) { if (_initialValue + convertedValue != _finalValue) { - revert ValuesNotEqual(_finalValue, _initialValue + convertedValue); + revert CompressionValueAddError(_finalValue, _initialValue + convertedValue); } } else if (_operation == 2) { if (_initialValue - convertedValue != _finalValue) { - revert ValuesNotEqual(_finalValue, _initialValue - convertedValue); + revert CompressionValueSubError(_finalValue, _initialValue - convertedValue); } } else { revert UnsupportedOperation(); diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index fde7a5de5..e6c8a06f2 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol"; import {INonceHolder} from "./interfaces/INonceHolder.sol"; diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index 3148de8ff..df8eb11cb 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -9,8 +9,8 @@ import {CREATE2_PREFIX, CREATE_PREFIX, NONCE_HOLDER_SYSTEM_CONTRACT, ACCOUNT_COD import {Utils} from "./libraries/Utils.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; -import {Unauthorized, InvalidNonceOrderingChange, ValuesNotEqual, EmptyBytes32, NotAllowedToDeployInKernelSpace, HashIsNonZero, NonEmptyAccount, UnknownCodeHash, NonEmptyMsgValue} from "./SystemContractErrors.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; +import {Unauthorized, InvalidNonceOrderingChange, ValueMismatch, EmptyBytes32, NotAllowedToDeployInKernelSpace, HashIsNonZero, NonEmptyAccount, UnknownCodeHash, NonEmptyMsgValue} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -21,7 +21,7 @@ import {Unauthorized, InvalidNonceOrderingChange, ValuesNotEqual, EmptyBytes32, * Note, contracts with bytecode that have already been published to L1 once * do not need to be published anymore. */ -contract ContractDeployer is IContractDeployer, ISystemContract { +contract ContractDeployer is IContractDeployer, SystemContractBase { /// @notice Information about an account contract. /// @dev For EOA and simple contracts (i.e. not accounts) this value is 0. mapping(address => AccountInfo) internal accountInfo; @@ -253,7 +253,7 @@ contract ContractDeployer is IContractDeployer, ISystemContract { sumOfValues += _deployments[i].value; } if (msg.value != sumOfValues) { - revert ValuesNotEqual(sumOfValues, msg.value); + revert ValueMismatch(sumOfValues, msg.value); } for (uint256 i = 0; i < deploymentsLength; ++i) { diff --git a/system-contracts/contracts/KnownCodesStorage.sol b/system-contracts/contracts/KnownCodesStorage.sol index efddf5d9c..9ddd18b94 100644 --- a/system-contracts/contracts/KnownCodesStorage.sol +++ b/system-contracts/contracts/KnownCodesStorage.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.20; import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {Utils} from "./libraries/Utils.sol"; import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; import {Unauthorized, MalformedBytecode, BytecodeError} from "./SystemContractErrors.sol"; @@ -16,7 +16,7 @@ import {Unauthorized, MalformedBytecode, BytecodeError} from "./SystemContractEr * the second byte denotes whether the contract is constructed, and the next two bytes denote the length in 32-byte words. * And then the next 28 bytes is the truncated hash. */ -contract KnownCodesStorage is IKnownCodesStorage, ISystemContract { +contract KnownCodesStorage is IKnownCodesStorage, SystemContractBase { modifier onlyCompressor() { if (msg.sender != address(COMPRESSOR_CONTRACT)) { revert Unauthorized(msg.sender); diff --git a/system-contracts/contracts/L1Messenger.sol b/system-contracts/contracts/L1Messenger.sol index 26d49672a..379ab46c9 100644 --- a/system-contracts/contracts/L1Messenger.sol +++ b/system-contracts/contracts/L1Messenger.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.20; import {IL1Messenger, L2ToL1Log, L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L2_TO_L1_LOG_SERIALIZE_SIZE, STATE_DIFF_COMPRESSION_VERSION_NUMBER} from "./interfaces/IL1Messenger.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {Utils} from "./libraries/Utils.sol"; @@ -23,7 +23,7 @@ import {ReconstructionMismatch, PubdataField} from "./SystemContractErrors.sol"; * - The contract on L1 accepts all sent messages and if the message came from this system contract * it requires that the preimage of `value` be provided. */ -contract L1Messenger is IL1Messenger, ISystemContract { +contract L1Messenger is IL1Messenger, SystemContractBase { /// @notice Sequential hash of logs sent in the current block. /// @dev Will be reset at the end of the block to zero value. bytes32 internal chainedLogsHash; @@ -88,7 +88,7 @@ contract L1Messenger is IL1Messenger, ISystemContract { // - at most 1 time keccakGasCost(64) when building the Merkle tree (as merkle tree can contain // ~2*N nodes, where the first N nodes are leaves the hash of which is calculated on the previous step). uint256 gasToPay = keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) + 2 * keccakGasCost(64); - SystemContractHelper.burnGas(Utils.safeCastToU32(gasToPay), 0); + SystemContractHelper.burnGas(Utils.safeCastToU32(gasToPay), uint32(L2_TO_L1_LOG_SERIALIZE_SIZE)); } /// @notice Internal function to send L2ToL1Log. @@ -209,7 +209,7 @@ contract L1Messenger is IL1Messenger, ISystemContract { calldataPtr += 4; bytes32[] memory l2ToL1LogsTreeArray = new bytes32[](L2_TO_L1_LOGS_MERKLE_TREE_LEAVES); - bytes32 reconstructedChainedLogsHash; + bytes32 reconstructedChainedLogsHash = bytes32(0); for (uint256 i = 0; i < numberOfL2ToL1Logs; ++i) { bytes32 hashedLog = EfficientCall.keccak( _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + L2_TO_L1_LOG_SERIALIZE_SIZE] @@ -238,7 +238,7 @@ contract L1Messenger is IL1Messenger, ISystemContract { /// Check messages uint32 numberOfMessages = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); calldataPtr += 4; - bytes32 reconstructedChainedMessagesHash; + bytes32 reconstructedChainedMessagesHash = bytes32(0); for (uint256 i = 0; i < numberOfMessages; ++i) { uint32 currentMessageLength = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); calldataPtr += 4; @@ -255,7 +255,7 @@ contract L1Messenger is IL1Messenger, ISystemContract { /// Check bytecodes uint32 numberOfBytecodes = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); calldataPtr += 4; - bytes32 reconstructedChainedL1BytecodesRevealDataHash; + bytes32 reconstructedChainedL1BytecodesRevealDataHash = bytes32(0); for (uint256 i = 0; i < numberOfBytecodes; ++i) { uint32 currentBytecodeLength = uint32( bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]) diff --git a/system-contracts/contracts/L2BaseToken.sol b/system-contracts/contracts/L2BaseToken.sol index c5b934013..c7b8f134b 100644 --- a/system-contracts/contracts/L2BaseToken.sol +++ b/system-contracts/contracts/L2BaseToken.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.20; import {IBaseToken} from "./interfaces/IBaseToken.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {MSG_VALUE_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS, L1_MESSENGER_CONTRACT} from "./Constants.sol"; import {IMailbox} from "./interfaces/IMailbox.sol"; import {Unauthorized, InsufficientFunds} from "./SystemContractErrors.sol"; @@ -16,7 +16,7 @@ import {Unauthorized, InsufficientFunds} from "./SystemContractErrors.sol"; * Instead, this contract is used by the bootloader and `MsgValueSimulator`/`ContractDeployer` system contracts * to perform the balance changes while simulating the `msg.value` Ethereum behavior. */ -contract L2BaseToken is IBaseToken, ISystemContract { +contract L2BaseToken is IBaseToken, SystemContractBase { /// @notice The balances of the users. mapping(address account => uint256 balance) internal balance; diff --git a/system-contracts/contracts/MsgValueSimulator.sol b/system-contracts/contracts/MsgValueSimulator.sol index 61a221653..00c405942 100644 --- a/system-contracts/contracts/MsgValueSimulator.sol +++ b/system-contracts/contracts/MsgValueSimulator.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.20; import {Utils} from "./libraries/Utils.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, REAL_BASE_TOKEN_SYSTEM_CONTRACT} from "./Constants.sol"; import {InvalidCall} from "./SystemContractErrors.sol"; @@ -17,7 +17,7 @@ import {InvalidCall} from "./SystemContractErrors.sol"; * the address to call in the second extraAbi param, transfers the funds and uses `mimicCall` to continue the * call with the same msg.sender. */ -contract MsgValueSimulator is ISystemContract { +contract MsgValueSimulator is SystemContractBase { /// @notice Extract value, isSystemCall and to from the extraAbi params. /// @dev The contract accepts value, the callee and whether the call should be a system one via its ABI params. /// @dev The first ABI param contains the value in the [0..127] bits. The 128th contains @@ -34,12 +34,12 @@ contract MsgValueSimulator is ISystemContract { } /// @notice The maximal number of gas out of the stipend that should be passed to the callee. - uint256 internal constant GAS_TO_PASS = 2300; + uint256 private constant GAS_TO_PASS = 2300; /// @notice The amount of gas that is passed to the MsgValueSimulator as a stipend. /// This number servers to pay for the ETH transfer as well as to provide gas for the `GAS_TO_PASS` gas. /// It is equal to the following constant: https://github.com/matter-labs/era-zkevm_opcode_defs/blob/7bf8016f5bb13a73289f321ad6ea8f614540ece9/src/system_params.rs#L96. - uint256 internal constant MSG_VALUE_SIMULATOR_STIPEND_GAS = 27000; + uint256 private constant MSG_VALUE_SIMULATOR_STIPEND_GAS = 27000; /// @notice The fallback function that is the main entry point for the MsgValueSimulator. /// @dev The contract accepts value, the callee and whether the call should be a system one via its ABI params. diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol index b769d2d37..2939ee210 100644 --- a/system-contracts/contracts/NonceHolder.sol +++ b/system-contracts/contracts/NonceHolder.sol @@ -4,9 +4,9 @@ pragma solidity 0.8.20; import {INonceHolder} from "./interfaces/INonceHolder.sol"; import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; -import {NonceIncreaseError, ZeroNonceError, NonceJumpError, ValuesNotEqual, NonceAlreadyUsed, NonceNotUsed, Unauthorized} from "./SystemContractErrors.sol"; +import {NonceIncreaseError, ZeroNonceError, NonceJumpError, ValueMismatch, NonceAlreadyUsed, NonceNotUsed, Unauthorized} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -25,7 +25,7 @@ import {NonceIncreaseError, ZeroNonceError, NonceJumpError, ValuesNotEqual, Nonc * @dev The behavior of some of the methods depends on the nonce ordering of the account. Nonce ordering is a mere suggestion and all the checks that are present * here serve more as a help to users to prevent from doing mistakes, rather than any invariants. */ -contract NonceHolder is INonceHolder, ISystemContract { +contract NonceHolder is INonceHolder, SystemContractBase { uint256 private constant DEPLOY_NONCE_MULTIPLIER = 2 ** 128; /// The minNonce can be increased by 2^32 at a time to prevent it from /// overflowing beyond 2**128. @@ -120,7 +120,7 @@ contract NonceHolder is INonceHolder, ISystemContract { (, uint256 oldMinNonce) = _splitRawNonce(oldRawNonce); if (oldMinNonce != _expectedNonce) { - revert ValuesNotEqual(_expectedNonce, oldMinNonce); + revert ValueMismatch(_expectedNonce, oldMinNonce); } unchecked { diff --git a/system-contracts/contracts/PubdataChunkPublisher.sol b/system-contracts/contracts/PubdataChunkPublisher.sol index a096e6900..4ddf35591 100644 --- a/system-contracts/contracts/PubdataChunkPublisher.sol +++ b/system-contracts/contracts/PubdataChunkPublisher.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.20; import {IPubdataChunkPublisher} from "./interfaces/IPubdataChunkPublisher.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {L1_MESSENGER_CONTRACT, BLOB_SIZE_BYTES, MAX_NUMBER_OF_BLOBS, SystemLogKey} from "./Constants.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {TooMuchPubdata} from "./SystemContractErrors.sol"; @@ -12,7 +12,7 @@ import {TooMuchPubdata} from "./SystemContractErrors.sol"; * @custom:security-contact security@matterlabs.dev * @notice Smart contract for chunking pubdata into the appropriate size for EIP-4844 blobs. */ -contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { +contract PubdataChunkPublisher is IPubdataChunkPublisher, SystemContractBase { /// @notice Chunks pubdata into pieces that can fit into blobs. /// @param _pubdata The total l2 to l1 pubdata that will be sent via L1 blobs. /// @dev Note: This is an early implementation, in the future we plan to support up to 16 blobs per l1 batch. diff --git a/system-contracts/contracts/SystemContext.sol b/system-contracts/contracts/SystemContext.sol index a37cf0c19..4f35641c0 100644 --- a/system-contracts/contracts/SystemContext.sol +++ b/system-contracts/contracts/SystemContext.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.20; import {ISystemContext} from "./interfaces/ISystemContext.sol"; -import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {ISystemContextDeprecated} from "./interfaces/ISystemContextDeprecated.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {BOOTLOADER_FORMAL_ADDRESS, SystemLogKey} from "./Constants.sol"; @@ -16,7 +16,7 @@ import {BOOTLOADER_FORMAL_ADDRESS, SystemLogKey} from "./Constants.sol"; * @notice Contract that stores some of the context variables, that may be either * block-scoped, tx-scoped or system-wide. */ -contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContract { +contract SystemContext is ISystemContext, ISystemContextDeprecated, SystemContractBase { /// @notice The number of latest L2 blocks to store. /// @dev EVM requires us to be able to query the hashes of previous 256 blocks. /// We could either: diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol index 5ab4ece43..21d0ae065 100644 --- a/system-contracts/contracts/SystemContractErrors.sol +++ b/system-contracts/contracts/SystemContractErrors.sol @@ -1,50 +1,117 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; -error Unauthorized(address); -error InvalidCodeHash(CodeHashReason); -error UnsupportedTxType(uint256); +// 0x86bb51b8 error AddressHasNoCode(address); -error EncodingLengthMismatch(); -error IndexOutOfBounds(); -error ValuesNotEqual(uint256 expected, uint256 actual); -error HashMismatch(bytes32 expected, uint256 actual); -error IndexSizeError(); -error UnsupportedOperation(); -error InvalidNonceOrderingChange(); +// 0xefce78c7 +error CallerMustBeBootloader(); +// 0xb7549616 +error CallerMustBeForceDeployer(); +// 0x9eedbd2b +error CallerMustBeSystemContract(); +// 0x4f951510 +error CompressionValueAddError(uint256 expected, uint256 actual); +// 0x1e6aff87 +error CompressionValueTransformError(uint256 expected, uint256 actual); +// 0xc2ea251e +error CompressionValueSubError(uint256 expected, uint256 actual); +// 0x849acb7f +error CompressorInitialWritesProcessedNotEqual(uint256 expected, uint256 actual); +// 0x61a6a4b3 +error CompressorEnumIndexNotEqual(uint256 expected, uint256 actual); +// 0x9be48d8d +error DerivedKeyNotEqualToCompressedValue(bytes32 expected, bytes32 provided); +// 0xe223db5e +error DictionaryDividedByEightNotGreaterThanEncodedDividedByTwo(); +// 0x1c25715b error EmptyBytes32(); -error NotAllowedToDeployInKernelSpace(); +// 0x92bf3cf8 +error EmptyVirtualBlocks(); +// 0xc06d5cb2 +error EncodedAndRealBytecodeChunkNotEqual(uint64 expected, uint64 provided); +// 0x2bfbfc11 +error EncodedLengthNotFourTimesSmallerThanOriginal(); +// 0xe95a1fbe +error FailedToChargeGas(); +// 0x1f70c58f +error FailedToPayOperator(); +// 0x9d5da395 +error FirstL2BlockInitializationError(); +// 0x9e4a3c8a error HashIsNonZero(bytes32); -error NonEmptyAccount(); -error UnknownCodeHash(bytes32); -error NonEmptyMsgValue(); +// 0x86302004 +error HashMismatch(bytes32 expected, uint256 actual); +// 0x4e23d035 +error IndexOutOfBounds(); +// 0x122e73e9 +error IndexSizeError(); +// 0x03eb8b54 error InsufficientFunds(uint256 required, uint256 actual); -error InvalidSig(SigField, uint256); -error FailedToPayOperator(); +// 0x1c26714c error InsufficientGas(); -error MalformedBytecode(BytecodeError); -error ReconstructionMismatch(PubdataField, bytes32 expected, bytes32 actual); +// 0xae962d4e error InvalidCall(); +// 0x6a84bc39 +error InvalidCodeHash(CodeHashReason); +// 0xb4fa3fb3 +error InvalidInput(); +// 0x60b85677 +error InvalidNonceOrderingChange(); +// 0x90f049c9 +error InvalidSig(SigField, uint256); +// 0xf4a271b5 +error Keccak256InvalidReturnData(); +// 0xd2906dd9 +error L2BlockMustBeGreaterThanZero(); +// 0x43e266b0 +error MalformedBytecode(BytecodeError); +// 0xe90aded4 +error NonceAlreadyUsed(address account, uint256 nonce); +// 0x45ac24a6 error NonceIncreaseError(uint256 max, uint256 proposed); -error ZeroNonceError(); +// 0x13595475 error NonceJumpError(); -error NonceAlreadyUsed(address account, uint256 nonce); +// 0x1f2f8478 error NonceNotUsed(address account, uint256 nonce); -error TooMuchPubdata(uint256 limit, uint256 supplied); -error UpgradeMustBeFirstTxn(); -error L2BlockMustBeGreaterThanZero(); -error FirstL2BlockInitializationError(); +// 0x760a1568 +error NonEmptyAccount(); +// 0x536ec84b +error NonEmptyMsgValue(); +// 0xd018e08e error NonIncreasingTimestamp(); -error EmptyVirtualBlocks(); -error SystemCallFlagRequired(); -error CallerMustBeSystemContract(); -error CallerMustBeBootloader(); -error CallerMustBeForceDeployer(); -error InvalidData(); -error FailedToChargeGas(); +// 0x50df6bc3 +error NotAllowedToDeployInKernelSpace(); +// 0x35278d12 error Overflow(); -error InvalidInput(); +// 0x7f7b0cf7 +error ReconstructionMismatch(PubdataField, bytes32 expected, bytes32 actual); +// 0x3adb5f1d +error ShaInvalidReturnData(); +// 0xbd8665e2 +error StateDiffLengthMismatch(); +// 0x71c3da01 +error SystemCallFlagRequired(); +// 0xe0456dfe +error TooMuchPubdata(uint256 limit, uint256 supplied); +// 0x8e4a23d6 +error Unauthorized(address); +// 0x3e5efef9 +error UnknownCodeHash(bytes32); +// 0x9ba6061b +error UnsupportedOperation(); +// 0xff15b069 error UnsupportedPaymasterFlow(); +// 0x17a84415 +error UnsupportedTxType(uint256); +// 0x5708aead +error UpgradeMustBeFirstTxn(); +// 0x626ade30 +error ValueMismatch(uint256 expected, uint256 actual); +// 0x460b9939 +error ValuesNotEqual(uint256 expected, uint256 actual); +// 0x6818f3f9 +error ZeroNonceError(); enum CodeHashReason { NotContractOnConstructor, diff --git a/system-contracts/contracts/interfaces/ISystemContract.sol b/system-contracts/contracts/abstract/SystemContractBase.sol similarity index 90% rename from system-contracts/contracts/interfaces/ISystemContract.sol rename to system-contracts/contracts/abstract/SystemContractBase.sol index 1f383a823..bb461df21 100644 --- a/system-contracts/contracts/interfaces/ISystemContract.sol +++ b/system-contracts/contracts/abstract/SystemContractBase.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {SystemContractHelper} from "../libraries/SystemContractHelper.sol"; import {BOOTLOADER_FORMAL_ADDRESS, FORCE_DEPLOYER} from "../Constants.sol"; @@ -15,7 +15,7 @@ import {SystemCallFlagRequired, Unauthorized, CallerMustBeSystemContract, Caller * @dev Never add storage variables into this contract as some * system contracts rely on this abstract contract as on interface! */ -abstract contract ISystemContract { +abstract contract SystemContractBase { /// @notice Modifier that makes sure that the method /// can only be called via a system call. modifier onlySystemCall() { diff --git a/system-contracts/contracts/interfaces/IAccount.sol b/system-contracts/contracts/interfaces/IAccount.sol index c32b35767..dad81b1b2 100644 --- a/system-contracts/contracts/interfaces/IAccount.sol +++ b/system-contracts/contracts/interfaces/IAccount.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {Transaction} from "../libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol index c266774ea..0115393a1 100644 --- a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol +++ b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IAccountCodeStorage { function storeAccountConstructingCodeHash(address _address, bytes32 _hash) external; diff --git a/system-contracts/contracts/interfaces/IBaseToken.sol b/system-contracts/contracts/interfaces/IBaseToken.sol index d15f2f123..b5a4cf912 100644 --- a/system-contracts/contracts/interfaces/IBaseToken.sol +++ b/system-contracts/contracts/interfaces/IBaseToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IBaseToken { function balanceOf(uint256) external view returns (uint256); diff --git a/system-contracts/contracts/interfaces/IBootloaderUtilities.sol b/system-contracts/contracts/interfaces/IBootloaderUtilities.sol index 31413320a..4437c9807 100644 --- a/system-contracts/contracts/interfaces/IBootloaderUtilities.sol +++ b/system-contracts/contracts/interfaces/IBootloaderUtilities.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {Transaction} from "../libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IComplexUpgrader.sol b/system-contracts/contracts/interfaces/IComplexUpgrader.sol index 1b5e15182..8ed670a10 100644 --- a/system-contracts/contracts/interfaces/IComplexUpgrader.sol +++ b/system-contracts/contracts/interfaces/IComplexUpgrader.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/interfaces/ICompressor.sol b/system-contracts/contracts/interfaces/ICompressor.sol index 3062ea4f7..077f30a2b 100644 --- a/system-contracts/contracts/interfaces/ICompressor.sol +++ b/system-contracts/contracts/interfaces/ICompressor.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; // The bitmask by applying which to the compressed state diff metadata we retrieve its operation. uint8 constant OPERATION_BITMASK = 7; diff --git a/system-contracts/contracts/interfaces/IContractDeployer.sol b/system-contracts/contracts/interfaces/IContractDeployer.sol index 3f84672d7..e8ce701eb 100644 --- a/system-contracts/contracts/interfaces/IContractDeployer.sol +++ b/system-contracts/contracts/interfaces/IContractDeployer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IContractDeployer { /// @notice Defines the version of the account abstraction protocol diff --git a/system-contracts/contracts/interfaces/IImmutableSimulator.sol b/system-contracts/contracts/interfaces/IImmutableSimulator.sol index d30ac9b96..cb7027fa1 100644 --- a/system-contracts/contracts/interfaces/IImmutableSimulator.sol +++ b/system-contracts/contracts/interfaces/IImmutableSimulator.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; struct ImmutableData { uint256 index; diff --git a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol index 98a1277d0..39687ddfc 100644 --- a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol +++ b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/interfaces/IL1Messenger.sol b/system-contracts/contracts/interfaces/IL1Messenger.sol index cd0cc90f7..808b5a082 100644 --- a/system-contracts/contracts/interfaces/IL1Messenger.sol +++ b/system-contracts/contracts/interfaces/IL1Messenger.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /// @dev The log passed from L2 /// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter. All other values are not used but are reserved for the future diff --git a/system-contracts/contracts/interfaces/IL2StandardToken.sol b/system-contracts/contracts/interfaces/IL2StandardToken.sol index 3d75c8ede..3439ba3c6 100644 --- a/system-contracts/contracts/interfaces/IL2StandardToken.sol +++ b/system-contracts/contracts/interfaces/IL2StandardToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IL2StandardToken { event BridgeMint(address indexed _account, uint256 _amount); diff --git a/system-contracts/contracts/interfaces/IMailbox.sol b/system-contracts/contracts/interfaces/IMailbox.sol index ba673058c..703612039 100644 --- a/system-contracts/contracts/interfaces/IMailbox.sol +++ b/system-contracts/contracts/interfaces/IMailbox.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; interface IMailbox { function finalizeEthWithdrawal( diff --git a/system-contracts/contracts/interfaces/INonceHolder.sol b/system-contracts/contracts/interfaces/INonceHolder.sol index 1213fbea4..30af5d100 100644 --- a/system-contracts/contracts/interfaces/INonceHolder.sol +++ b/system-contracts/contracts/interfaces/INonceHolder.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/interfaces/IPaymaster.sol b/system-contracts/contracts/interfaces/IPaymaster.sol index 7b06d86ee..68d520eee 100644 --- a/system-contracts/contracts/interfaces/IPaymaster.sol +++ b/system-contracts/contracts/interfaces/IPaymaster.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {Transaction} from "../libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IPaymasterFlow.sol b/system-contracts/contracts/interfaces/IPaymasterFlow.sol index 38866073e..0458c3026 100644 --- a/system-contracts/contracts/interfaces/IPaymasterFlow.sol +++ b/system-contracts/contracts/interfaces/IPaymasterFlow.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol b/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol index 83c1893fd..15faadf66 100644 --- a/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol +++ b/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/interfaces/ISystemContext.sol b/system-contracts/contracts/interfaces/ISystemContext.sol index a122a04f5..9926d197d 100644 --- a/system-contracts/contracts/interfaces/ISystemContext.sol +++ b/system-contracts/contracts/interfaces/ISystemContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol b/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol index a44b61b23..a7f3740be 100644 --- a/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol +++ b/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/libraries/EfficientCall.sol b/system-contracts/contracts/libraries/EfficientCall.sol index 70f33ae5d..8f203b02a 100644 --- a/system-contracts/contracts/libraries/EfficientCall.sol +++ b/system-contracts/contracts/libraries/EfficientCall.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {SystemContractHelper, ADDRESS_MASK} from "./SystemContractHelper.sol"; import {SystemContractsCaller, CalldataForwardingMode, RAW_FAR_CALL_BY_REF_CALL_ADDRESS, SYSTEM_CALL_BY_REF_CALL_ADDRESS, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, MIMIC_CALL_BY_REF_CALL_ADDRESS} from "./SystemContractsCaller.sol"; import {Utils} from "./Utils.sol"; import {SHA256_SYSTEM_CONTRACT, KECCAK256_SYSTEM_CONTRACT, MSG_VALUE_SYSTEM_CONTRACT} from "../Constants.sol"; -import {InvalidData} from "../SystemContractErrors.sol"; +import {Keccak256InvalidReturnData, ShaInvalidReturnData} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -38,7 +38,7 @@ library EfficientCall { function keccak(bytes calldata _data) internal view returns (bytes32) { bytes memory returnData = staticCall(gasleft(), KECCAK256_SYSTEM_CONTRACT, _data); if (returnData.length != 32) { - revert InvalidData(); + revert Keccak256InvalidReturnData(); } return bytes32(returnData); } @@ -49,7 +49,7 @@ library EfficientCall { function sha(bytes calldata _data) internal view returns (bytes32) { bytes memory returnData = staticCall(gasleft(), SHA256_SYSTEM_CONTRACT, _data); if (returnData.length != 32) { - revert InvalidData(); + revert ShaInvalidReturnData(); } return bytes32(returnData); } diff --git a/system-contracts/contracts/libraries/RLPEncoder.sol b/system-contracts/contracts/libraries/RLPEncoder.sol index 7bfbd2a69..b21969731 100644 --- a/system-contracts/contracts/libraries/RLPEncoder.sol +++ b/system-contracts/contracts/libraries/RLPEncoder.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol index 14d29f100..0f832dc79 100644 --- a/system-contracts/contracts/libraries/SystemContractHelper.sol +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; diff --git a/system-contracts/contracts/libraries/SystemContractsCaller.sol b/system-contracts/contracts/libraries/SystemContractsCaller.sol index d964fbbe7..14f361c6f 100644 --- a/system-contracts/contracts/libraries/SystemContractsCaller.sol +++ b/system-contracts/contracts/libraries/SystemContractsCaller.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {MSG_VALUE_SYSTEM_CONTRACT, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT} from "../Constants.sol"; import {Utils} from "./Utils.sol"; @@ -80,7 +80,7 @@ library SystemContractsCaller { assembly { dataStart := add(data, 0x20) } - uint32 dataLength = uint32(Utils.safeCastToU32(data.length)); + uint32 dataLength = Utils.safeCastToU32(data.length); uint256 farCallAbi = SystemContractsCaller.getFarCallABI({ dataOffset: 0, diff --git a/system-contracts/contracts/libraries/TransactionHelper.sol b/system-contracts/contracts/libraries/TransactionHelper.sol index fbdc57919..e34599d39 100644 --- a/system-contracts/contracts/libraries/TransactionHelper.sol +++ b/system-contracts/contracts/libraries/TransactionHelper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {IERC20} from "../openzeppelin/token/ERC20/IERC20.sol"; import {SafeERC20} from "../openzeppelin/token/ERC20/utils/SafeERC20.sol"; diff --git a/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol b/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol index 4ce65f5fb..4c72d3542 100644 --- a/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol +++ b/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /** * @author Matter Labs diff --git a/system-contracts/contracts/libraries/Utils.sol b/system-contracts/contracts/libraries/Utils.sol index 4f535e2c1..b4a843d9b 100644 --- a/system-contracts/contracts/libraries/Utils.sol +++ b/system-contracts/contracts/libraries/Utils.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; import {EfficientCall} from "./EfficientCall.sol"; import {MalformedBytecode, BytecodeError, Overflow} from "../SystemContractErrors.sol"; diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol b/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol index b816bfed0..dc3ad760b 100644 --- a/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol +++ b/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) - +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol b/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol index bb43e53b6..d98bfbce9 100644 --- a/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol +++ b/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) - +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol b/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol index 2ae0c4b0e..2c94d1b59 100644 --- a/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol +++ b/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) - +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; import {IERC20} from "../IERC20.sol"; diff --git a/system-contracts/contracts/openzeppelin/utils/Address.sol b/system-contracts/contracts/openzeppelin/utils/Address.sol index 7a7d2d5d3..9669a9c14 100644 --- a/system-contracts/contracts/openzeppelin/utils/Address.sol +++ b/system-contracts/contracts/openzeppelin/utils/Address.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) - +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.1; /** diff --git a/system-contracts/contracts/test-contracts/AlwaysRevert.sol b/system-contracts/contracts/test-contracts/AlwaysRevert.sol index 902117487..3c9d469ce 100644 --- a/system-contracts/contracts/test-contracts/AlwaysRevert.sol +++ b/system-contracts/contracts/test-contracts/AlwaysRevert.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.20; contract AlwaysRevert { fallback() external { diff --git a/system-contracts/contracts/test-contracts/CodeOracleTest.sol b/system-contracts/contracts/test-contracts/CodeOracleTest.sol index 4db306fb6..f022fb77b 100644 --- a/system-contracts/contracts/test-contracts/CodeOracleTest.sol +++ b/system-contracts/contracts/test-contracts/CodeOracleTest.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.20; address constant REAL_CODE_ORACLE_ADDR = 0x0000000000000000000000000000000000008011; diff --git a/system-contracts/contracts/test-contracts/DelegateCaller.sol b/system-contracts/contracts/test-contracts/DelegateCaller.sol index caa5aae6b..a28cc0167 100644 --- a/system-contracts/contracts/test-contracts/DelegateCaller.sol +++ b/system-contracts/contracts/test-contracts/DelegateCaller.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.20; contract DelegateCaller { function delegateCall(address _to) external payable { diff --git a/system-contracts/contracts/test-contracts/KeccakTest.sol b/system-contracts/contracts/test-contracts/KeccakTest.sol index 19ce77ea1..79581afc4 100644 --- a/system-contracts/contracts/test-contracts/KeccakTest.sol +++ b/system-contracts/contracts/test-contracts/KeccakTest.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.20; pragma abicoder v2; import {LOAD_LATEST_RETURNDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, SystemContractsCaller, CalldataForwardingMode, RAW_FAR_CALL_BY_REF_CALL_ADDRESS} from "../libraries/SystemContractsCaller.sol"; diff --git a/system-contracts/contracts/test-contracts/TransferTest.sol b/system-contracts/contracts/test-contracts/TransferTest.sol index 1342c5a6d..1b9e9bd75 100644 --- a/system-contracts/contracts/test-contracts/TransferTest.sol +++ b/system-contracts/contracts/test-contracts/TransferTest.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.20; contract TransferTest { function transfer(address payable to, uint256 amount, bool warmUpRecipient) public payable { diff --git a/system-contracts/test/Compressor.spec.ts b/system-contracts/test/Compressor.spec.ts index 363be1d13..615ab9211 100644 --- a/system-contracts/test/Compressor.spec.ts +++ b/system-contracts/test/Compressor.spec.ts @@ -58,7 +58,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0002" + "deadbeefdeadbeef" + "0000" + "0000" + "0000" + "0000"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); + ).to.be.revertedWithCustomError(compressor, "EncodedLengthNotFourTimesSmallerThanOriginal"); }); it("should revert when there is no encoded data", async () => { @@ -67,7 +67,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0002" + "deadbeefdeadbeef" + "deadbeefdeadbeef"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); + ).to.be.revertedWithCustomError(compressor, "EncodedLengthNotFourTimesSmallerThanOriginal"); }); it("should revert when the encoded data length is invalid", async () => { @@ -81,7 +81,7 @@ describe("Compressor tests", function () { // The length of the encodedData should be 32 / 4 = 8 bytes await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); + ).to.be.revertedWithCustomError(compressor, "EncodedLengthNotFourTimesSmallerThanOriginal"); }); it("should revert when the dictionary has too many entries", async () => { @@ -102,7 +102,7 @@ describe("Compressor tests", function () { // The dictionary should have at most encode data length entries await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); + ).to.be.revertedWithCustomError(compressor, "DictionaryDividedByEightNotGreaterThanEncodedDividedByTwo"); }); it("should revert when the encoded data has chunks where index is out of bounds", async () => { @@ -123,7 +123,7 @@ describe("Compressor tests", function () { "0x0002" + "deadbeefdeadbeef" + "1111111111111111" + "0001" + "0000" + "0000" + "0001"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "EncodedAndRealBytecodeChunkNotEqual"); }); it("should revert when the bytecode length in bytes is invalid", async () => { @@ -221,7 +221,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(4, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 4, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "DerivedKeyNotEqualToCompressedValue"); }); it("repeated write key mismatch", async () => { @@ -238,7 +238,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(8, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 8, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "CompressorEnumIndexNotEqual"); }); it("no compression value mismatch", async () => { @@ -261,7 +261,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(3, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 3, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "CompressionValueTransformError"); }); it("transform value mismatch", async () => { @@ -284,7 +284,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "CompressionValueTransformError"); }); it("add value mismatch", async () => { @@ -301,7 +301,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "CompressionValueAddError"); }); it("sub value mismatch", async () => { @@ -318,7 +318,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "CompressionValueSubError"); }); it("invalid operation", async () => { @@ -365,7 +365,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "CompressorInitialWritesProcessedNotEqual"); }); it("Extra data in compressed state diffs", async () => { @@ -393,7 +393,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); + ).to.be.revertedWithCustomError(compressor, "StateDiffLengthMismatch"); }); it("successfully verified", async () => { diff --git a/system-contracts/test/NonceHolder.spec.ts b/system-contracts/test/NonceHolder.spec.ts index 4c2ea8738..cbab36d21 100644 --- a/system-contracts/test/NonceHolder.spec.ts +++ b/system-contracts/test/NonceHolder.spec.ts @@ -107,7 +107,7 @@ describe("NonceHolder tests", () => { it("should revert Incorrect nonce", async () => { await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.revertedWithCustomError( nonceHolder, - "ValuesNotEqual" + "ValueMismatch" ); }); diff --git a/yarn.lock b/yarn.lock index 728d64dae..2dfdc5f28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -902,10 +902,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz#bbb43f0e01f40839b0bd38c2c443cb6910ae955f" integrity sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg== -"@nomicfoundation/edr-darwin-arm64@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.5.0.tgz#08b7302c7ce00e3c4dc43e7cfc9065997463c470" - integrity sha512-G6OX/PESdfU4ZOyJ4MDh4eevW0wt2mduuxA+thXtTcStOiQTtPuV205h4kLOR5wRB1Zz6Zy0LedTMax7TzOtGw== +"@nomicfoundation/edr-darwin-arm64@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.5.2.tgz#72f7a826c9f0f2c91308edca562de3b9484ac079" + integrity sha512-Gm4wOPKhbDjGTIRyFA2QUAPfCXA1AHxYOKt3yLSGJkQkdy9a5WW+qtqKeEKHc/+4wpJSLtsGQfpzyIzggFfo/A== "@nomicfoundation/edr-darwin-x64@0.3.7": version "0.3.7" @@ -917,10 +917,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz#b1ffcd9142418fd8498de34a7336b3f977907c86" integrity sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg== -"@nomicfoundation/edr-darwin-x64@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.5.0.tgz#4a30a8584721bffd1ad6d7cc7fb70f2b2034e3b5" - integrity sha512-fI7uHfHqPtdPZjkFUTpotc/F5gGv41ws+jSZy9+2AR9RDMOAIXMEArOx9rGLBcevWu8SFnyH/l/77kG/5FXbDw== +"@nomicfoundation/edr-darwin-x64@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.5.2.tgz#6d0fedb219d664631c6feddc596ab8c3bbc36fa8" + integrity sha512-ClyABq2dFCsrYEED3/UIO0c7p4H1/4vvlswFlqUyBpOkJccr75qIYvahOSJRM62WgUFRhbSS0OJXFRwc/PwmVg== "@nomicfoundation/edr-linux-arm64-gnu@0.3.7": version "0.3.7" @@ -932,10 +932,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz#8173d16d4f6f2b3e82ba7096d2a1ea3619d8bfa7" integrity sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ== -"@nomicfoundation/edr-linux-arm64-gnu@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.5.0.tgz#f4a0e9a5ac8157dc4e241f751c8e8b09f446aa8d" - integrity sha512-eMC3sWPkBZILg2/YB4Xv6IR0nggCLt5hS8K8jjHeGEeUs9pf8poBF2Oy+G4lSu0YLLjexGzHypz9/P+pIuxZHw== +"@nomicfoundation/edr-linux-arm64-gnu@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.5.2.tgz#60e4d52d963141bc2bb4a02639dc590a7fbdda2f" + integrity sha512-HWMTVk1iOabfvU2RvrKLDgtFjJZTC42CpHiw2h6rfpsgRqMahvIlx2jdjWYzFNy1jZKPTN1AStQ/91MRrg5KnA== "@nomicfoundation/edr-linux-arm64-musl@0.3.7": version "0.3.7" @@ -947,10 +947,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz#b1ce293a7c3e0d9f70391e1aef1a82b83b997567" integrity sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg== -"@nomicfoundation/edr-linux-arm64-musl@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.5.0.tgz#34e240a02ebb8d6e0e262642058370f24d555386" - integrity sha512-yPK0tKjYRxe5ktggFr8aBHH0DCI9uafuaD8QuzyrQAfSf/m/ebTdgthROdbYp6eRk5mJyfAQT/45fM3tnlYsWw== +"@nomicfoundation/edr-linux-arm64-musl@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.5.2.tgz#6676a09eab57c435a16ffc144658c896acca9baa" + integrity sha512-CwsQ10xFx/QAD5y3/g5alm9+jFVuhc7uYMhrZAu9UVF+KtVjeCvafj0PaVsZ8qyijjqVuVsJ8hD1x5ob7SMcGg== "@nomicfoundation/edr-linux-x64-gnu@0.3.7": version "0.3.7" @@ -962,10 +962,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz#4c12c4e4bfd3d837f5663ad7cbf7cb6d5634ef83" integrity sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA== -"@nomicfoundation/edr-linux-x64-gnu@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.5.0.tgz#c118f26567eba994133c7fda11a022dee46c5e13" - integrity sha512-Hds8CRYi4DEyuErjcwUNSvNpMzmOYUihW4qYCoKgSBUVS5saX1PyPYvFYuYpeU5J8/T2iMk6yAPVLCxtKbgnKg== +"@nomicfoundation/edr-linux-x64-gnu@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.5.2.tgz#f558d9697ce961410e7a7468f9ab8c8a601b9df6" + integrity sha512-CWVCEdhWJ3fmUpzWHCRnC0/VLBDbqtqTGTR6yyY1Ep3S3BOrHEAvt7h5gx85r2vLcztisu2vlDq51auie4IU1A== "@nomicfoundation/edr-linux-x64-musl@0.3.7": version "0.3.7" @@ -977,10 +977,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz#8842004aa1a47c504f10863687da28b65dca7baa" integrity sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw== -"@nomicfoundation/edr-linux-x64-musl@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.5.0.tgz#b437a652ead59186b566fc2c7a45278018d85806" - integrity sha512-1hXMDSzdyh5ojwO3ZSRbt7t5KKYycGUlFdC3lgJRZ7gStB8xjb7RA3hZn2csn9OydS950Ne4nh+puNq91iXApw== +"@nomicfoundation/edr-linux-x64-musl@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.5.2.tgz#c9c9cbb2997499f75c1d022be724b0551d44569f" + integrity sha512-+aJDfwhkddy2pP5u1ISg3IZVAm0dO836tRlDTFWtvvSMQ5hRGqPcWwlsbobhDQsIxhPJyT7phL0orCg5W3WMeA== "@nomicfoundation/edr-win32-x64-msvc@0.3.7": version "0.3.7" @@ -992,10 +992,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz#29d8bbb2edf9912a95f5453855cf17cdcb269957" integrity sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A== -"@nomicfoundation/edr-win32-x64-msvc@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.5.0.tgz#0dd0eb9c0d6c2f47403393b9712dd8577bd06041" - integrity sha512-CFagD423400xXkRmACIR13FoocN48qi4ogRnuFQIvBDtEE3aMEajfFj4bycmQQDqnqChsZy/jwD4OxbX6oaNJw== +"@nomicfoundation/edr-win32-x64-msvc@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.5.2.tgz#f16db88bf4fe09a996af0a25096e09deecb72bfa" + integrity sha512-CcvvuA3sAv7liFNPsIR/68YlH6rrybKzYttLlMr80d4GKJjwJ5OKb3YgE6FdZZnOfP19HEHhsLcE0DPLtY3r0w== "@nomicfoundation/edr@^0.3.1": version "0.3.7" @@ -1024,17 +1024,17 @@ "@nomicfoundation/edr-win32-x64-msvc" "0.4.0" "@nomicfoundation/edr@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.5.0.tgz#febcce36898ae3e01f04f2013a24b8bec0c2ca24" - integrity sha512-nAUyjGhxntXje/1AkDX9POfH+pqUxdi4XHzIhaf/dJYs7fgAFxL3STBK1OYcA3LR7vtiylLHMz7wxjqLzlLGKg== - dependencies: - "@nomicfoundation/edr-darwin-arm64" "0.5.0" - "@nomicfoundation/edr-darwin-x64" "0.5.0" - "@nomicfoundation/edr-linux-arm64-gnu" "0.5.0" - "@nomicfoundation/edr-linux-arm64-musl" "0.5.0" - "@nomicfoundation/edr-linux-x64-gnu" "0.5.0" - "@nomicfoundation/edr-linux-x64-musl" "0.5.0" - "@nomicfoundation/edr-win32-x64-msvc" "0.5.0" + version "0.5.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.5.2.tgz#e8c7b3d3dd4a312432ab3930dec60f76dc5c4926" + integrity sha512-hW/iLvUQZNTVjFyX/I40rtKvvDOqUEyIi96T28YaLfmPL+3LW2lxmYLUXEJ6MI14HzqxDqrLyhf6IbjAa2r3Dw== + dependencies: + "@nomicfoundation/edr-darwin-arm64" "0.5.2" + "@nomicfoundation/edr-darwin-x64" "0.5.2" + "@nomicfoundation/edr-linux-arm64-gnu" "0.5.2" + "@nomicfoundation/edr-linux-arm64-musl" "0.5.2" + "@nomicfoundation/edr-linux-x64-gnu" "0.5.2" + "@nomicfoundation/edr-linux-x64-musl" "0.5.2" + "@nomicfoundation/edr-win32-x64-msvc" "0.5.2" "@nomicfoundation/ethereumjs-common@4.0.4": version "4.0.4" @@ -1216,12 +1216,12 @@ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" integrity sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg== -"@openzeppelin/contracts-upgradeable@4.9.5": +"@openzeppelin/contracts-upgradeable-v4@npm:@openzeppelin/contracts-upgradeable@4.9.5": version "4.9.5" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.5.tgz#572b5da102fc9be1d73f34968e0ca56765969812" integrity sha512-f7L1//4sLlflAN7fVzJLoRedrf5Na3Oal5PZfIq55NFcVZ90EpV1q5xOvL4lFvg3MNICSDr2hH0JUBxwlxcoPg== -"@openzeppelin/contracts@4.9.5": +"@openzeppelin/contracts-v4@npm:@openzeppelin/contracts@4.9.5": version "4.9.5" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.5.tgz#1eed23d4844c861a1835b5d33507c1017fa98de8" integrity sha512-ZK+W5mVhRppff9BE6YdR8CC52C8zAvsVAiWhEtQ5+oNxFE6h1WdeWo+FJSF8KKvtxxVYZ7MTP/5KoVpAU3aSWg== From 7b488e67a52a3056901c359d8b5fbd3c779c8f83 Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:37:03 +0100 Subject: [PATCH 28/42] chore: foundry config cleanup (#722) --- l1-contracts/foundry.toml | 17 ++++++++++------- l1-contracts/remappings.txt | 7 ------- l2-contracts/foundry.toml | 3 ++- system-contracts/foundry.toml | 4 +++- 4 files changed, 15 insertions(+), 16 deletions(-) delete mode 100644 l1-contracts/remappings.txt diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index 2051dd070..be0511889 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -1,12 +1,15 @@ [profile.default] -src = 'contracts' -out = 'out' -libs = ['node_modules', '../lib'] -cache_path = 'cache-forge' -test = 'test/foundry' +src = "contracts" +out = "out" +libs = ["node_modules", "../lib"] +cache_path = "cache-forge" +test = "test/foundry" solc_version = "0.8.24" evm_version = "cancun" ignored_error_codes = ["missing-receive-ether", "code-size"] ignored_warnings_from = ["test", "contracts/dev-contracts"] - -# See more config options https://github.com/foundry-rs/foundry/tree/master/crates/config +remappings = [ + "forge-std/=../lib/forge-std/src/", + "murky/=../lib/murky/src/", + "foundry-test/=test/foundry/", +] diff --git a/l1-contracts/remappings.txt b/l1-contracts/remappings.txt deleted file mode 100644 index 1b0710cf5..000000000 --- a/l1-contracts/remappings.txt +++ /dev/null @@ -1,7 +0,0 @@ -@ensdomains/=../node_modules/@ensdomains/ -ds-test/=../lib/forge-std/lib/ds-test/src/ -eth-gas-reporter/=../node_modules/eth-gas-reporter/ -forge-std/=../lib/forge-std/src/ -hardhat/=../node_modules/hardhat/ -murky/=../lib/murky/src/ -foundry-test/=test/foundry/ diff --git a/l2-contracts/foundry.toml b/l2-contracts/foundry.toml index fcf297c30..d34805bfe 100644 --- a/l2-contracts/foundry.toml +++ b/l2-contracts/foundry.toml @@ -2,11 +2,12 @@ src = "contracts" out = "out" libs = ["lib"] +cache_path = "cache-forge" +evm_version = "paris" remappings = [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", ] -evm_version = "paris" [profile.default.zksync] zksolc = "1.5.0" diff --git a/system-contracts/foundry.toml b/system-contracts/foundry.toml index 0ab0a20d7..ee3885489 100644 --- a/system-contracts/foundry.toml +++ b/system-contracts/foundry.toml @@ -2,10 +2,12 @@ src = "contracts-preprocessed" out = "out" libs = ["lib"] -evm_version = 'paris' +cache_path = "cache-forge" +evm_version = "paris" remappings = [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", ] + [profile.default.zksync] zksolc = "1.5.0" From 2395aed1fa42821824f6400d491fd73d2b8480e3 Mon Sep 17 00:00:00 2001 From: Nacho Avecilla Date: Fri, 23 Aug 2024 13:30:30 -0300 Subject: [PATCH 29/42] Update solidity contracts version (#688) --- system-contracts/SystemContractsHashes.json | 84 +++++++++---------- .../contracts/AccountCodeStorage.sol | 2 +- .../contracts/BootloaderUtilities.sol | 2 +- .../contracts/ComplexUpgrader.sol | 2 +- system-contracts/contracts/Compressor.sol | 2 +- system-contracts/contracts/Constants.sol | 1 + .../contracts/ContractDeployer.sol | 2 +- system-contracts/contracts/Create2Factory.sol | 2 +- system-contracts/contracts/DefaultAccount.sol | 2 +- system-contracts/contracts/EmptyContract.sol | 2 +- .../contracts/ImmutableSimulator.sol | 2 +- .../contracts/KnownCodesStorage.sol | 2 +- system-contracts/contracts/L1Messenger.sol | 2 +- system-contracts/contracts/L2BaseToken.sol | 2 +- .../contracts/MsgValueSimulator.sol | 2 +- system-contracts/contracts/NonceHolder.sol | 2 +- .../contracts/PubdataChunkPublisher.sol | 2 +- system-contracts/contracts/SystemContext.sol | 2 +- .../contracts/SystemContractErrors.sol | 1 + .../contracts/test-contracts/Deployable.sol | 2 +- .../contracts/test-contracts/MockContract.sol | 2 +- .../contracts/test-contracts/SystemCaller.sol | 2 +- system-contracts/hardhat.config.ts | 3 +- 23 files changed, 65 insertions(+), 62 deletions(-) diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index ab97cd3fe..e70d6c003 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,113 +3,113 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x0100005d64619baff70736b321ae7fc72e6d9f724347b8f122c73ef89d159863", - "sourceCodeHash": "0x5d544ebe1b1d4f99fe4410c9be644cd0b407109e30f632e968b484bf2d456994" + "bytecodeHash": "0x0100005d39637f175e59ed8b149fb5767eaa1e1668ec9e884a13ad656c625748", + "sourceCodeHash": "0xcf59b8e87c4e6a45172938d0f991c301717556141e03a6c43f30db220b4b8093" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007c7288dc176003cc849cf9f416a3044acfb8dc5a765f913aeddeeaa9049", - "sourceCodeHash": "0x26060f33c7c63bd1f8a1a2f3b368b97ef8dd939bc53e95090f2c556248b99dce" + "bytecodeHash": "0x010007c72a6c3838b90ba1574a7f0b9ead2ccc53b7429e94055eb4e29f9cdd62", + "sourceCodeHash": "0x2605e2d28cf99dbde11aa545e7fa9b6343f988b7173283f7dfd54780e9947ce9" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x0100004d0baa3ea2154890efb215a755bb7dc83b1d4ce3d006b7ee915fb3a69c", - "sourceCodeHash": "0xdde7c49a94cc3cd34c3e7ced1b5ba45e4740df68d26243871edbe393e7298f7a" + "bytecodeHash": "0x0100004dee09025db93936ca0913936a6ef363256c2427e7c6c646ea5aeb8631", + "sourceCodeHash": "0x796046a914fb676ba2bbd337b2924311ee2177ce54571c18a2c3945755c83614" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x0100014f56e04fc62384e7b4fcd95886169e81e0baeecb53fd1ed9220302dcf5", - "sourceCodeHash": "0x11646629bb325ba0f343b8d9c99ee60ac847db28841e25e16df8f3d1dd442c7e" + "bytecodeHash": "0x0100014f7c7a4728b9960e1146b1ab129cf4df893f523a45bf2c1a6713ece7be", + "sourceCodeHash": "0xc6f7cd8b21aae52ed3dd5083c09b438a7af142a4ecda6067c586770e8be745a5" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010004e5ae40ac1d3e2a5341f3e9ff1e6f389cc318d34bf6cd3ddb8f24db7b96", - "sourceCodeHash": "0x73056341b4db6b90b6486b36a67b775f857d75641d5759ef7cfa549e1eef5569" + "bytecodeHash": "0x010004e54238d31df887052849f439609045c2f21aa4e311e381be824749da74", + "sourceCodeHash": "0x2b52178555e74f3696f9ae08fdce14c6046c3b18e0f02f0187609ca8a3bba471" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x010000494b831ba9201da08e9996cb88bc85cec3344ff9b17c0d374921cb393e", - "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" + "bytecodeHash": "0x0100004931dda7bd294161ad0ef0e228d4b4afc937cab9af4a2d938935fb6ea0", + "sourceCodeHash": "0x114d9322a9ca654989f3e0b3b21f1311dbc4db84f443d054cd414f6414d84de3" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x0100055d5f308aa35d8b308207f095412dbeac7b09c8bb1845640b1069391255", - "sourceCodeHash": "0xeb5ac8fc83e1c8619db058a9b6973958bd6ed1b6f4938f8f4541d702f12e085d" + "bytecodeHash": "0x0100055da70d970f98ca4677a4b2fcecef5354f345cc5c6d13a78339e5fd87a9", + "sourceCodeHash": "0xebffe840ebbd9329edb1ebff8ca50f6935e7dabcc67194a896fcc2e968d46dfb" }, { "contractName": "EmptyContract", "bytecodePath": "artifacts-zk/contracts-preprocessed/EmptyContract.sol/EmptyContract.json", "sourceCodePath": "contracts-preprocessed/EmptyContract.sol", - "bytecodeHash": "0x0100000781e55a60f3f14fd7dd67e3c8caab896b7b0fca4a662583959299eede", - "sourceCodeHash": "0xc88a4210dda96bc21fc852860fb74a4efeb0cc4101ffe6d928551cab46d15263" + "bytecodeHash": "0x010000078f32964c38fbd138a0369f4723f07ac6f4919c45ef738c18bf874ccd", + "sourceCodeHash": "0xcac36c5afafbcff83601f4fbfdff660aa66d8c80ed97b9322d3011c1926b554d" }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003b4921070b396b98a09369b50a1885e964bcd7bd472954ade597435df9", - "sourceCodeHash": "0x4212e99cbc1722887cfb5b4cb967f278ac8642834786f0e3c6f3b324a9316815" + "bytecodeHash": "0x01000039575b3cb0a5e96a80d89738a7cafa7e7995e7e4857f83c8982f5ff866", + "sourceCodeHash": "0x9659e69f7db09e8f60a8bb95314b1ed26afcc689851665cf27f5408122f60c98" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100006f7cae202a327bc851d670b261ccb186f8914551d3faea3b9f9bf673ba", - "sourceCodeHash": "0x579950be3bcde43a5a4b1f62d8083b10b974bb3e29a3d0108c0bb65235fb15e9" + "bytecodeHash": "0x0100006f232f5cf3c8ffde9230c1af56f3129f69d9851a8d29751613a385418f", + "sourceCodeHash": "0xb39b5b81168653e0c5062f7b8e1d6d15a4e186df3317f192f0cb2fc3a74f5448" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x01000295b3a3343d055aefa650a194f3b8463226d71824c5e46fa3ab0c03b09b", - "sourceCodeHash": "0xf54fae4c1a4bcd0c59e86e3138a5bc3607c9475e14abd0bdc3fcac9ff6b193c5" + "bytecodeHash": "0x010002956ca323790f0c8b855ccc115fe48fa127189d80de464eaf956acda5a3", + "sourceCodeHash": "0xa8768fdaac6d8804782f14e2a51bbe2b6be31dee9103b6d02d149ea8dc46eb6a" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x01000105ed9165628c35526f34a6849d4d292fb49ce0747fea77049e5af7aa8d", - "sourceCodeHash": "0xc9211efcd2b050fbd8a1b6f119eadb61e9a861eea680acc3bbbcae4273f38877" + "bytecodeHash": "0x0100010348a5ee59718d33426818b6d5a20a50efe68aecf7053304aeff82b7aa", + "sourceCodeHash": "0x8bdd2b4d0b53dba84c9f0af250bbaa2aad10b3de6747bba957f0bd3721090dfa" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x0100005dabca233a79399af9da2828d2f37cfd1af346aa34904aefeb93142977", - "sourceCodeHash": "0x2f1ff8df1edb1d3240b62e8ae0e21ed3cce0be12940464d2dbe051d09645ff5f" + "bytecodeHash": "0x0100005d426224423feeefe85bc7c7a02f65d01eb7e088c6978e421d78cfea72", + "sourceCodeHash": "0x082f3dcbc2fe4d93706c86aae85faa683387097d1b676e7ebd00f71ee0f13b71" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000db81f4d732c5f4ca60920dff4b849f330d7f4a61ec61f35df5849d417e", - "sourceCodeHash": "0x32f2f4794ded4d9756b460213d3aea39afece6f4f10e10e2b524c4a5bd92497d" + "bytecodeHash": "0x010000d91567c5bd154d2350868fb366fbb131e51087799cc5da6a7bc9f40a92", + "sourceCodeHash": "0xcd0c0366effebf2c98c58cf96322cc242a2d1c675620ef5514b7ed1f0a869edc" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x0100004772e57643de06b7513a4a823ca2996f954544fc5351feb161f1cd9039", - "sourceCodeHash": "0xc4d42950e01529cb4594ec4637b4b07c993a7f4be17e2afe209439b8511d3de3" + "bytecodeHash": "0x0100004731b1807f406a678ca56a14d29917e2de60fca30cc7fa01169418f3ce", + "sourceCodeHash": "0xd7161e2c8092cf57b43c6220bc605c0e7e540bddcde1af24e2d90f75633b098e" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001a57a8eb66307a7f54e37a90a83b54b8776a5c1ccd503bb6474aa3de620", - "sourceCodeHash": "0x2d075dace38e50e046c723a1bd71b7cc4b8cd3fba20dccdcf3c4ed26b0bcb7b2" + "bytecodeHash": "0x010001a5a3730f0455b91c43e1b4cdd96cbffbdb60c161eb16586908a5e740d8", + "sourceCodeHash": "0xf308743981ef5cea2f7a3332b8e51695a5e47e811a63974437fc1cceee475e7a" }, { "contractName": "EventWriter", @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb3b017071d5d91d0ad424d9e5a31fa6199e80282fa6c85c8af1de0cef", - "sourceCodeHash": "0xeb3ae62b4739a5275c2459336923b005e367eb4292583fc20bde95fc08fea585" + "bytecodeHash": "0x010003cbdea8040793e57c3584e3ef2fd3260caf9244d1ab22a64e8cf890b485", + "sourceCodeHash": "0x8fe3cf367c26e64e8bfb85f7488723bcf229e71ee6685dda6ee6ce9bc7d28cab" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x0100094f3e9b6fdb0b38fce9c15d336e2e4c9896608562978026ce20faa26d4c", - "sourceCodeHash": "0x2ee776cfab86d04d8d847b2e592b6ef6b2fb8ca39e369848d552490aa5a12ece" + "bytecodeHash": "0x0100094fe95a0ee1b8b9a86befeb23939f5036a69a5808235e058e1af1e935d8", + "sourceCodeHash": "0x6071a22c177ad6ed84a6d8a283eb3272dbb127da394417c11fb94056dfcce3cc" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d53b584b41e2cb3aa15f79a6eb4273280ce19a7fd5127c0d79c14890f9", - "sourceCodeHash": "0xb85c3e6c03b00d751c328cb9447d56b29bf030ae7e2064c35cc2d0cbc4610997" + "bytecodeHash": "0x010008d5319bd1a8c92f7519824ca73c6b993930a68982b205ad9cce2b50e147", + "sourceCodeHash": "0x0d08c8894d54a6498ae0ffbc10816439652c1b43022a77364b9aa4df91cd3ba5" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x010009558349dded3878c1aa4ba39f63b93757abce048d43dde53e732f5d6568", - "sourceCodeHash": "0xbb36c241de8fd9e15b9f3225c42122c3f15b11a4b320fdc0ea69e5b1e108f151" + "bytecodeHash": "0x0100095541c24966c34984d5521cb7a06263eb4715205f5632a6d5f596010c24", + "sourceCodeHash": "0x5a8ba82172223403a83ec95be070c87ec9bf931898f4df2091c93535fefd8223" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e5dbc05eb7cc68eb07d04f104fec42b84bdecb78bd985c2d361d359817", - "sourceCodeHash": "0x6d8bf101d643f47d98fb2ebf895e5beb378a4ae510a99b3687d3ac2f1fc9763c" + "bytecodeHash": "0x010008e50a84cb5e11b650d08b8040a90cd42203490f09362e5e39f1925234aa", + "sourceCodeHash": "0x2c4178f33c0c8ac6402d0f9f53c01c3a143c4d789cf97ba491ae590c4515a2b0" } ] diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 747e79380..03a128ad6 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol"; import {Utils} from "./libraries/Utils.sol"; diff --git a/system-contracts/contracts/BootloaderUtilities.sol b/system-contracts/contracts/BootloaderUtilities.sol index 0aafee7be..384f6a121 100644 --- a/system-contracts/contracts/BootloaderUtilities.sol +++ b/system-contracts/contracts/BootloaderUtilities.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IBootloaderUtilities} from "./interfaces/IBootloaderUtilities.sol"; import {Transaction, TransactionHelper, EIP_712_TX_TYPE, LEGACY_TX_TYPE, EIP_2930_TX_TYPE, EIP_1559_TX_TYPE} from "./libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/ComplexUpgrader.sol b/system-contracts/contracts/ComplexUpgrader.sol index 009e8994d..a69545148 100644 --- a/system-contracts/contracts/ComplexUpgrader.sol +++ b/system-contracts/contracts/ComplexUpgrader.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol"; import {FORCE_DEPLOYER} from "./Constants.sol"; diff --git a/system-contracts/contracts/Compressor.sol b/system-contracts/contracts/Compressor.sol index 3cb41b17e..d4c52f989 100644 --- a/system-contracts/contracts/Compressor.sol +++ b/system-contracts/contracts/Compressor.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {ICompressor, OPERATION_BITMASK, LENGTH_BITS_OFFSET, MAX_ENUMERATION_INDEX_SIZE} from "./interfaces/ICompressor.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index e6c8a06f2..6be56db16 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT + // We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index df8eb11cb..a61eae096 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {ImmutableData} from "./interfaces/IImmutableSimulator.sol"; import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; diff --git a/system-contracts/contracts/Create2Factory.sol b/system-contracts/contracts/Create2Factory.sol index 6f68fbb52..868de66fa 100644 --- a/system-contracts/contracts/Create2Factory.sol +++ b/system-contracts/contracts/Create2Factory.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {REAL_DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; diff --git a/system-contracts/contracts/DefaultAccount.sol b/system-contracts/contracts/DefaultAccount.sol index ff62e9a57..40a38e49b 100644 --- a/system-contracts/contracts/DefaultAccount.sol +++ b/system-contracts/contracts/DefaultAccount.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IAccount, ACCOUNT_VALIDATION_SUCCESS_MAGIC} from "./interfaces/IAccount.sol"; import {TransactionHelper, Transaction} from "./libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/EmptyContract.sol b/system-contracts/contracts/EmptyContract.sol index 3f021964a..15516a7b3 100644 --- a/system-contracts/contracts/EmptyContract.sol +++ b/system-contracts/contracts/EmptyContract.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; /** * @author Matter Labs diff --git a/system-contracts/contracts/ImmutableSimulator.sol b/system-contracts/contracts/ImmutableSimulator.sol index 701ee5d90..93110d782 100644 --- a/system-contracts/contracts/ImmutableSimulator.sol +++ b/system-contracts/contracts/ImmutableSimulator.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IImmutableSimulator, ImmutableData} from "./interfaces/IImmutableSimulator.sol"; import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; diff --git a/system-contracts/contracts/KnownCodesStorage.sol b/system-contracts/contracts/KnownCodesStorage.sol index 9ddd18b94..31fa04734 100644 --- a/system-contracts/contracts/KnownCodesStorage.sol +++ b/system-contracts/contracts/KnownCodesStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; diff --git a/system-contracts/contracts/L1Messenger.sol b/system-contracts/contracts/L1Messenger.sol index 379ab46c9..f9578b19b 100644 --- a/system-contracts/contracts/L1Messenger.sol +++ b/system-contracts/contracts/L1Messenger.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IL1Messenger, L2ToL1Log, L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L2_TO_L1_LOG_SERIALIZE_SIZE, STATE_DIFF_COMPRESSION_VERSION_NUMBER} from "./interfaces/IL1Messenger.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; diff --git a/system-contracts/contracts/L2BaseToken.sol b/system-contracts/contracts/L2BaseToken.sol index c7b8f134b..9f826a80b 100644 --- a/system-contracts/contracts/L2BaseToken.sol +++ b/system-contracts/contracts/L2BaseToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IBaseToken} from "./interfaces/IBaseToken.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; diff --git a/system-contracts/contracts/MsgValueSimulator.sol b/system-contracts/contracts/MsgValueSimulator.sol index 00c405942..5fcd0f2d9 100644 --- a/system-contracts/contracts/MsgValueSimulator.sol +++ b/system-contracts/contracts/MsgValueSimulator.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {Utils} from "./libraries/Utils.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol index 2939ee210..cca07b1b4 100644 --- a/system-contracts/contracts/NonceHolder.sol +++ b/system-contracts/contracts/NonceHolder.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {INonceHolder} from "./interfaces/INonceHolder.sol"; import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; diff --git a/system-contracts/contracts/PubdataChunkPublisher.sol b/system-contracts/contracts/PubdataChunkPublisher.sol index 4ddf35591..9402f05a6 100644 --- a/system-contracts/contracts/PubdataChunkPublisher.sol +++ b/system-contracts/contracts/PubdataChunkPublisher.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IPubdataChunkPublisher} from "./interfaces/IPubdataChunkPublisher.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; diff --git a/system-contracts/contracts/SystemContext.sol b/system-contracts/contracts/SystemContext.sol index 4f35641c0..4763b4153 100644 --- a/system-contracts/contracts/SystemContext.sol +++ b/system-contracts/contracts/SystemContext.sol @@ -2,7 +2,7 @@ // solhint-disable reason-string, gas-custom-errors -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {ISystemContext} from "./interfaces/ISystemContext.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol index 21d0ae065..f95879643 100644 --- a/system-contracts/contracts/SystemContractErrors.sol +++ b/system-contracts/contracts/SystemContractErrors.sol @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT + // We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; diff --git a/system-contracts/contracts/test-contracts/Deployable.sol b/system-contracts/contracts/test-contracts/Deployable.sol index be35861a4..8178eadb4 100644 --- a/system-contracts/contracts/test-contracts/Deployable.sol +++ b/system-contracts/contracts/test-contracts/Deployable.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; contract Deployable { event Deployed(uint256 value, bytes data); diff --git a/system-contracts/contracts/test-contracts/MockContract.sol b/system-contracts/contracts/test-contracts/MockContract.sol index 1505be34c..b7d9bcb55 100644 --- a/system-contracts/contracts/test-contracts/MockContract.sol +++ b/system-contracts/contracts/test-contracts/MockContract.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; contract MockContract { event Called(uint256 value, bytes data); diff --git a/system-contracts/contracts/test-contracts/SystemCaller.sol b/system-contracts/contracts/test-contracts/SystemCaller.sol index a377174ae..b51caec0b 100644 --- a/system-contracts/contracts/test-contracts/SystemCaller.sol +++ b/system-contracts/contracts/test-contracts/SystemCaller.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {SYSTEM_CALL_CALL_ADDRESS, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, SystemContractsCaller, CalldataForwardingMode} from "../libraries/SystemContractsCaller.sol"; import {Utils} from "../libraries/Utils.sol"; diff --git a/system-contracts/hardhat.config.ts b/system-contracts/hardhat.config.ts index 68550e6c3..7ad59a41f 100644 --- a/system-contracts/hardhat.config.ts +++ b/system-contracts/hardhat.config.ts @@ -34,8 +34,9 @@ export default { ethNetwork: "http://localhost:8545", }, solidity: { - version: "0.8.20", + version: "0.8.24", settings: { + evmVersion: "cancun", optimizer: { enabled: true, runs: 9999999, From a36c6c2f34894b892d36d408c1cc769dc44c1911 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Wed, 28 Aug 2024 10:05:35 +0200 Subject: [PATCH 30/42] chore(config): Fix server build with symlinks (#740) Co-authored-by: Zach Kolodny --- .eslintrc | 3 +- l1-contracts/foundry.toml | 13 ++++ .../lib/openzeppelin-contracts-upgradeable-v4 | 1 + l1-contracts/lib/openzeppelin-contracts-v4 | 1 + system-contracts/SystemContractsHashes.json | 20 +++--- system-contracts/bootloader/bootloader.yul | 61 ------------------- 6 files changed, 27 insertions(+), 72 deletions(-) create mode 120000 l1-contracts/lib/openzeppelin-contracts-upgradeable-v4 create mode 120000 l1-contracts/lib/openzeppelin-contracts-v4 diff --git a/.eslintrc b/.eslintrc index 077931cae..d8474e32a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,6 +11,7 @@ "no-console": "off" }, "ignorePatterns": [ - "**/lib/*" + "**/lib/*", + "lib/*" ] } diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index be0511889..04fd5c656 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -6,10 +6,23 @@ cache_path = "cache-forge" test = "test/foundry" solc_version = "0.8.24" evm_version = "cancun" +allow_paths = ["../l2-contracts/contracts"] +fs_permissions = [ + { access = "read", path = "../system-contracts/bootloader/build/artifacts" }, + { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed" }, + { access = "read", path = "../l2-contracts/artifacts-zk/" }, + { access = "read", path = "../l2-contracts/zkout/" }, + { access = "read", path = "../system-contracts/zkout/" }, + { access = "read", path = "./script-config" }, + { access = "read-write", path = "./script-out" }, + { access = "read", path = "./out" } +] ignored_error_codes = ["missing-receive-ether", "code-size"] ignored_warnings_from = ["test", "contracts/dev-contracts"] remappings = [ "forge-std/=../lib/forge-std/src/", "murky/=../lib/murky/src/", "foundry-test/=test/foundry/", + "@openzeppelin/contracts-v4/=./lib/openzeppelin-contracts-v4/contracts/", + "@openzeppelin/contracts-upgradeable-v4/=./lib/openzeppelin-contracts-upgradeable-v4/contracts/", ] diff --git a/l1-contracts/lib/openzeppelin-contracts-upgradeable-v4 b/l1-contracts/lib/openzeppelin-contracts-upgradeable-v4 new file mode 120000 index 000000000..0551b6016 --- /dev/null +++ b/l1-contracts/lib/openzeppelin-contracts-upgradeable-v4 @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-upgradeable-v4 \ No newline at end of file diff --git a/l1-contracts/lib/openzeppelin-contracts-v4 b/l1-contracts/lib/openzeppelin-contracts-v4 new file mode 120000 index 000000000..693e94537 --- /dev/null +++ b/l1-contracts/lib/openzeppelin-contracts-v4 @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-v4 \ No newline at end of file diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index e70d6c003..9d17edc7d 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cbdea8040793e57c3584e3ef2fd3260caf9244d1ab22a64e8cf890b485", - "sourceCodeHash": "0x8fe3cf367c26e64e8bfb85f7488723bcf229e71ee6685dda6ee6ce9bc7d28cab" + "bytecodeHash": "0x010003cb94018874dce8c4f3b254625cffc7032c37f85c6b743d30cbac87c934", + "sourceCodeHash": "0x42b9c4235bd0b3de0beff158d7d848381990c55907daeaa3a9c8b6d66b53c0f3" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x0100094fe95a0ee1b8b9a86befeb23939f5036a69a5808235e058e1af1e935d8", - "sourceCodeHash": "0x6071a22c177ad6ed84a6d8a283eb3272dbb127da394417c11fb94056dfcce3cc" + "bytecodeHash": "0x0100092dd79e0d7171d5dfe246e20c2d3f2d8b1ba8104ba1199e0c1a4b8af9ef", + "sourceCodeHash": "0xe538d080f0071f7f31ab1ea013fccec31560450d67e2859257d627100a5fcd07" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d5319bd1a8c92f7519824ca73c6b993930a68982b205ad9cce2b50e147", - "sourceCodeHash": "0x0d08c8894d54a6498ae0ffbc10816439652c1b43022a77364b9aa4df91cd3ba5" + "bytecodeHash": "0x010008b3ffe296bc8b565f555fa15f8aca08d9b88f5b06c15d72094cf5d779b6", + "sourceCodeHash": "0xcc36539d29f136bccd80fea0c3f9976cfc9e238972930b2aca98e6ad2e38fd1c" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x0100095541c24966c34984d5521cb7a06263eb4715205f5632a6d5f596010c24", - "sourceCodeHash": "0x5a8ba82172223403a83ec95be070c87ec9bf931898f4df2091c93535fefd8223" + "bytecodeHash": "0x010009339296f1ba9bd8b81e7152125a8286c4e7f9c3e194e35fc325a9e5c7d2", + "sourceCodeHash": "0xaac0c38a7b033eec41e2533c04b3541099c0c6ee70eb4acd8eea69edd1ef936a" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e50a84cb5e11b650d08b8040a90cd42203490f09362e5e39f1925234aa", - "sourceCodeHash": "0x2c4178f33c0c8ac6402d0f9f53c01c3a143c4d789cf97ba491ae590c4515a2b0" + "bytecodeHash": "0x010008c37ecadea8b003884eb9d81fdfb7161b3b309504e5318f15da19c500d8", + "sourceCodeHash": "0x64618bc0fd4affe7fd2a0fa6a5a16d16be2df194bbe3e0ad6d54f1878a4a6d95" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index 7d080009b..e5daed9e0 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -692,63 +692,6 @@ object "Bootloader" { ret := mload(0) } - /// @dev The function that is temporarily needed to upgrade the SystemContext system contract. This function is to be removed - /// once the upgrade is complete. - /// @dev Checks whether the code hash of the SystemContext contract is correct and updates it if needed. - /// @dev The bootloader calls `setPubdataInfo` before each transaction, including the upgrade one. - /// However, the old SystemContext does not have this method. So the bootloader should invoke this function - /// before starting any transaction. - function upgradeSystemContextIfNeeded() { - let expectedCodeHash := {{SYSTEM_CONTEXT_EXPECTED_CODE_HASH}} - - let actualCodeHash := getRawCodeHash(SYSTEM_CONTEXT_ADDR(), true) - if iszero(eq(expectedCodeHash, actualCodeHash)) { - // Now, we need to encode the call to the `ContractDeployer.forceDeployOnAddresses()` function. - - // The `mimicCallOnlyResult` requires that the first word of the data - // contains its length. Here it is 292 bytes. - mstore(0, 292) - mstore(32, {{PADDED_FORCE_DEPLOY_ON_ADDRESSES_SELECTOR}}) - - // The 0x20 offset, for the array of forced deployments - mstore(36, 0x0000000000000000000000000000000000000000000000000000000000000020) - // Only one force deployment - mstore(68, 0x0000000000000000000000000000000000000000000000000000000000000001) - - // Now, starts the description of the forced deployment itself. - // Firstly, the offset. - mstore(100, 0x0000000000000000000000000000000000000000000000000000000000000020) - // The new hash of the SystemContext contract. - mstore(132, expectedCodeHash) - // The address of the system context - mstore(164, SYSTEM_CONTEXT_ADDR()) - // The constructor must be called to reset the `blockGasLimit` variable - mstore(196, 0x0000000000000000000000000000000000000000000000000000000000000001) - // The value should be 0. - mstore(228, 0x0000000000000000000000000000000000000000000000000000000000000000) - // The offset of the input array. - mstore(260, 0x00000000000000000000000000000000000000000000000000000000000000a0) - // No input is provided, the array is empty. - mstore(292, 0x0000000000000000000000000000000000000000000000000000000000000000) - - // We'll use a mimicCall to simulate the correct sender. - let success := mimicCallOnlyResult( - CONTRACT_DEPLOYER_ADDR(), - FORCE_DEPLOYER(), - 0, - 0, - 0, - 0, - 0, - 0 - ) - - if iszero(success) { - assertionError("system context upgrade fail") - } - } - } - /// @dev Calculates the canonical hash of the L1->L2 transaction that will be /// sent to L1 as a message to the L1 contract that a certain operation has been processed. function getCanonicalL1TxHash(txDataOffset) -> ret { @@ -4019,8 +3962,6 @@ object "Bootloader" { assertionError("baseFee inconsistent") } - upgradeSystemContextIfNeeded() - setNewBatch(PREV_BATCH_HASH, NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) @@ -4029,8 +3970,6 @@ object "Bootloader" { let SHOULD_SET_NEW_BATCH := mload(224) - upgradeSystemContextIfNeeded() - switch SHOULD_SET_NEW_BATCH case 0 { unsafeOverrideBatch(NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) From 8d9240f54e29fe6e842f2bcb63f9159f00686e54 Mon Sep 17 00:00:00 2001 From: Dima Zhornyk <55756184+dimazhornyk@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:31:09 +0200 Subject: [PATCH 31/42] feat: add a script to prepare chain registration calldata (#671) --- .gitignore | 1 + .../config-prepare-registration-calldata.toml | 12 + .../PrepareZKChainRegistrationCalldata.s.sol | 366 ++++++++++++++++++ .../script-config/artifacts/BeaconProxy.json | 81 ++++ .../artifacts/L2SharedBridge.json | 262 +++++++++++++ .../TransparentUpgradeableProxy.json | 86 ++++ 6 files changed, 808 insertions(+) create mode 100644 l1-contracts/deploy-script-config-template/config-prepare-registration-calldata.toml create mode 100644 l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol create mode 100644 l1-contracts/script-config/artifacts/BeaconProxy.json create mode 100644 l1-contracts/script-config/artifacts/L2SharedBridge.json create mode 100644 l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json diff --git a/.gitignore b/.gitignore index 1897dead9..21c173828 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ l1-contracts/coverage/* l1-contracts/out/* l1-contracts/broadcast/* l1-contracts/script-config/* +!l1-contracts/script-config/artifacts l1-contracts/script-out/* !l1-contracts/script-out/.gitkeep *.timestamp diff --git a/l1-contracts/deploy-script-config-template/config-prepare-registration-calldata.toml b/l1-contracts/deploy-script-config-template/config-prepare-registration-calldata.toml new file mode 100644 index 000000000..99ff2e7ce --- /dev/null +++ b/l1-contracts/deploy-script-config-template/config-prepare-registration-calldata.toml @@ -0,0 +1,12 @@ +[deployed_addresses] +state_transition_proxy_addr = "0x635853efd1d388f597feb9fe06e666efda397911" +erc20_bridge_proxy_addr = "0x147CDc5DD347bA141545Ad08fce748484Ed7fDbA" + + +[chain] +chain_id = 123 +era_chain_id = 9 +admin = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +diamond_cut_data = "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000cf3cd7fa8948f7748d20f7f33e85a0320b6c5d4d0000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000a200000000000000000000000003fe9b8f276c1a2e26d2190f2d9fd1897a04eb90a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000d0e18b681000000000000000000000000000000000000000000000000000000001733894500000000000000000000000000000000000000000000000000000000fc57565f000000000000000000000000000000000000000000000000000000001cc5d1030000000000000000000000000000000000000000000000000000000021f603d700000000000000000000000000000000000000000000000000000000235d9eb50000000000000000000000000000000000000000000000000000000027ae4c16000000000000000000000000000000000000000000000000000000004623c91d000000000000000000000000000000000000000000000000000000004dd18bf50000000000000000000000000000000000000000000000000000000064bf8d6600000000000000000000000000000000000000000000000000000000a9f6d94100000000000000000000000000000000000000000000000000000000be6f11cf00000000000000000000000000000000000000000000000000000000e76db865000000000000000000000000000000000000000000000000000000000000000000000000000000000e70df06c0938e724ce23e49b3c4f01abed6bbfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000002906d49e5b00000000000000000000000000000000000000000000000000000000086a56f8000000000000000000000000000000000000000000000000000000000ec6b0b700000000000000000000000000000000000000000000000000000000fe26699e0000000000000000000000000000000000000000000000000000000018e3a941000000000000000000000000000000000000000000000000000000001de72e340000000000000000000000000000000000000000000000000000000029b98c670000000000000000000000000000000000000000000000000000000033ce93fe000000000000000000000000000000000000000000000000000000003591c1a000000000000000000000000000000000000000000000000000000000396073820000000000000000000000000000000000000000000000000000000046657fe90000000000000000000000000000000000000000000000000000000052ef6b2c000000000000000000000000000000000000000000000000000000005518c73b0000000000000000000000000000000000000000000000000000000056142d7a00000000000000000000000000000000000000000000000000000000631f4bac000000000000000000000000000000000000000000000000000000006e9960c30000000000000000000000000000000000000000000000000000000074f4d30d0000000000000000000000000000000000000000000000000000000079823c9a000000000000000000000000000000000000000000000000000000007a0ed627000000000000000000000000000000000000000000000000000000007b30c8da0000000000000000000000000000000000000000000000000000000098acd7a6000000000000000000000000000000000000000000000000000000009cd939e4000000000000000000000000000000000000000000000000000000009d1b5a8100000000000000000000000000000000000000000000000000000000a1954fc500000000000000000000000000000000000000000000000000000000adfca15e00000000000000000000000000000000000000000000000000000000af6a2dcd00000000000000000000000000000000000000000000000000000000b22dd78e00000000000000000000000000000000000000000000000000000000b8c2f66f00000000000000000000000000000000000000000000000000000000bd7c541200000000000000000000000000000000000000000000000000000000c3bbd2d700000000000000000000000000000000000000000000000000000000cdffacc600000000000000000000000000000000000000000000000000000000d046815600000000000000000000000000000000000000000000000000000000d86970d800000000000000000000000000000000000000000000000000000000db1f0bf900000000000000000000000000000000000000000000000000000000e5355c7500000000000000000000000000000000000000000000000000000000e81e0ba100000000000000000000000000000000000000000000000000000000ea6c029c00000000000000000000000000000000000000000000000000000000ef3f0bae00000000000000000000000000000000000000000000000000000000f5c1182c00000000000000000000000000000000000000000000000000000000facd743b00000000000000000000000000000000000000000000000000000000fd791f3c000000000000000000000000000000000000000000000000000000000000000000000000000000006e2e077311fb218b80404298c9a227c42b792b610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008042901c70000000000000000000000000000000000000000000000000000000012f43dab00000000000000000000000000000000000000000000000000000000eb67241900000000000000000000000000000000000000000000000000000000263b7f8e000000000000000000000000000000000000000000000000000000006c0960f900000000000000000000000000000000000000000000000000000000b473318e00000000000000000000000000000000000000000000000000000000c924de3500000000000000000000000000000000000000000000000000000000e4948f4300000000000000000000000000000000000000000000000000000000000000000000000000000000a226529de193f2153b25d7d9ad774689b78c301e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000080f23da4300000000000000000000000000000000000000000000000000000000c3d93e7c000000000000000000000000000000000000000000000000000000006edd4f12000000000000000000000000000000000000000000000000000000006f497ac600000000000000000000000000000000000000000000000000000000701f58c5000000000000000000000000000000000000000000000000000000007f61885c0000000000000000000000000000000000000000000000000000000097c09d3400000000000000000000000000000000000000000000000000000000c37533bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000007bd175a72991f0a30ed333eaf1cb215c42e7492c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e3200000000000000000000000000000000000000000000000000000000044aa200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000001d4c00000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000000000182b8000000000000000000000000000000000000000000000000000000000ee6b280000000000000000000000000baa109e4e90cc08a3c5069a0173aace4e934d57e" +bridgehub_create_new_chain_salt = 0 +base_token_addr = "0x0000000000000000000000000000000000000001" diff --git a/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol b/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol new file mode 100644 index 000000000..3810805c8 --- /dev/null +++ b/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol @@ -0,0 +1,366 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +// solhint-disable no-console + +import {Script, console2 as console} from "forge-std/Script.sol"; +import {stdToml} from "forge-std/StdToml.sol"; + +import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; +import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; +import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; +import {AddressAliasHelper} from "contracts/vendor/AddressAliasHelper.sol"; +import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; +import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; +import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {Utils} from "./Utils.sol"; + +/** + * @title Prepare ZKChain Registration Calldata + * @dev Script to prepare calldata for registering a new ZKChain on the bridgehub + * + * This script prepares calldata for registering a new ZKChain on the bridgehub + * That includes 3 steps: + * 1. Register base token on the bridgehub + * 2. Register the new ZKChain on the bridgehub + * 3. Initialize the L2 bridge on the L1 shared bridge + * + * The script precomputes the address of the L2 bridge to generate the calldata for the third step. + * It assumes that L1 governance is the owner of the L2 bridge and the L2 bridge is deployed by the msg.sender of the script. + * + * The script reads the configuration from a TOML file `script-config/prepare-registration-calldata.toml` + * and writes the output to a TOML file `script-out/output-prepare-registration-calldata.toml`. + * + * The output contains 4 fields: + * - scheduleCalldataStageOne: calldata for scheduling the first stage + * - executeCalldataStageOne: calldata for executing the first stage + * - scheduleCalldataStageTwo: calldata for scheduling the second stage + * - executeCalldataStageTwo: calldata for executing the second stage + * (stage 2 of the execution is the registration of the L2 bridge on the L1 shared bridge) + * + * The separation is required to ensure that there is no period of time where the L2 bridge is registered, so users + * can send their funds there, but they will be burned in case L2 bridge is not initialized by the chain operator. + * It is meant to be executed only after the L2 bridge is deployed. + * + * How to use: + * 1. Create a TOML file `script-config/prepare-registration-calldata.toml`, reference config at `deploy-script-config-template/config-prepare-registration-calldata.toml`. + * 2. Run the script impersonating the address that will deploy the L2 bridge, `forge script --rpc-url $RPC --sender $DEPLOYER PrepareZKChainRegistrationCalldata.s.sol` + * 3. Run the `scheduleCalldataStageOne` and `executeCalldataStageOne` on the L1 chain using governance. + * 4. Deploy the L2 bridge using the address from step 2. This address doesn't need any special permissions, just has to be consistent across all the stages. + * 5. Run the `scheduleCalldataStageTwo` and `executeCalldataStageTwo` on the L1 chain using governance. + * + */ +contract PrepareZKChainRegistrationCalldataScript is Script { + using stdToml for string; + + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + + struct Config { + // Admin of the yet-to-be-registered chain (L1-based address) + address chainAdmin; + // STM proxy address + address stateTransitionProxy; + // Chain ID of the new chain + uint256 chainId; + // Chain ID of the era (required for the L2 bridge deployment) + uint256 eraChainId; + // Salt for createNewChain call, also used as a governance operation salt + uint256 bridgehubCreateNewChainSalt; + // Address of the new chain's base token + address baseToken; + // Diamond cut data is a "configuration" for the Diamond proxy that will be created for a new chain. + // It can only be the one that's allowed by the STM. It can be generated by the other scripts or taken from the + // `etc/env/ecosystems/ENV.yaml` file in `zksync-era` repository + bytes diamondCutData; + // Address of the L1 ERC20 bridge proxy (required for the L2 bridge deployment) + address erc20BridgeProxy; + } + + // Addresses of the contracts in the L1 ecosystem that are fetched from the chain + struct EcosystemContracts { + // Address of the L1 shared bridge proxy + address l1SharedBridgeProxy; + // Bridgehub proxy address + address bridgehub; + // Address of the governance contract for the L1 ecosystem + address governance; + } + + struct ContractsBytecodes { + // Default bytecode of the ERC-20 on L2 (BeaconProxy) + bytes beaconProxy; + // Bytecode of the L2 shared bridge + bytes l2SharedBridgeBytecode; + // Bytecode of the L2 shared bridge proxy (TransparentUpgradeableProxy) + bytes l2SharedBridgeProxyBytecode; + } + + Config internal config; + EcosystemContracts internal ecosystem; + ContractsBytecodes internal bytecodes; + + function run() public { + console.log("Preparing ZK chain registration calldata"); + + initializeConfig(); + + checkBaseTokenAddress(); + + IGovernance.Call[] memory calls; + uint256 cnt = 0; + if (!IBridgehub(ecosystem.bridgehub).tokenIsRegistered(config.baseToken)) { + calls = new IGovernance.Call[](2); + console.log("Adding a call to register base token on the bridgehub"); + IGovernance.Call memory baseTokenRegistrationCall = prepareRegisterBaseTokenCall(); + calls[cnt] = baseTokenRegistrationCall; + ++cnt; + } else { + calls = new IGovernance.Call[](1); + } + + IGovernance.Call memory registerChainCall = prepareRegisterHyperchainCall(); + calls[cnt] = registerChainCall; + ++cnt; + + address l2SharedBridgeProxy = computeL2BridgeAddress(); + IGovernance.Call memory initChainCall = prepareInitializeChainGovernanceCall(l2SharedBridgeProxy); + + scheduleTransparentCalldata(calls, initChainCall); + } + + function initializeConfig() internal { + // Grab config from output of l1 deployment + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-config/prepare-registration-calldata.toml"); + console.log("Reading a config from", path); + string memory toml = vm.readFile(path); + + // Config file must be parsed key by key, otherwise values returned + // are parsed alphabetically and not by key. + // https://book.getfoundry.sh/cheatcodes/parse-toml + config.stateTransitionProxy = toml.readAddress("$.deployed_addresses.state_transition_proxy_addr"); + config.erc20BridgeProxy = toml.readAddress("$.deployed_addresses.erc20_bridge_proxy_addr"); + + ecosystem.bridgehub = IStateTransitionManager(config.stateTransitionProxy).BRIDGE_HUB(); + ecosystem.l1SharedBridgeProxy = address(Bridgehub(ecosystem.bridgehub).sharedBridge()); + ecosystem.governance = Bridgehub(ecosystem.bridgehub).owner(); + + config.chainId = toml.readUint("$.chain.chain_id"); + config.eraChainId = toml.readUint("$.chain.era_chain_id"); + config.chainAdmin = toml.readAddress("$.chain.admin"); + config.diamondCutData = toml.readBytes("$.chain.diamond_cut_data"); + config.bridgehubCreateNewChainSalt = toml.readUint("$.chain.bridgehub_create_new_chain_salt"); + config.baseToken = toml.readAddress("$.chain.base_token_addr"); + + bytecodes.l2SharedBridgeBytecode = Utils.readHardhatBytecode("/script-config/artifacts/L2SharedBridge.json"); + bytecodes.beaconProxy = Utils.readHardhatBytecode("/script-config/artifacts/BeaconProxy.json"); + bytecodes.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode( + "/script-config/artifacts/TransparentUpgradeableProxy.json" + ); + } + + function checkBaseTokenAddress() internal view { + if (config.baseToken == address(0)) { + revert("Base token address is not set"); + } + + // Check if it's ethereum address + if (config.baseToken == ADDRESS_ONE) { + return; + } + + // Does not prevent registering a non-ERC-20 contract as a token + // But calling the ERC-20 methods here on non-ERC-20 will fail without a readable revert message + if (config.baseToken.code.length == 0) { + revert("Token address is an EOA"); + } + + console.log("Using base token address:", config.baseToken); + } + + function prepareRegisterBaseTokenCall() internal view returns (IGovernance.Call memory) { + Bridgehub bridgehub = Bridgehub(ecosystem.bridgehub); + + bytes memory data = abi.encodeCall(bridgehub.addToken, (config.baseToken)); + + return IGovernance.Call({target: ecosystem.bridgehub, value: 0, data: data}); + } + + // @dev Computes the address of the L2 bridge and the L2 bridge proxy + // The variables that are used to compute the address are: + // - Salt + // - L2 bridge impl bytecode hash + // - Era chain ID + // - Beacon proxy bytecode hash + // - L1 governance address(owner of the L2 bridge) + // - L1 ERC20 bridge proxy address + // - Default ERC20 proxy address + // - Deployer's address + function computeL2BridgeAddress() internal view returns (address) { + bytes32 salt = ""; + bytes32 bridgeBytecodeHash = L2ContractHelper.hashL2Bytecode(bytecodes.l2SharedBridgeBytecode); + bytes memory bridgeConstructorData = abi.encode(config.eraChainId); + + address deployer; + address l2GovernanceAddress; + + // ZKsync's protocol design assumes that the addresses of all the smart contracts that are sending L1->L2 + // messages are aliased. We have to check if the sender is an EOA and apply the alias if it is not. + if (isEOA(msg.sender)) { + deployer = msg.sender; + } else { + deployer = AddressAliasHelper.applyL1ToL2Alias(msg.sender); + } + + // If the governance address is an EOA, we use it directly, otherwise we apply the alias. On the Mainnet/Testnet + // the governance address is a smart contract, but in case someone uses the script with different envs, we have + // to check if the address is an EOA. + if (isEOA(ecosystem.governance)) { + l2GovernanceAddress = ecosystem.governance; + } else { + l2GovernanceAddress = AddressAliasHelper.applyL1ToL2Alias(ecosystem.governance); + } + + address implContractAddress = L2ContractHelper.computeCreate2Address( + deployer, + salt, + bridgeBytecodeHash, + keccak256(bridgeConstructorData) + ); + + console.log("Computed L2 bridge impl address:", implContractAddress); + console.log("Bridge bytecode hash:"); + console.logBytes32(bridgeBytecodeHash); + console.log("Bridge constructor data:"); + console.logBytes(bridgeConstructorData); + console.log("Deployer:", deployer); + + bytes32 l2StandardErc20BytecodeHash = L2ContractHelper.hashL2Bytecode(bytecodes.beaconProxy); + + // solhint-disable-next-line func-named-parameters + bytes memory proxyInitializationParams = abi.encodeWithSignature( + "initialize(address,address,bytes32,address)", + ecosystem.l1SharedBridgeProxy, + config.erc20BridgeProxy, + l2StandardErc20BytecodeHash, + l2GovernanceAddress + ); + + bytes memory l2SharedBridgeProxyConstructorData = abi.encode( + implContractAddress, + l2GovernanceAddress, + proxyInitializationParams + ); + + address proxyContractAddress = L2ContractHelper.computeCreate2Address( + deployer, + salt, + L2ContractHelper.hashL2Bytecode(bytecodes.l2SharedBridgeProxyBytecode), + keccak256(l2SharedBridgeProxyConstructorData) + ); + + console.log("Computed L2 bridge proxy address:", proxyContractAddress); + console.log("L1 shared bridge proxy:", ecosystem.l1SharedBridgeProxy); + console.log("L1 ERC20 bridge proxy:", config.erc20BridgeProxy); + console.log("L2 governor addr:", l2GovernanceAddress); + + return proxyContractAddress; + } + + function prepareRegisterHyperchainCall() internal view returns (IGovernance.Call memory) { + Bridgehub bridgehub = Bridgehub(ecosystem.bridgehub); + + bytes memory data = abi.encodeCall( + bridgehub.createNewChain, + ( + config.chainId, + config.stateTransitionProxy, + config.baseToken, + config.bridgehubCreateNewChainSalt, + config.chainAdmin, + config.diamondCutData + ) + ); + + return IGovernance.Call({target: ecosystem.bridgehub, value: 0, data: data}); + } + + function prepareInitializeChainGovernanceCall( + address l2SharedBridgeProxy + ) internal view returns (IGovernance.Call memory) { + L1SharedBridge bridge = L1SharedBridge(ecosystem.l1SharedBridgeProxy); + + bytes memory data = abi.encodeCall(bridge.initializeChainGovernance, (config.chainId, l2SharedBridgeProxy)); + + return IGovernance.Call({target: ecosystem.l1SharedBridgeProxy, value: 0, data: data}); + } + + // @dev Prepares a call to schedule a transparent operation on the governance contract + // `calls` is an array of calls that will be executed in the first stage (add a token to BH, create a new chain) + // `initChainGovCall` is a call that will be executed in the second stage (register the L2 bridge on the L1 shared bridge) + function scheduleTransparentCalldata( + IGovernance.Call[] memory calls, + IGovernance.Call memory initChainGovCall + ) internal { + IGovernance governance = IGovernance(ecosystem.governance); + + IGovernance.Operation memory operation = IGovernance.Operation({ + calls: calls, + predecessor: bytes32(0), + salt: bytes32(config.bridgehubCreateNewChainSalt) + }); + + bytes memory scheduleCalldata = abi.encodeCall(governance.scheduleTransparent, (operation, 0)); + bytes memory executeCalldata = abi.encodeCall(governance.execute, (operation)); + + IGovernance.Call[] memory initChainGovArray = new IGovernance.Call[](1); + initChainGovArray[0] = initChainGovCall; + + IGovernance.Operation memory operation2 = IGovernance.Operation({ + calls: initChainGovArray, + predecessor: bytes32(0), + salt: bytes32(config.bridgehubCreateNewChainSalt) + }); + + bytes memory scheduleCalldata2 = abi.encodeCall(governance.scheduleTransparent, (operation2, 0)); + bytes memory executeCalldata2 = abi.encodeCall(governance.execute, (operation2)); + + saveOutput(scheduleCalldata, executeCalldata, scheduleCalldata2, executeCalldata2); + } + + // Writes the output to a TOML file `script-out/output-prepare-registration-calldata.toml + // For the detailed explanation of the output - look into the contract description + function saveOutput( + bytes memory schedule, + bytes memory execute, + bytes memory schedule2, + bytes memory execute2 + ) internal { + vm.serializeBytes("root", "scheduleCalldataStageOne", schedule); + vm.serializeBytes("root", "executeCalldataStageOne", execute); + vm.serializeBytes("root", "scheduleCalldataStageTwo", schedule2); + string memory toml = vm.serializeBytes("root", "executeCalldataStageTwo", execute2); + + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-out/output-prepare-registration-calldata.toml"); + + console.log("Writing the output to", path); + vm.writeToml(toml, path); + } + + function isEOA(address _addr) private view returns (bool) { + uint32 size; + assembly { + size := extcodesize(_addr) + } + + return (size == 0); + } +} + +// Done by the chain admin separately from this script: +// - add validators +// - deploy L2 contracts +// - set pubdata sending mode +// - set base token gas price multiplier diff --git a/l1-contracts/script-config/artifacts/BeaconProxy.json b/l1-contracts/script-config/artifacts/BeaconProxy.json new file mode 100644 index 000000000..258780377 --- /dev/null +++ b/l1-contracts/script-config/artifacts/BeaconProxy.json @@ -0,0 +1,81 @@ +{ + "_format": "hh-zksolc-artifact-1", + "contractName": "BeaconProxy", + "sourceName": "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000001020030019d0000010203300197000300000031035500020000000103550000008008000039000000400080043f00000001022001900000001c0000c13d000000000131034f0000010d02000041000000000202041a0000010b04000041000000800040043f00000106022001970000000004000414000000000303004b000000250000c13d000000040320008c000000ab0000c13d0000000103000031000000200230008c00000000040300190000002004008039000000d60000013d0000010302300041000001040220009c0000002c0000213d0000011d0100004100000000001004350000004101000039000000040010043f0000011e010000410000040400010430000000040320008c000001160000c13d0000000103000031000000200230008c00000000040300190000002004008039000001410000013d0000009f023000390000010502200197000000400020043f0000001f0230018f00000005043002720000003b0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000330000413d000000000502004b0000004a0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000003f0130008c0000014a0000a13d000000800a00043d0000010601a0009c0000014a0000213d000000a00200043d000001070120009c0000014a0000213d0000001f012000390000010804000041000000000531004b000000000500001900000000050480190000010801100197000000000601004b0000000004008019000001080110009c000000000405c019000000000104004b0000014a0000c13d00000080012000390000000001010433000001070410009c0000001f0000213d0000003f04100039000000200700008a000000000474016f000000400900043d0000000004490019000000000594004b00000000050000190000000105004039000001070640009c0000001f0000213d00000001055001900000001f0000c13d0000008003300039000000400040043f0000000006190436000000a0022000390000000004210019000000000334004b0000014a0000213d000600000009001d000500000007001d000400000008001d000000000301004b000000820000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b0000007b0000413d000300000006001d000000000116001900000000000104350000010901000041000000000010043900070000000a001d0000000400a0044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400a00043d000000000101043b000000000101004b000002200000c13d0000006401a000390000011b0200004100000000002104350000004401a000390000011c0200004100000000002104350000002401a0003900000025020000390000000000210435000001150100004100000000001a04350000000401a000390000002002000039000000000021043500000102010000410000010202a0009c000000000a0180190000004001a002100000011a011001c700000404000104300000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000000c30000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000000bb0000413d000000000705004b000000d20000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000014c0000613d0000009f02400039000000e00220018f000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000014a0000213d000000020500036700000000040000310000001f0740018f0000000506400272000000eb0000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000000e40000413d000000000807004b000000f90000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001c40000c13d0000001f0430018f0000000502300272000001070000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001000000413d000000000504004b000001ed0000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000001ed0000013d0000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000012e0000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000001260000413d000000000705004b0000013d0000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000001690000613d0000001f02400039000000600220018f00000080022001bf000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000018c0000a13d00000000010000190000040400010430000000400200043d0000001f0430018f0000000505300272000001590000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001510000413d000000000604004b000001680000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d000000400200043d0000001f0430018f0000000505300272000001760000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000016e0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000010201000041000001020420009c000000000201801900000040012002100000006002300210000000000121019f0000040400010430000000020500036700000000040000310000001f0740018f0000000506400272000001990000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000001920000413d000000000807004b000001a70000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001ee0000c13d0000001f0430018f0000000502300272000001b50000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001ae0000413d000000000504004b000002170000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000001dd0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001d60000413d000000000604004b000001eb0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021c0000613d000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000002070000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000002000000413d000000000604004b000002150000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021e0000613d0000010201000041000001020230009c00000000030180190000006001300210000004030001042e00000060013002100000040400010430000000600130021000000404000104300000010b0100004100000000001a0435000000000100041400000007020000290000010602200197000000040320008c000700000002001d0000022d0000c13d0000000103000031000000200130008c000000000403001900000020040080390000025e0000013d0000010204000041000001020310009c00000000010480190000010203a0009c00000000040a40190000004003400210000000c001100210000000000131019f0000010c011001c700020000000a001d040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000024b0000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002430000413d000000000705004b0000025a0000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000002950000613d0000001f01400039000000600210018f0000000001a20019000000000221004b00000000020000190000000102004039000001070410009c0000001f0000213d00000001022001900000001f0000c13d000000400010043f000000200130008c0000014a0000413d00000000010a0433000001060210009c0000014a0000213d00000109020000410000000000200439000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400200043d000200000002001d000000000101043b000000000101004b000002b20000c13d0000000203000029000000640130003900000118020000410000000000210435000000440130003900000119020000410000000000210435000000240130003900000030020000390000000000210435000001150100004100000000001304350000000401300039000000200200003900000000002104350000010201000041000001020230009c000000000301801900000040013002100000011a011001c70000040400010430000000400200043d0000001f0430018f0000000505300272000002a20000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000029a0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d0000010d01000041000000000201041a0000010e022001970000000705000029000000000252019f000000000021041b00000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010f011001c70000800d0200003900000002030000390000011004000041040203f30000040f000000010120019000000006010000290000014a0000613d0000000001010433000000000101004b000002cd0000c13d0000002001000039000001000010044300000120000004430000011701000041000004030001042e0000010b010000410000000202000029000000000012043500000000010004140000000702000029000000040220008c000002d90000c13d0000000103000031000000200130008c000000000403001900000020040080390000030b0000013d0000010202000041000001020310009c00000000010280190000000204000029000001020340009c00000000020440190000004002200210000000c001100210000000000121019f0000010c011001c70000000702000029040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000002f80000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002f00000413d000000000705004b000003070000613d0000000506600210000000000761034f00000002066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003380000613d0000001f01400039000000600110018f0000000202100029000000000112004b00000000010000190000000101004039000700000002001d000001070220009c00000006040000290000001f0000213d00000001011001900000001f0000c13d0000000701000029000000400010043f000000200130008c0000014a0000413d00000002010000290000000001010433000200000001001d000001060110009c0000014a0000213d0000000701000029000001110110009c0000001f0000213d00000007050000290000006001500039000000400010043f000000400150003900000112020000410000000000210435000000270100003900000000021504360000011301000041000100000002001d0000000000120435000000000204043300000000010004140000000204000029000000040440008c000003550000c13d0000000102000039000001070130009c00000005050000290000001f0000213d0000036d0000013d000000400200043d0000001f0430018f0000000505300272000003450000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000033d0000413d000000000604004b000003540000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d00000102030000410000000305000029000001020450009c00000000050380190000004004500210000001020520009c00000000020380190000006002200210000000000242019f000001020410009c0000000001038019000000c001100210000000000121019f0000000202000029040203fd0000040f0000006004000039000000010220018f00030000000103550000006001100270000101020010019d000001020310019800000004090000290000000505000029000003960000613d0000003f01300039000000000151016f000000400400043d0000000001140019000000000541004b00000000050000190000000105004039000001070610009c0000001f0000213d00000001055001900000001f0000c13d000000400010043f0000001f0130018f000000000934043600000003050003670000000503300272000003870000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b0000037f0000413d000000000601004b000003960000613d0000000503300210000000000535034f00000000033900190000000301100210000000000603043300000000061601cf000000000616022f000000000505043b0000010001100089000000000515022f00000000011501cf000000000161019f00000000001304350000000001040433000000000202004b000003b60000c13d000000000201004b000003dc0000c13d000000400400043d000600000004001d0000011501000041000000000014043500000004014000390000002002000039000000000021043500000007010000290000000003010433000700000003001d0000002401400039000000000031043500000044024000390000000101000029040203e50000040f00000007010000290000001f01100039000000050110017f00000044011000390000010202000041000001020310009c00000000010280190000000604000029000001020340009c00000000040280190000004002400210000003e20000013d000000000101004b000002c80000c13d000001090100004100000000001004390000000201000029000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000000101043b000000000101004b000002c80000c13d000000400100043d00000044021000390000011403000041000000000032043500000024021000390000001d030000390000000000320435000001150200004100000000002104350000000402100039000000200300003900000000003204350000010202000041000001020310009c0000000001028019000000400110021000000116011001c70000040400010430000000000001042f0000010202000041000001020310009c0000000001028019000001020390009c000000000902801900000040029002100000006001100210000000000121019f0000040400010430000000000403004b000003ef0000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000003e80000413d00000000012300190000000000010435000000000001042d000000000001042f000003f6002104210000000102000039000000000001042d0000000002000019000000000001042d000003fb002104230000000102000039000000000001042d0000000002000019000000000001042d00000400002104250000000102000039000000000001042d0000000002000019000000000001042d0000040200000432000004030001042e000004040001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8302000002000000000000000000000000000000240000000000000000000000005c60da1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50ffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000008c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000020000000000000000000000000000004000000100000000000000000073206e6f74206120636f6e747261637400000000000000000000000000000000455243313936373a20626561636f6e20696d706c656d656e746174696f6e206900000000000000000000000000000000000000840000000000000000000000007472616374000000000000000000000000000000000000000000000000000000455243313936373a206e657720626561636f6e206973206e6f74206120636f6e4e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000004000000800000000000000000d32177e88b033622e0bc848f24ab73d0795ed87730981120fcdf94fbc134fa5d", + "deployedBytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000001020030019d0000010203300197000300000031035500020000000103550000008008000039000000400080043f00000001022001900000001c0000c13d000000000131034f0000010d02000041000000000202041a0000010b04000041000000800040043f00000106022001970000000004000414000000000303004b000000250000c13d000000040320008c000000ab0000c13d0000000103000031000000200230008c00000000040300190000002004008039000000d60000013d0000010302300041000001040220009c0000002c0000213d0000011d0100004100000000001004350000004101000039000000040010043f0000011e010000410000040400010430000000040320008c000001160000c13d0000000103000031000000200230008c00000000040300190000002004008039000001410000013d0000009f023000390000010502200197000000400020043f0000001f0230018f00000005043002720000003b0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000330000413d000000000502004b0000004a0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000003f0130008c0000014a0000a13d000000800a00043d0000010601a0009c0000014a0000213d000000a00200043d000001070120009c0000014a0000213d0000001f012000390000010804000041000000000531004b000000000500001900000000050480190000010801100197000000000601004b0000000004008019000001080110009c000000000405c019000000000104004b0000014a0000c13d00000080012000390000000001010433000001070410009c0000001f0000213d0000003f04100039000000200700008a000000000474016f000000400900043d0000000004490019000000000594004b00000000050000190000000105004039000001070640009c0000001f0000213d00000001055001900000001f0000c13d0000008003300039000000400040043f0000000006190436000000a0022000390000000004210019000000000334004b0000014a0000213d000600000009001d000500000007001d000400000008001d000000000301004b000000820000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b0000007b0000413d000300000006001d000000000116001900000000000104350000010901000041000000000010043900070000000a001d0000000400a0044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400a00043d000000000101043b000000000101004b000002200000c13d0000006401a000390000011b0200004100000000002104350000004401a000390000011c0200004100000000002104350000002401a0003900000025020000390000000000210435000001150100004100000000001a04350000000401a000390000002002000039000000000021043500000102010000410000010202a0009c000000000a0180190000004001a002100000011a011001c700000404000104300000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000000c30000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000000bb0000413d000000000705004b000000d20000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000014c0000613d0000009f02400039000000e00220018f000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000014a0000213d000000020500036700000000040000310000001f0740018f0000000506400272000000eb0000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000000e40000413d000000000807004b000000f90000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001c40000c13d0000001f0430018f0000000502300272000001070000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001000000413d000000000504004b000001ed0000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000001ed0000013d0000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000012e0000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000001260000413d000000000705004b0000013d0000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000001690000613d0000001f02400039000000600220018f00000080022001bf000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000018c0000a13d00000000010000190000040400010430000000400200043d0000001f0430018f0000000505300272000001590000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001510000413d000000000604004b000001680000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d000000400200043d0000001f0430018f0000000505300272000001760000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000016e0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000010201000041000001020420009c000000000201801900000040012002100000006002300210000000000121019f0000040400010430000000020500036700000000040000310000001f0740018f0000000506400272000001990000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000001920000413d000000000807004b000001a70000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001ee0000c13d0000001f0430018f0000000502300272000001b50000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001ae0000413d000000000504004b000002170000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000001dd0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001d60000413d000000000604004b000001eb0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021c0000613d000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000002070000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000002000000413d000000000604004b000002150000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021e0000613d0000010201000041000001020230009c00000000030180190000006001300210000004030001042e00000060013002100000040400010430000000600130021000000404000104300000010b0100004100000000001a0435000000000100041400000007020000290000010602200197000000040320008c000700000002001d0000022d0000c13d0000000103000031000000200130008c000000000403001900000020040080390000025e0000013d0000010204000041000001020310009c00000000010480190000010203a0009c00000000040a40190000004003400210000000c001100210000000000131019f0000010c011001c700020000000a001d040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000024b0000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002430000413d000000000705004b0000025a0000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000002950000613d0000001f01400039000000600210018f0000000001a20019000000000221004b00000000020000190000000102004039000001070410009c0000001f0000213d00000001022001900000001f0000c13d000000400010043f000000200130008c0000014a0000413d00000000010a0433000001060210009c0000014a0000213d00000109020000410000000000200439000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400200043d000200000002001d000000000101043b000000000101004b000002b20000c13d0000000203000029000000640130003900000118020000410000000000210435000000440130003900000119020000410000000000210435000000240130003900000030020000390000000000210435000001150100004100000000001304350000000401300039000000200200003900000000002104350000010201000041000001020230009c000000000301801900000040013002100000011a011001c70000040400010430000000400200043d0000001f0430018f0000000505300272000002a20000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000029a0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d0000010d01000041000000000201041a0000010e022001970000000705000029000000000252019f000000000021041b00000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010f011001c70000800d0200003900000002030000390000011004000041040203f30000040f000000010120019000000006010000290000014a0000613d0000000001010433000000000101004b000002cd0000c13d0000002001000039000001000010044300000120000004430000011701000041000004030001042e0000010b010000410000000202000029000000000012043500000000010004140000000702000029000000040220008c000002d90000c13d0000000103000031000000200130008c000000000403001900000020040080390000030b0000013d0000010202000041000001020310009c00000000010280190000000204000029000001020340009c00000000020440190000004002200210000000c001100210000000000121019f0000010c011001c70000000702000029040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000002f80000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002f00000413d000000000705004b000003070000613d0000000506600210000000000761034f00000002066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003380000613d0000001f01400039000000600110018f0000000202100029000000000112004b00000000010000190000000101004039000700000002001d000001070220009c00000006040000290000001f0000213d00000001011001900000001f0000c13d0000000701000029000000400010043f000000200130008c0000014a0000413d00000002010000290000000001010433000200000001001d000001060110009c0000014a0000213d0000000701000029000001110110009c0000001f0000213d00000007050000290000006001500039000000400010043f000000400150003900000112020000410000000000210435000000270100003900000000021504360000011301000041000100000002001d0000000000120435000000000204043300000000010004140000000204000029000000040440008c000003550000c13d0000000102000039000001070130009c00000005050000290000001f0000213d0000036d0000013d000000400200043d0000001f0430018f0000000505300272000003450000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000033d0000413d000000000604004b000003540000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d00000102030000410000000305000029000001020450009c00000000050380190000004004500210000001020520009c00000000020380190000006002200210000000000242019f000001020410009c0000000001038019000000c001100210000000000121019f0000000202000029040203fd0000040f0000006004000039000000010220018f00030000000103550000006001100270000101020010019d000001020310019800000004090000290000000505000029000003960000613d0000003f01300039000000000151016f000000400400043d0000000001140019000000000541004b00000000050000190000000105004039000001070610009c0000001f0000213d00000001055001900000001f0000c13d000000400010043f0000001f0130018f000000000934043600000003050003670000000503300272000003870000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b0000037f0000413d000000000601004b000003960000613d0000000503300210000000000535034f00000000033900190000000301100210000000000603043300000000061601cf000000000616022f000000000505043b0000010001100089000000000515022f00000000011501cf000000000161019f00000000001304350000000001040433000000000202004b000003b60000c13d000000000201004b000003dc0000c13d000000400400043d000600000004001d0000011501000041000000000014043500000004014000390000002002000039000000000021043500000007010000290000000003010433000700000003001d0000002401400039000000000031043500000044024000390000000101000029040203e50000040f00000007010000290000001f01100039000000050110017f00000044011000390000010202000041000001020310009c00000000010280190000000604000029000001020340009c00000000040280190000004002400210000003e20000013d000000000101004b000002c80000c13d000001090100004100000000001004390000000201000029000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000000101043b000000000101004b000002c80000c13d000000400100043d00000044021000390000011403000041000000000032043500000024021000390000001d030000390000000000320435000001150200004100000000002104350000000402100039000000200300003900000000003204350000010202000041000001020310009c0000000001028019000000400110021000000116011001c70000040400010430000000000001042f0000010202000041000001020310009c0000000001028019000001020390009c000000000902801900000040029002100000006001100210000000000121019f0000040400010430000000000403004b000003ef0000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000003e80000413d00000000012300190000000000010435000000000001042d000000000001042f000003f6002104210000000102000039000000000001042d0000000002000019000000000001042d000003fb002104230000000102000039000000000001042d0000000002000019000000000001042d00000400002104250000000102000039000000000001042d0000000002000019000000000001042d0000040200000432000004030001042e000004040001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8302000002000000000000000000000000000000240000000000000000000000005c60da1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50ffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000008c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000020000000000000000000000000000004000000100000000000000000073206e6f74206120636f6e747261637400000000000000000000000000000000455243313936373a20626561636f6e20696d706c656d656e746174696f6e206900000000000000000000000000000000000000840000000000000000000000007472616374000000000000000000000000000000000000000000000000000000455243313936373a206e657720626561636f6e206973206e6f74206120636f6e4e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000004000000800000000000000000d32177e88b033622e0bc848f24ab73d0795ed87730981120fcdf94fbc134fa5d", + "linkReferences": {}, + "deployedLinkReferences": {}, + "factoryDeps": {} +} diff --git a/l1-contracts/script-config/artifacts/L2SharedBridge.json b/l1-contracts/script-config/artifacts/L2SharedBridge.json new file mode 100644 index 000000000..a74e5c9ad --- /dev/null +++ b/l1-contracts/script-config/artifacts/L2SharedBridge.json @@ -0,0 +1,262 @@ +{ + "_format": "hh-zksolc-artifact-1", + "contractName": "L2SharedBridge", + "sourceName": "contracts/bridge/L2SharedBridge.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eraChainId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FinalizeDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l2Sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalInitiated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "finalizeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1SharedBridge", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Bridge", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_l2TokenProxyBytecodeHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_aliasedOwner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1SharedBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "l2TokenAddress", + "type": "address" + } + ], + "name": "l1TokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "l1TokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + } + ], + "name": "l2TokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2TokenBeacon", + "outputs": [ + { + "internalType": "contract UpgradeableBeacon", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x0004000000000002001000000000000200000000030100190000006004300270000001a20340019700030000003103550002000000010355000001a20040019d00000001022001900000001d0000c13d0000008002000039000000400020043f000000040230008c000000400000413d000000000201043b000000e002200270000001ab0420009c000000420000213d000001b10420009c0000008a0000213d000001b40120009c000000c10000613d000001b50120009c000000400000c13d0000000001000416000000000101004b000000400000c13d0000000401000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000bf02300039000001a302200197000000400020043f0000001f0230018f00000005043002720000002f0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000000270000413d000000000502004b0000003e0000613d0000000504400210000000000141034f0000000302200210000000a004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f0000000000140435000000200130008c000000640000813d00000000010000190000068300010430000001ac0420009c000000940000213d000001af0420009c000000c60000613d000001b00220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000600220008c000000400000413d0000000402100370000000000402043b000001b60240009c000000400000213d0000002402100370000000000302043b000001b60230009c000000400000213d0000004401100370000000000201043b000000000102004b000001de0000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000001501000039000000a40010043f000001c501000041000000c40010043f000001c6010000410000068300010430000000a00100043d000000800010043f000000000200041a0000ff0003200190000000ac0000c13d000000ff0320018f000000ff0330008c000000820000613d000000ff012001bf000000000010041b000000ff01000039000000400200043d0000000000120435000001a2010000410000000003000414000001a20430009c0000000003018019000001a20420009c00000000020180190000004001200210000000c002300210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d000000800100043d000001400000044300000160001004430000002001000039000001000010044300000001010000390000012000100443000001aa01000041000006820001042e000001b20420009c000001a50000613d000001b30120009c000000400000c13d0000000001000416000000000101004b000000400000c13d000000000100041a0000001001100270000001da0000013d000001ad0420009c000001c90000613d000001ae0220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d068106050000040f000001b601100197000000400200043d0000000000120435000001a201000041000001a20320009c00000000020180190000004001200210000001b7011001c7000006820001042e000000400100043d0000006402100039000001a40300004100000000003204350000004402100039000001a5030000410000000000320435000000240210003900000027030000390000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001a7011001c700000683000104300000000001000416000000000101004b000000400000c13d0000000101000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000a00220008c000000400000413d0000000402100370000000000802043b000001b60280009c000000400000213d0000002402100370000000000902043b000001b60290009c000000400000213d0000004402100370000000000a02043b000001b602a0009c000000400000213d0000008402100370000000000202043b000001bd0420009c000000400000213d0000002304200039000001c705000041000000000634004b00000000060000190000000006058019000001c704400197000000000704004b0000000005008019000001c70440009c000000000506c019000000000405004b000000400000c13d0000000404200039000000000441034f000000000504043b000001bd0450009c000000400000213d001000240020003d0000001002500029000000000232004b000000400000213d000b00000005001d000f0000000a001d000e00000009001d000c00000008001d0000006401100370000000000101043b000d00000001001d0000000001000411000001c801100041000001b6011001970000000402000039000000000202041a000001b602200197000000000221004b000001050000613d000000000200041a0000001002200270000001b602200197000000000121004b000002c10000c13d0000000101000039000800000001001d000000000101041a000001b601100197000000a00010043f0000004001000039000900000001001d000000c00010043f000000e00000043f0000006001000039000a00000001001d000000800010043f0000010001000039000000400010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ca011001c700008010020000390681067c0000040f00000001022001900000000f05000029000000400000613d0000000202000039000700000002001d000000000202041a000000000301043b000000400100043d000000a004100039000000000034043500000080031000390000000000230435000000600210003900000000005204350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000002170000213d000000c003100039000000400030043f000001a204000041000001a20320009c000000000204801900000040022002100000000001010433000001a20310009c00000000010480190000006001100210000000000121019f0000000002000414000001a20320009c0000000002048019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000500000001001d000001b601100197000600000001001d00000000001004350000000301000039000400000001001d000000200010043f0000000001000414000001a20210009c000001a201008041000000c001100210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000000000101041a000001b601100198000003ad0000c13d00000000010004140000000702000029000000000402041a0000000802000029000000000202041a000000400300043d000000400530003900000009060000290000000000650435000001b602200197000000200530003900000000002504350000000a02000029000000000023043500000060023000390000000000020435000001c00230009c000002170000213d0000008002300039000000400020043f000000a005300039000001cf060000410000000000650435000000e4053000390000000a060000290000000000650435000000c4053000390000000000450435000000a4043000390000000f0500002900000000005404350000010405300039000000000403043300000000004504350000012405300039000000000604004b0000018a0000613d000000000600001900000000075600190000002006600039000000000836001900000000080804330000000000870435000000000746004b000001830000413d000000000354001900000000000304350000001f03400039000a0020000000920000000a0330017f00000084043000390000000000420435000000c3033000390000000a0430017f0000000003240019000000000443004b00000000040000190000000104004039000001bd0530009c000002170000213d0000000104400190000002170000c13d000000400030043f0000000004020433000001d00540009c0000045f0000413d0000004401300039000001dc02000041000000000021043500000024013000390000000802000039000002b50000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000800220008c000000400000413d0000000402100370000000000202043b000001b60320009c000000400000213d0000002403100370000000000603043b000001b60360009c000000400000213d0000006403100370000000000503043b000001b60350009c000000400000213d000000000300041a0000fffe043001900000021d0000c13d000001e00330019700000102033001bf000000000030041b0000004401100370000000000401043b000000000102004b000002290000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f501000041000000610000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d00000000001004350000000301000039000000200010043f00000040020000390000000001000019068106610000040f000000000101041a000001b601100197000000800010043f000001b801000041000006820001042e000f00000002001d000e00000004001d000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000001004000029000000400000613d000000400500043d00000024015000390000000f020000290000000000210435000001bb0100004100000000001504350000000001000411000d00000001001d000001b601100197000000040250003900000000001204350000000001000414000000040240008c000002150000613d000001a202000041000001a20310009c0000000001028019000001a20350009c00000000020540190000004002200210000000c001100210000000000121019f000001bc011001c70000000002040019000c00000005001d068106770000040f0000000c05000029000000100400002900000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000002640000613d000001bd0150009c000002400000a13d000001f00100004100000000001004350000004101000039000000040010043f000001ef010000410000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000002e01000039000000a40010043f000001dd01000041000000c40010043f000001de01000041000000e40010043f000001df010000410000068300010430000000000104004b000002330000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f401000041000000610000013d001000000006001d000f00000004001d000e00000005001d000000000105004b000002870000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f301000041000000610000013d000000400050043f00000000004004350000000301000039000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000400200043d0000002403200039000000000101043b000000000101041a000001b601100198000002c90000c13d000001a6010000410000000000120435000000040120003900000020040000390000000000410435000000020100003900000000001304350000004401200039000001c3030000410000000000310435000001a201000041000001a20320009c00000000020180190000004001200210000001c4011001c70000068300010430000000400200043d0000001f0430018f0000000505300272000002710000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000002690000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20420009c000000000201801900000040012002100000006002300210000000000121019f0000068300010430000001e1013001970000001002200210000001e202200197000000000121019f000000000010041b000001e3010000410000000000100439000000000100041200000004001004430000002400000443000001a2030000410000000001000414000001a20210009c0000000001038019000000c001100210000001e4011001c700008005020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000d00000001001d000001e50100004100000000001004390000000001000414000001a20210009c000001a201008041000000c001100210000001e6011001c70000800b020000390681067c0000040f00000001022001900000059c0000613d000000400200043d000c00000002001d000000000101043b0000000d0110006c0000034d0000c13d000000100100006b0000038f0000c13d0000000c030000290000004401300039000001f2020000410000000000210435000000240130003900000003020000390000000000210435000001a6010000410000000000130435000000040130003900000020020000390000000000210435000001a201000041000001a20230009c00000000030180190000004001300210000001c4011001c70000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001c901000041000000610000013d0000002004200039000001bf0500004100000000005404350000000e04000029000000600440021000000000004304350000006001100210000000380320003900000000001304350000004c012000390000000f0300002900000000003104350000004c010000390000000000120435000001c00120009c000002170000213d0000008003200039000000400030043f000001c101000041000c00000003001d0000000000130435000000840120003900000020030000390000000000310435000000a40320003900000000010204330000000000130435000000c403200039000000000401004b000002ef0000613d000000000400001900000000053400190000002004400039000000000624001900000000060604330000000000650435000000000514004b000002e80000413d000000000231001900000000000204350000001f01100039000000200200008a000000000121016f000001a2020000410000000c04000029000001a20340009c0000000003020019000000000304401900000040033002100000004401100039000001a20410009c00000000010280190000006001100210000000000131019f0000000003000414000001a20430009c0000000003028019000000c002300210000000000112019f0000800802000039068106770000040f0000000c0a00002900000000030100190000006003300270000001a203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000003190000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000003110000413d000000000705004b000003280000613d0000000506600210000000000761034f0000000c066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003720000613d0000001f01400039000000600210018f0000000c01200029000000000221004b00000000020000190000000102004039000001bd0410009c00000010070000290000000e05000029000002170000213d0000000102200190000002170000c13d000000400010043f000000200230008c000000400000413d0000000f020000290000000000210435000001a2020000410000000003000414000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000112019f000001a8011001c7000001b6065001970000800d020000390000000403000039000001c2040000410000000d05000029000003a80000013d0000000c01000029000001e70110009c000002170000813d0000000c040000290000002401400039000001e8020000410000000000210435000000440140003900000000020004140000006003000039001000000003001d0000000000310435000001e90100004100000000001404350000006401400039000000000001043500000004014000390000000000010435000001a201000041000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000121019f000001ea011001c70000800602000039068106770000040f0000000102200190000003fc0000613d000000000201043b000000000102004b000004380000c13d00000003010003670000000102000031000004010000013d000000400200043d0000001f0430018f00000005053002720000037f0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000003770000413d000000000604004b0000038e0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d0000000401000039000000000201041a000001d90220019700000010022001af000000000021041b000001f101000041000000000200041a000000000112016f000000000010041b00000002010000390000000c040000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d0000000001000019000006820001042e0000000f0110006c000004260000c13d000001b901000041000000000010043900000006010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400400043d00000024014000390000000d030000290000000000310435000001da010000410000000000140435000001b602200197001000000004001d0000000401400039000f00000002001d000000000021043500000000010004140000000602000029000000040220008c000003e30000613d000001a202000041000001a20310009c00000000010280190000001004000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001bc011001c70000000602000029068106770000040f00000000030100190000006003300270000101a20030019d000001a203300197000300000001035500000001022001900000059d0000613d0000001001000029000001bd0110009c000002170000213d0000001004000029000000400040043f0000000d010000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000000c02000029000001b6052001970000800d020000390000000403000039000001db040000410000000f060000290000000607000029000003a80000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000040e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000004060000413d000000000604004b0000041d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20430009c0000000003018019000001a20420009c000000000201801900000060012002100000004002300210000000000112019f0000068300010430000000400100043d0000004402100039000001ce030000410000000000320435000000240210003900000007030000290000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001c4011001c70000068300010430000000400100043d000001eb0310009c000002170000213d000001b602200197000000840310003900000000002304350000002402100039000001ec0300004100000000003204350000006402100039000000000300041400000020040000390000000000420435000000440210003900000010040000290000000000420435000001e902000041000000000021043500000004021000390000000000020435000001a202000041000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000121019f000001ed011001c70000800602000039068106770000040f00000001022001900000053c0000613d000000000101043b000000000201004b0000055e0000c13d00000003010003670000000102000031000005410000013d000000c001100210000001d1011001970000004002200210000001d202200041000001d302200197000000000121019f0000006002400210000001d402200197000000000121019f000001d5011001c700008006020000390000000003000019000000000400001900000000050000190000000006000019068106770000040f000300000001035500000000030100190000006003300270000101a20030019d000001a2053001970000003f03500039000001a306300197000000400400043d0000000003460019000000000663004b00000000060000190000000106004039000001bd0730009c000002170000213d0000000106600190000002170000c13d000000400030043f00000000035404360000001f0650003900000005066002720000048f0000613d0000000007000031000000020770036700000000080000190000000509800210000000000a930019000000000997034f000000000909043b00000000009a04350000000108800039000000000968004b000004870000413d000000000600004b000004910000613d0000001f0650018f00000005055002720000049d0000613d000000000700001900000005087002100000000009830019000000000881034f000000000808043b00000000008904350000000107700039000000000857004b000004950000413d000000000706004b000004ac0000613d0000000505500210000000000151034f00000000055300190000000306600210000000000705043300000000076701cf000000000767022f000000000101043b0000010006600089000000000161022f00000000016101cf000000000171019f00000000001504350000000101200190000005ba0000613d0000000001040433000001c702000041000000200410008c00000000040000190000000004024019000001c701100197000000000501004b000000000200a019000001c70110009c000000000204c019000000000102004b000000400000c13d0000000001030433000800000001001d000001b60110009c000000400000213d000001b901000041000000000010043900000008010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000f020000290000000b04000029000000400000613d000000400300043d000001d701000041000000000013043500000024053000390000000901000029000300000005001d00000000001504350000000401300039000200000001001d00000000002104350000001f0240018f0000006401300039000900000003001d0000004403300039000100000003001d0000000000430435000000100300002900000002033003670000000504400272000004ee0000613d000000000500001900000005065002100000000007610019000000000663034f000000000606043b00000000006704350000000105500039000000000645004b000004e60000413d000000000502004b000004fd0000613d0000000504400210000000000343034f00000000044100190000000302200210000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f00000000002404350000000b01100029000000000001043500000000010004140000000802000029000000040220008c0000051e0000613d0000000b020000290000001f022000390000000a0220017f000001a2030000410000000905000029000001a20450009c0000000004030019000000000405401900000040044002100000006402200039000001a20520009c00000000020380190000006002200210000000000224019f000001a20410009c0000000001038019000000c001100210000000000121019f0000000802000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005db0000613d0000000901000029000001bd0110009c000002170000213d0000000901000029000000400010043f0000000802000029000000050120014f000001b601100198000005f80000c13d000000060100002900000000001004350000000401000029000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f00000001022001900000000f03000029000000400000613d000000000101043b000000000201041a000001d902200197000000000232019f000000000021041b000003af0000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000054e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005460000413d000000000604004b0000055d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000041d0000013d000001b6031001970000000101000039000000000201041a000001d902200197000000000232019f000000000021041b00000002010000390000000f02000029000000000021041b000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400300043d000001ee010000410000000000130435000c00000003001d0000000401300039000000000021043500000000010004140000001002000029000000040220008c000005960000613d000001a202000041000001a20310009c00000000010280190000000c04000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001ef011001c70000001002000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005be0000613d0000000c01000029000001bd0110009c000002170000213d0000000c01000029000000400010043f000003940000013d000000000001042f000000400200043d0000001f0430018f0000000505300272000005aa0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005a20000413d000000000604004b000005b90000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400100043d0000004402100039000001d603000041000004290000013d000000400200043d0000001f0430018f0000000505300272000005cb0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005c30000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400200043d0000001f0430018f0000000505300272000005e80000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005e00000413d000000000604004b000005f70000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000001a60100004100000009030000290000000000130435000000200100003900000002020000290000000000120435000000070100002900000003020000290000000000120435000001d80100004100000001020000290000000000120435000002bb0000013d0001000000000002000100000001001d0000000101000039000000000301041a000000400100043d00000040021000390000004004000039000000000042043500000060020000390000000002210436000001b603300197000000000032043500000060031000390000000000030435000001f60310009c000006580000813d0000008003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d0000000202000039000000000202041a000000000301043b000000400100043d000000a0041000390000000000340435000000800310003900000000002304350000000102000029000001b602200197000000600310003900000000002304350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000006580000213d000000c003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d000000000101043b000001b601100197000000000001042d000001f00100004100000000001004350000004101000039000000040010043f000001ef01000041000006830001043000000000010000190000068300010430000000000001042f000001a203000041000001a20410009c00000000010380190000004001100210000001a20420009c00000000020380190000006002200210000000000112019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000006750000613d000000000101043b000000000001042d000000000100001900000683000104300000067a002104210000000102000039000000000001042d0000000002000019000000000001042d0000067f002104230000000102000039000000000001042d0000000002000019000000000001042d0000068100000432000006820001042e0000068300010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe0616c697a696e6700000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320696e69746908c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000002000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000cfe7af7b00000000000000000000000000000000000000000000000000000000f54266a100000000000000000000000000000000000000000000000000000000f54266a200000000000000000000000000000000000000000000000000000000f5f1516800000000000000000000000000000000000000000000000000000000cfe7af7c00000000000000000000000000000000000000000000000000000000d9caed1200000000000000000000000000000000000000000000000000000000a31ee5af00000000000000000000000000000000000000000000000000000000a31ee5b000000000000000000000000000000000000000000000000000000000b852ad36000000000000000000000000000000000000000000000000000000006dde720900000000000000000000000000000000000000000000000000000000969b53da000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000008000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83020000020000000000000000000000000000002400000000000000000000000074f4f547000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff020000000000000000000000000000000000004000000000000000000000000011a2ccc100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f62f84b24000000000000000000000000000000000000000000000000000000002fc3848834aac8e883a2d2a17a7514dc4f2d3dd268089df9b9f5d918259ef3b079680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000416d6f756e742063616e6e6f74206265207a65726f000000000000000000000000000000000000000000000000000000000000640000008000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeffffffffffffffffffffffffffffffffeeef6d710000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000060000000a000000000000000002020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494000000000000000000000000000000000000000000000000ffffffffffffff3f020000000000000000000000000000000000000000000000000000000000000067670000000000000000000000000000000000000000000000000000000000003cda335100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffff00000000000000000000000001000000000000000000000000000000000000000000000000000000000000006d6b00000000000000000000000000000000000000000000000000000000000095f11a40000000000000000000000000000000000000000000000000000000006d74000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000008c2a993e00000000000000000000000000000000000000000000000000000000b84fba9af218da60d299dc177abd5805e7ac541d2673cbee7808c10017874f634f766572666c6f77000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65640000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000000000000000000000000000000000000000010200000000000000000000ffffffffffffffffffffffffffffffffffffffff0000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e02000002000000000000000000000000000000440000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7c010004751688ab9322961547058fd0f36d3edf69880b64cbb2857041d33f4a133cda33511d41a8a5431b1770c5bc0ddd62e1cd30555d16659b89c0d60f4f9f570200000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7b010000691fa4f751f8312bc555242f18ed78cdc9aabc0ea77d7d5a675ee8ac6f02000000000000000000000000000000000000a4000000000000000000000000f2fde38b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6266320000000000000000000000000000000000000000000000000000000000736600000000000000000000000000000000000000000000000000000000000064660000000000000000000000000000000000000000000000000000000000006266000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff800000000000000000000000000000000000000000000000000000000000000000f5cf0be6820df44d868e986d4d5cafabd5702ac45d181a5ac4eb5ed59a001b03", + "deployedBytecode": "0x0004000000000002001000000000000200000000030100190000006004300270000001a20340019700030000003103550002000000010355000001a20040019d00000001022001900000001d0000c13d0000008002000039000000400020043f000000040230008c000000400000413d000000000201043b000000e002200270000001ab0420009c000000420000213d000001b10420009c0000008a0000213d000001b40120009c000000c10000613d000001b50120009c000000400000c13d0000000001000416000000000101004b000000400000c13d0000000401000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000bf02300039000001a302200197000000400020043f0000001f0230018f00000005043002720000002f0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000000270000413d000000000502004b0000003e0000613d0000000504400210000000000141034f0000000302200210000000a004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f0000000000140435000000200130008c000000640000813d00000000010000190000068300010430000001ac0420009c000000940000213d000001af0420009c000000c60000613d000001b00220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000600220008c000000400000413d0000000402100370000000000402043b000001b60240009c000000400000213d0000002402100370000000000302043b000001b60230009c000000400000213d0000004401100370000000000201043b000000000102004b000001de0000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000001501000039000000a40010043f000001c501000041000000c40010043f000001c6010000410000068300010430000000a00100043d000000800010043f000000000200041a0000ff0003200190000000ac0000c13d000000ff0320018f000000ff0330008c000000820000613d000000ff012001bf000000000010041b000000ff01000039000000400200043d0000000000120435000001a2010000410000000003000414000001a20430009c0000000003018019000001a20420009c00000000020180190000004001200210000000c002300210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d000000800100043d000001400000044300000160001004430000002001000039000001000010044300000001010000390000012000100443000001aa01000041000006820001042e000001b20420009c000001a50000613d000001b30120009c000000400000c13d0000000001000416000000000101004b000000400000c13d000000000100041a0000001001100270000001da0000013d000001ad0420009c000001c90000613d000001ae0220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d068106050000040f000001b601100197000000400200043d0000000000120435000001a201000041000001a20320009c00000000020180190000004001200210000001b7011001c7000006820001042e000000400100043d0000006402100039000001a40300004100000000003204350000004402100039000001a5030000410000000000320435000000240210003900000027030000390000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001a7011001c700000683000104300000000001000416000000000101004b000000400000c13d0000000101000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000a00220008c000000400000413d0000000402100370000000000802043b000001b60280009c000000400000213d0000002402100370000000000902043b000001b60290009c000000400000213d0000004402100370000000000a02043b000001b602a0009c000000400000213d0000008402100370000000000202043b000001bd0420009c000000400000213d0000002304200039000001c705000041000000000634004b00000000060000190000000006058019000001c704400197000000000704004b0000000005008019000001c70440009c000000000506c019000000000405004b000000400000c13d0000000404200039000000000441034f000000000504043b000001bd0450009c000000400000213d001000240020003d0000001002500029000000000232004b000000400000213d000b00000005001d000f0000000a001d000e00000009001d000c00000008001d0000006401100370000000000101043b000d00000001001d0000000001000411000001c801100041000001b6011001970000000402000039000000000202041a000001b602200197000000000221004b000001050000613d000000000200041a0000001002200270000001b602200197000000000121004b000002c10000c13d0000000101000039000800000001001d000000000101041a000001b601100197000000a00010043f0000004001000039000900000001001d000000c00010043f000000e00000043f0000006001000039000a00000001001d000000800010043f0000010001000039000000400010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ca011001c700008010020000390681067c0000040f00000001022001900000000f05000029000000400000613d0000000202000039000700000002001d000000000202041a000000000301043b000000400100043d000000a004100039000000000034043500000080031000390000000000230435000000600210003900000000005204350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000002170000213d000000c003100039000000400030043f000001a204000041000001a20320009c000000000204801900000040022002100000000001010433000001a20310009c00000000010480190000006001100210000000000121019f0000000002000414000001a20320009c0000000002048019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000500000001001d000001b601100197000600000001001d00000000001004350000000301000039000400000001001d000000200010043f0000000001000414000001a20210009c000001a201008041000000c001100210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000000000101041a000001b601100198000003ad0000c13d00000000010004140000000702000029000000000402041a0000000802000029000000000202041a000000400300043d000000400530003900000009060000290000000000650435000001b602200197000000200530003900000000002504350000000a02000029000000000023043500000060023000390000000000020435000001c00230009c000002170000213d0000008002300039000000400020043f000000a005300039000001cf060000410000000000650435000000e4053000390000000a060000290000000000650435000000c4053000390000000000450435000000a4043000390000000f0500002900000000005404350000010405300039000000000403043300000000004504350000012405300039000000000604004b0000018a0000613d000000000600001900000000075600190000002006600039000000000836001900000000080804330000000000870435000000000746004b000001830000413d000000000354001900000000000304350000001f03400039000a0020000000920000000a0330017f00000084043000390000000000420435000000c3033000390000000a0430017f0000000003240019000000000443004b00000000040000190000000104004039000001bd0530009c000002170000213d0000000104400190000002170000c13d000000400030043f0000000004020433000001d00540009c0000045f0000413d0000004401300039000001dc02000041000000000021043500000024013000390000000802000039000002b50000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000800220008c000000400000413d0000000402100370000000000202043b000001b60320009c000000400000213d0000002403100370000000000603043b000001b60360009c000000400000213d0000006403100370000000000503043b000001b60350009c000000400000213d000000000300041a0000fffe043001900000021d0000c13d000001e00330019700000102033001bf000000000030041b0000004401100370000000000401043b000000000102004b000002290000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f501000041000000610000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d00000000001004350000000301000039000000200010043f00000040020000390000000001000019068106610000040f000000000101041a000001b601100197000000800010043f000001b801000041000006820001042e000f00000002001d000e00000004001d000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000001004000029000000400000613d000000400500043d00000024015000390000000f020000290000000000210435000001bb0100004100000000001504350000000001000411000d00000001001d000001b601100197000000040250003900000000001204350000000001000414000000040240008c000002150000613d000001a202000041000001a20310009c0000000001028019000001a20350009c00000000020540190000004002200210000000c001100210000000000121019f000001bc011001c70000000002040019000c00000005001d068106770000040f0000000c05000029000000100400002900000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000002640000613d000001bd0150009c000002400000a13d000001f00100004100000000001004350000004101000039000000040010043f000001ef010000410000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000002e01000039000000a40010043f000001dd01000041000000c40010043f000001de01000041000000e40010043f000001df010000410000068300010430000000000104004b000002330000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f401000041000000610000013d001000000006001d000f00000004001d000e00000005001d000000000105004b000002870000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f301000041000000610000013d000000400050043f00000000004004350000000301000039000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000400200043d0000002403200039000000000101043b000000000101041a000001b601100198000002c90000c13d000001a6010000410000000000120435000000040120003900000020040000390000000000410435000000020100003900000000001304350000004401200039000001c3030000410000000000310435000001a201000041000001a20320009c00000000020180190000004001200210000001c4011001c70000068300010430000000400200043d0000001f0430018f0000000505300272000002710000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000002690000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20420009c000000000201801900000040012002100000006002300210000000000121019f0000068300010430000001e1013001970000001002200210000001e202200197000000000121019f000000000010041b000001e3010000410000000000100439000000000100041200000004001004430000002400000443000001a2030000410000000001000414000001a20210009c0000000001038019000000c001100210000001e4011001c700008005020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000d00000001001d000001e50100004100000000001004390000000001000414000001a20210009c000001a201008041000000c001100210000001e6011001c70000800b020000390681067c0000040f00000001022001900000059c0000613d000000400200043d000c00000002001d000000000101043b0000000d0110006c0000034d0000c13d000000100100006b0000038f0000c13d0000000c030000290000004401300039000001f2020000410000000000210435000000240130003900000003020000390000000000210435000001a6010000410000000000130435000000040130003900000020020000390000000000210435000001a201000041000001a20230009c00000000030180190000004001300210000001c4011001c70000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001c901000041000000610000013d0000002004200039000001bf0500004100000000005404350000000e04000029000000600440021000000000004304350000006001100210000000380320003900000000001304350000004c012000390000000f0300002900000000003104350000004c010000390000000000120435000001c00120009c000002170000213d0000008003200039000000400030043f000001c101000041000c00000003001d0000000000130435000000840120003900000020030000390000000000310435000000a40320003900000000010204330000000000130435000000c403200039000000000401004b000002ef0000613d000000000400001900000000053400190000002004400039000000000624001900000000060604330000000000650435000000000514004b000002e80000413d000000000231001900000000000204350000001f01100039000000200200008a000000000121016f000001a2020000410000000c04000029000001a20340009c0000000003020019000000000304401900000040033002100000004401100039000001a20410009c00000000010280190000006001100210000000000131019f0000000003000414000001a20430009c0000000003028019000000c002300210000000000112019f0000800802000039068106770000040f0000000c0a00002900000000030100190000006003300270000001a203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000003190000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000003110000413d000000000705004b000003280000613d0000000506600210000000000761034f0000000c066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003720000613d0000001f01400039000000600210018f0000000c01200029000000000221004b00000000020000190000000102004039000001bd0410009c00000010070000290000000e05000029000002170000213d0000000102200190000002170000c13d000000400010043f000000200230008c000000400000413d0000000f020000290000000000210435000001a2020000410000000003000414000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000112019f000001a8011001c7000001b6065001970000800d020000390000000403000039000001c2040000410000000d05000029000003a80000013d0000000c01000029000001e70110009c000002170000813d0000000c040000290000002401400039000001e8020000410000000000210435000000440140003900000000020004140000006003000039001000000003001d0000000000310435000001e90100004100000000001404350000006401400039000000000001043500000004014000390000000000010435000001a201000041000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000121019f000001ea011001c70000800602000039068106770000040f0000000102200190000003fc0000613d000000000201043b000000000102004b000004380000c13d00000003010003670000000102000031000004010000013d000000400200043d0000001f0430018f00000005053002720000037f0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000003770000413d000000000604004b0000038e0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d0000000401000039000000000201041a000001d90220019700000010022001af000000000021041b000001f101000041000000000200041a000000000112016f000000000010041b00000002010000390000000c040000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d0000000001000019000006820001042e0000000f0110006c000004260000c13d000001b901000041000000000010043900000006010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400400043d00000024014000390000000d030000290000000000310435000001da010000410000000000140435000001b602200197001000000004001d0000000401400039000f00000002001d000000000021043500000000010004140000000602000029000000040220008c000003e30000613d000001a202000041000001a20310009c00000000010280190000001004000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001bc011001c70000000602000029068106770000040f00000000030100190000006003300270000101a20030019d000001a203300197000300000001035500000001022001900000059d0000613d0000001001000029000001bd0110009c000002170000213d0000001004000029000000400040043f0000000d010000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000000c02000029000001b6052001970000800d020000390000000403000039000001db040000410000000f060000290000000607000029000003a80000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000040e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000004060000413d000000000604004b0000041d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20430009c0000000003018019000001a20420009c000000000201801900000060012002100000004002300210000000000112019f0000068300010430000000400100043d0000004402100039000001ce030000410000000000320435000000240210003900000007030000290000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001c4011001c70000068300010430000000400100043d000001eb0310009c000002170000213d000001b602200197000000840310003900000000002304350000002402100039000001ec0300004100000000003204350000006402100039000000000300041400000020040000390000000000420435000000440210003900000010040000290000000000420435000001e902000041000000000021043500000004021000390000000000020435000001a202000041000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000121019f000001ed011001c70000800602000039068106770000040f00000001022001900000053c0000613d000000000101043b000000000201004b0000055e0000c13d00000003010003670000000102000031000005410000013d000000c001100210000001d1011001970000004002200210000001d202200041000001d302200197000000000121019f0000006002400210000001d402200197000000000121019f000001d5011001c700008006020000390000000003000019000000000400001900000000050000190000000006000019068106770000040f000300000001035500000000030100190000006003300270000101a20030019d000001a2053001970000003f03500039000001a306300197000000400400043d0000000003460019000000000663004b00000000060000190000000106004039000001bd0730009c000002170000213d0000000106600190000002170000c13d000000400030043f00000000035404360000001f0650003900000005066002720000048f0000613d0000000007000031000000020770036700000000080000190000000509800210000000000a930019000000000997034f000000000909043b00000000009a04350000000108800039000000000968004b000004870000413d000000000600004b000004910000613d0000001f0650018f00000005055002720000049d0000613d000000000700001900000005087002100000000009830019000000000881034f000000000808043b00000000008904350000000107700039000000000857004b000004950000413d000000000706004b000004ac0000613d0000000505500210000000000151034f00000000055300190000000306600210000000000705043300000000076701cf000000000767022f000000000101043b0000010006600089000000000161022f00000000016101cf000000000171019f00000000001504350000000101200190000005ba0000613d0000000001040433000001c702000041000000200410008c00000000040000190000000004024019000001c701100197000000000501004b000000000200a019000001c70110009c000000000204c019000000000102004b000000400000c13d0000000001030433000800000001001d000001b60110009c000000400000213d000001b901000041000000000010043900000008010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000f020000290000000b04000029000000400000613d000000400300043d000001d701000041000000000013043500000024053000390000000901000029000300000005001d00000000001504350000000401300039000200000001001d00000000002104350000001f0240018f0000006401300039000900000003001d0000004403300039000100000003001d0000000000430435000000100300002900000002033003670000000504400272000004ee0000613d000000000500001900000005065002100000000007610019000000000663034f000000000606043b00000000006704350000000105500039000000000645004b000004e60000413d000000000502004b000004fd0000613d0000000504400210000000000343034f00000000044100190000000302200210000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f00000000002404350000000b01100029000000000001043500000000010004140000000802000029000000040220008c0000051e0000613d0000000b020000290000001f022000390000000a0220017f000001a2030000410000000905000029000001a20450009c0000000004030019000000000405401900000040044002100000006402200039000001a20520009c00000000020380190000006002200210000000000224019f000001a20410009c0000000001038019000000c001100210000000000121019f0000000802000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005db0000613d0000000901000029000001bd0110009c000002170000213d0000000901000029000000400010043f0000000802000029000000050120014f000001b601100198000005f80000c13d000000060100002900000000001004350000000401000029000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f00000001022001900000000f03000029000000400000613d000000000101043b000000000201041a000001d902200197000000000232019f000000000021041b000003af0000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000054e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005460000413d000000000604004b0000055d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000041d0000013d000001b6031001970000000101000039000000000201041a000001d902200197000000000232019f000000000021041b00000002010000390000000f02000029000000000021041b000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400300043d000001ee010000410000000000130435000c00000003001d0000000401300039000000000021043500000000010004140000001002000029000000040220008c000005960000613d000001a202000041000001a20310009c00000000010280190000000c04000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001ef011001c70000001002000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005be0000613d0000000c01000029000001bd0110009c000002170000213d0000000c01000029000000400010043f000003940000013d000000000001042f000000400200043d0000001f0430018f0000000505300272000005aa0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005a20000413d000000000604004b000005b90000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400100043d0000004402100039000001d603000041000004290000013d000000400200043d0000001f0430018f0000000505300272000005cb0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005c30000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400200043d0000001f0430018f0000000505300272000005e80000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005e00000413d000000000604004b000005f70000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000001a60100004100000009030000290000000000130435000000200100003900000002020000290000000000120435000000070100002900000003020000290000000000120435000001d80100004100000001020000290000000000120435000002bb0000013d0001000000000002000100000001001d0000000101000039000000000301041a000000400100043d00000040021000390000004004000039000000000042043500000060020000390000000002210436000001b603300197000000000032043500000060031000390000000000030435000001f60310009c000006580000813d0000008003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d0000000202000039000000000202041a000000000301043b000000400100043d000000a0041000390000000000340435000000800310003900000000002304350000000102000029000001b602200197000000600310003900000000002304350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000006580000213d000000c003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d000000000101043b000001b601100197000000000001042d000001f00100004100000000001004350000004101000039000000040010043f000001ef01000041000006830001043000000000010000190000068300010430000000000001042f000001a203000041000001a20410009c00000000010380190000004001100210000001a20420009c00000000020380190000006002200210000000000112019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000006750000613d000000000101043b000000000001042d000000000100001900000683000104300000067a002104210000000102000039000000000001042d0000000002000019000000000001042d0000067f002104230000000102000039000000000001042d0000000002000019000000000001042d0000068100000432000006820001042e0000068300010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe0616c697a696e6700000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320696e69746908c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000002000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000cfe7af7b00000000000000000000000000000000000000000000000000000000f54266a100000000000000000000000000000000000000000000000000000000f54266a200000000000000000000000000000000000000000000000000000000f5f1516800000000000000000000000000000000000000000000000000000000cfe7af7c00000000000000000000000000000000000000000000000000000000d9caed1200000000000000000000000000000000000000000000000000000000a31ee5af00000000000000000000000000000000000000000000000000000000a31ee5b000000000000000000000000000000000000000000000000000000000b852ad36000000000000000000000000000000000000000000000000000000006dde720900000000000000000000000000000000000000000000000000000000969b53da000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000008000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83020000020000000000000000000000000000002400000000000000000000000074f4f547000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff020000000000000000000000000000000000004000000000000000000000000011a2ccc100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f62f84b24000000000000000000000000000000000000000000000000000000002fc3848834aac8e883a2d2a17a7514dc4f2d3dd268089df9b9f5d918259ef3b079680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000416d6f756e742063616e6e6f74206265207a65726f000000000000000000000000000000000000000000000000000000000000640000008000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeffffffffffffffffffffffffffffffffeeef6d710000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000060000000a000000000000000002020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494000000000000000000000000000000000000000000000000ffffffffffffff3f020000000000000000000000000000000000000000000000000000000000000067670000000000000000000000000000000000000000000000000000000000003cda335100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffff00000000000000000000000001000000000000000000000000000000000000000000000000000000000000006d6b00000000000000000000000000000000000000000000000000000000000095f11a40000000000000000000000000000000000000000000000000000000006d74000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000008c2a993e00000000000000000000000000000000000000000000000000000000b84fba9af218da60d299dc177abd5805e7ac541d2673cbee7808c10017874f634f766572666c6f77000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65640000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000000000000000000000000000000000000000010200000000000000000000ffffffffffffffffffffffffffffffffffffffff0000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e02000002000000000000000000000000000000440000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7c010004751688ab9322961547058fd0f36d3edf69880b64cbb2857041d33f4a133cda33511d41a8a5431b1770c5bc0ddd62e1cd30555d16659b89c0d60f4f9f570200000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7b010000691fa4f751f8312bc555242f18ed78cdc9aabc0ea77d7d5a675ee8ac6f02000000000000000000000000000000000000a4000000000000000000000000f2fde38b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6266320000000000000000000000000000000000000000000000000000000000736600000000000000000000000000000000000000000000000000000000000064660000000000000000000000000000000000000000000000000000000000006266000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff800000000000000000000000000000000000000000000000000000000000000000f5cf0be6820df44d868e986d4d5cafabd5702ac45d181a5ac4eb5ed59a001b03", + "linkReferences": {}, + "deployedLinkReferences": {}, + "factoryDeps": { + "0x010000691fa4f751f8312bc555242f18ed78cdc9aabc0ea77d7d5a675ee8ac6f": "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol:UpgradeableBeacon", + "0x010004751688ab9322961547058fd0f36d3edf69880b64cbb2857041d33f4a13": "contracts/bridge/L2StandardERC20.sol:L2StandardERC20" + } +} diff --git a/l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json b/l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json new file mode 100644 index 000000000..c8880c120 --- /dev/null +++ b/l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json @@ -0,0 +1,86 @@ +{ + "_format": "hh-zksolc-artifact-1", + "contractName": "TransparentUpgradeableProxy", + "sourceName": "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x00020000000000020008000000000002000000000301001900000060033002700000012c0330019700010000003103550000008008000039000000400080043f00000001022001900000001e0000c13d000000000431034f00000000050004110000013d02000041000000000702041a0000013002700197000000000603004b000000270000c13d000000000325004b0000010c0000c13d000000000101043b0000014101100197000001420310009c0000001b0000613d000001430310009c000002c20000613d000001440310009c000002680000c13d00000000010004160000000001000019000004ac000104300000012d023000410000012e0220009c0000005f0000213d000001520100004100000000001004350000004101000039000000040010043f0000015301000041000004ac00010430000000000525004b0000012d0000c13d000000000401043b0000014104400197000001420540009c000001670000c13d0000000002000416000000000202004b000002c20000c13d000000240230008c000002c20000413d0000000401100370000000000201043b000001300120009c000002c20000213d000000a001000039000000400010043f000000800000043f00000133010000410000000000100439000800000002001d00000004002004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002a80000c13d000000400100043d00000064021000390000015403000041000000000032043500000044021000390000015503000041000000000032043500000024021000390000002d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014c011001c7000004ac000104300000009f023000390000012f02200197000000400020043f0000001f0230018f00000005043002720000006e0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000660000413d000000000502004b0000007d0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000005f0130008c000002c20000a13d000000800900043d000001300190009c000002c20000213d000000a00700043d000001300170009c000002c20000213d000000c00200043d000001310120009c000002c20000213d0000001f012000390000013204000041000000000531004b000000000500001900000000050480190000013201100197000000000601004b0000000004008019000001320110009c000000000405c019000000000104004b000002c20000c13d00000080012000390000000001010433000001310410009c000000210000213d0000003f04100039000000200a00008a0000000004a4016f000000400b00043d00000000044b00190000000005b4004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d0000008003300039000000400040043f00000000061b0436000000a0022000390000000004210019000000000334004b000002c20000213d00060000000b001d00050000000a001d000700000007001d000300000008001d000000000301004b000000b90000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b000000b20000413d000400000006001d0000000001160019000000000001043500000133010000410000000000100439000800000009001d00000004009004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d000000080100002900000130051001970000013501000041000000000201041a0000013602200197000000000252019f000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f0000000803000029000000010120019000000007020000290000000605000029000002c20000613d0000000001050433000000000101004b000003770000c13d0000013d01000041000000000301041a0000013004200197000000400100043d0000002002100039000800000004001d0000000000420435000700000003001d000001300230019700000000002104350000012c0200004100000000030004140000012c0430009c00000000030280190000012c0410009c00000000010280190000004001100210000000c002300210000000000112019f0000013e011001c70000800d0200003900000001030000390000013f0400004104aa049b0000040f0000000101200190000002c20000613d000000080100006b0000025a0000613d0000000701000029000001360110019700000008011001af0000013d02000041000000000012041b0000002001000039000001000010044300000120000004430000014001000041000004ab0001042e0000013501000041000000000201041a00000000010004140000013002200197000000040320008c000001e90000c13d00000000030000310000001f0230018f00000005013002720000011e0000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001170000413d000000000502004b0000020e0000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f00000000002104350000020e0000013d0000001f0530018f0000013502000041000000000202041a000001300220019700000005063002720000013b0000613d00000000070000190000000508700210000000000981034f000000000909043b00000000009804350000000107700039000000000867004b000001340000413d000000000705004b000001490000613d00000003055002100000000506600210000000000706043300000000075701cf000000000757022f000000000161034f000000000101043b0000010005500089000000000151022f00000000015101cf000000000171019f00000000001604350000000001000414000000040520008c0000020f0000c13d00000000030000310000001f0230018f0000000501300272000001580000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001510000413d000000000502004b000002360000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f0000000000210435000002360000013d000001430540009c0000023b0000c13d000000440230008c000002c20000413d0000000402100370000000000802043b000001300280009c000002c20000213d0000002402100370000000000402043b000001310240009c000002c20000213d00000023024000390000013205000041000000000632004b000000000600001900000000060580190000013202200197000000000702004b0000000005008019000001320220009c000000000506c019000000000205004b000002c20000c13d0000000405400039000000000251034f000000000202043b000001310620009c000000210000213d000000bf06200039000000200900008a000000000696016f000001310760009c000000210000213d000000400060043f000000800020043f00000000042400190000002404400039000000000334004b000002c20000213d0000002003500039000000000131034f0000001f0320018f00000005042002720000019d0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000001950000413d000700000009001d000000000503004b000001ad0000613d0000000504400210000000000141034f0000000303300210000000a004400039000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000140435000000a001200039000000000001043500000133010000410000000000100439000800000008001d00000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d0000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008030000290000000101200190000002c20000613d000000400100043d000600000001001d000001390110009c000000210000213d00000006040000290000006001400039000000400010043f00000040014000390000013a02000041000000000021043500000020014000390000013b02000041000000000021043500000027010000390000000000140435000000800200043d0000000001000414000000040330008c0000040d0000c13d000000010200003900000000040000310000041d0000013d0000012c030000410000012c0410009c0000000001038019000000c00110021004aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000001fe0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001f70000413d000000000604004b0000020c0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002640000613d000002360000013d0000012c040000410000012c0510009c0000000001048019000000c0011002100000006003300210000000000131019f04aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000002260000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b0000021f0000413d000000000604004b000002340000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002660000613d0000012c010000410000012c0230009c00000000030180190000006001300210000004ab0001042e000001440540009c0000026e0000c13d0000000004000416000000000404004b000002c20000c13d000000240330008c000002c20000413d0000000401100370000000000401043b000001300140009c000002c20000213d000000800020043f000000a00040043f0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000148011001c70000800d020000390000000103000039000700000004001d0000013f04000041000800000007001d04aa049b0000040f000000070400002900000008030000290000000101200190000002c20000613d000000000104004b000002c40000c13d000000400100043d00000064021000390000014a03000041000000000032043500000044021000390000014b03000041000000000032043500000024021000390000002603000039000000530000013d0000006001300210000004ac000104300000006001300210000004ac00010430000001450310009c000002750000c13d0000000001000416000000000101004b000002c20000c13d0000027d0000013d000001450140009c000002840000c13d0000000001000416000000000101004b000002c20000c13d000000a00020043f0000028d0000013d000001460110009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013002100197000000a00020043f0000002001000039000000800010043f000000c001000039000000400010043f0000015a01000041000004ab0001042e000001460140009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013001100197000000a00010043f0000002001000039000000800010043f000000c001000039000000400010043f000000800100003900000147020000410000015003000041000001500410009c000000000103801900000040011002100000015101100041000000000121019f000004ab0001042e0000013c01000041000000800010043f0000002001000039000000840010043f0000004201000039000000a40010043f0000015601000041000000c40010043f0000015701000041000000e40010043f0000015801000041000001040010043f0000015901000041000004ac000104300000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008080000290000000101200190000002c20000613d000000800100043d000000000101004b000002d00000c13d000000400100043d000001490210009c000000210000213d000002cb0000013d0000000001000019000004ac000104300000013601300197000000000114019f0000013d02000041000000000012041b000000400100043d000001490210009c000000210000213d0000002002100039000000400020043f00000000000104350000000002000019000002930000013d000000400900043d000001390190009c000000210000213d0000006001900039000000400010043f00000040019000390000013a02000041000000000021043500000020019000390000013b02000041000000000021043500000027010000390000000000190435000000800200043d0000000001000414000000040380008c000002e40000c13d00000001020000390000000004000031000002f70000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c70000000002080019000700000009001d04aa04a50000040f00000007090000290000000808000029000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b000003230000c13d0000000003030433000000000202004b000003530000c13d000000000203004b0000038c0000c13d000000400100043d0000013c0200004100000000002104350000000402100039000000200300003900000000003204350000000002090433000000240310003900000000002304350000004403100039000000000402004b000003140000613d000000000400001900000000053400190000002004400039000000000694001900000000060604330000000000650435000000000524004b0000030d0000413d0000001f04200039000000200500008a000000000454016f0000000002320019000000000002043500000044024000390000012c030000410000012c0420009c00000000020380190000012c0410009c000000000103801900000040011002100000006002200210000000000112019f000004ac00010430000001310140009c000000210000213d0000003f01400039000000200300008a000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000000a090019000000400010043f0000001f0540018f000000000143043600000001060003670000000504400272000003410000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000003390000413d000000000705004b000000080800002900000000090a0019000002fb0000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000002fb0000013d000000000103004b000002be0000c13d0000013301000041000000000010043900000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002be0000c13d000000400100043d00000044021000390000014e03000041000000000032043500000024021000390000001d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014f011001c7000004ac00010430000000400400043d000001390140009c000000210000213d0000006001400039000000400010043f00000040014000390000013a0200004100000000002104350000002701000039000200000004001d00000000021404360000013b01000041000100000002001d000000000012043500000000020504330000000001000414000000040330008c000003950000c13d00000001020000390000000003000031000003a90000013d0000012c020000410000012c0430009c00000000030280190000012c0410009c000000000102801900000040011002100000006002300210000000000112019f000004ac000104300000012c0300004100000004050000290000012c0450009c000000000503801900000040045002100000012c0520009c00000000020380190000006002200210000000000242019f0000012c0410009c0000000001038019000000c001100210000000000112019f000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c031001970000006001000039000000000403004b000003c90000c13d0000000001010433000000000202004b000003f70000c13d000000000201004b000004830000c13d000000400400043d000800000004001d0000013c01000041000000000014043500000004014000390000002002000039000000000021043500000002010000290000000003010433000700000003001d000000240140003900000000003104350000004402400039000000010100002904aa048d0000040f00000007010000290000001f01100039000000050110017f00000044011000390000012c020000410000012c0310009c00000000010280190000000804000029000004870000013d000001310130009c0000000504000029000000210000213d0000003f01300039000000000441016f000000400100043d0000000004410019000000000514004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d000000400040043f0000001f0430018f000000000931043600000001050003670000000503300272000003e60000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b000003de0000413d000300000009001d000000000604004b000003ac0000613d0000000503300210000000000535034f00000003033000290000000304400210000000000603043300000000064601cf000000000646022f000000000505043b0000010004400089000000000545022f00000000044501cf000000000464019f0000000000430435000003ac0000013d000000000101004b00000007020000290000000803000029000000e60000c13d0000013301000041000000000010043900000004003004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000000702000029000000e60000c13d000003650000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c7000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b0000043e0000c13d0000000003030433000000000202004b0000046b0000c13d000000000203004b0000038c0000c13d000000400100043d0000013c02000041000000000021043500000004021000390000002003000039000000000032043500000006070000290000000002070433000000240310003900000000002304350000004403100039000000000402004b0000043b0000613d000000000400001900000000053400190000002004400039000000000674001900000000060604330000000000650435000000000524004b000004340000413d0000001f042000390000000705000029000003160000013d000001310140009c0000000703000029000000210000213d0000003f01400039000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000400010043f0000001f0540018f0000000001430436000000010600036700000005044002720000045b0000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000004530000413d000000000705004b000004210000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000004210000013d000000000103004b0000047e0000c13d00000133010000410000000000100439000000080100002900000004001004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000003650000613d000000400100043d000001490210009c000000210000213d000002cb0000013d000000000001042f0000012c020000410000012c0310009c000000000102801900000003040000290000012c0340009c000000000402801900000040024002100000006001100210000000000121019f000004ac00010430000000000403004b000004970000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000004900000413d00000000012300190000000000010435000000000001042d000000000001042f0000049e002104210000000102000039000000000001042d0000000002000019000000000001042d000004a3002104230000000102000039000000000001042d0000000002000019000000000001042d000004a8002104250000000102000039000000000001042d0000000002000019000000000001042d000004aa00000432000004ab0001042e000004ac0001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcffffffffffffffffffffffff00000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c08c379a000000000000000000000000000000000000000000000000000000000b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610302000000000000000000000000000000000000400000000000000000000000007e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f0000000200000000000000000000000000000040000001000000000000000000ffffffff000000000000000000000000000000000000000000000000000000003659cfe6000000000000000000000000000000000000000000000000000000004f1ef286000000000000000000000000000000000000000000000000000000008f28397000000000000000000000000000000000000000000000000000000000f851a440000000000000000000000000000000000000000000000000000000005c60da1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000200000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf6464726573730000000000000000000000000000000000000000000000000000455243313936373a206e65772061646d696e20697320746865207a65726f206100000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffdf00000000000000000000000000000000000000000000002000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000006f74206120636f6e747261637400000000000000000000000000000000000000455243313936373a206e657720696d706c656d656e746174696f6e206973206e5472616e73706172656e745570677261646561626c6550726f78793a2061646d696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40000008000000000000000000000000000000000000000000000000000000020000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000007444ff0b02dc9864c7dbf97ccd7719c286d6972190eeb0285ea9e04a713977c0", + "deployedBytecode": "0x00020000000000020008000000000002000000000301001900000060033002700000012c0330019700010000003103550000008008000039000000400080043f00000001022001900000001e0000c13d000000000431034f00000000050004110000013d02000041000000000702041a0000013002700197000000000603004b000000270000c13d000000000325004b0000010c0000c13d000000000101043b0000014101100197000001420310009c0000001b0000613d000001430310009c000002c20000613d000001440310009c000002680000c13d00000000010004160000000001000019000004ac000104300000012d023000410000012e0220009c0000005f0000213d000001520100004100000000001004350000004101000039000000040010043f0000015301000041000004ac00010430000000000525004b0000012d0000c13d000000000401043b0000014104400197000001420540009c000001670000c13d0000000002000416000000000202004b000002c20000c13d000000240230008c000002c20000413d0000000401100370000000000201043b000001300120009c000002c20000213d000000a001000039000000400010043f000000800000043f00000133010000410000000000100439000800000002001d00000004002004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002a80000c13d000000400100043d00000064021000390000015403000041000000000032043500000044021000390000015503000041000000000032043500000024021000390000002d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014c011001c7000004ac000104300000009f023000390000012f02200197000000400020043f0000001f0230018f00000005043002720000006e0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000660000413d000000000502004b0000007d0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000005f0130008c000002c20000a13d000000800900043d000001300190009c000002c20000213d000000a00700043d000001300170009c000002c20000213d000000c00200043d000001310120009c000002c20000213d0000001f012000390000013204000041000000000531004b000000000500001900000000050480190000013201100197000000000601004b0000000004008019000001320110009c000000000405c019000000000104004b000002c20000c13d00000080012000390000000001010433000001310410009c000000210000213d0000003f04100039000000200a00008a0000000004a4016f000000400b00043d00000000044b00190000000005b4004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d0000008003300039000000400040043f00000000061b0436000000a0022000390000000004210019000000000334004b000002c20000213d00060000000b001d00050000000a001d000700000007001d000300000008001d000000000301004b000000b90000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b000000b20000413d000400000006001d0000000001160019000000000001043500000133010000410000000000100439000800000009001d00000004009004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d000000080100002900000130051001970000013501000041000000000201041a0000013602200197000000000252019f000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f0000000803000029000000010120019000000007020000290000000605000029000002c20000613d0000000001050433000000000101004b000003770000c13d0000013d01000041000000000301041a0000013004200197000000400100043d0000002002100039000800000004001d0000000000420435000700000003001d000001300230019700000000002104350000012c0200004100000000030004140000012c0430009c00000000030280190000012c0410009c00000000010280190000004001100210000000c002300210000000000112019f0000013e011001c70000800d0200003900000001030000390000013f0400004104aa049b0000040f0000000101200190000002c20000613d000000080100006b0000025a0000613d0000000701000029000001360110019700000008011001af0000013d02000041000000000012041b0000002001000039000001000010044300000120000004430000014001000041000004ab0001042e0000013501000041000000000201041a00000000010004140000013002200197000000040320008c000001e90000c13d00000000030000310000001f0230018f00000005013002720000011e0000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001170000413d000000000502004b0000020e0000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f00000000002104350000020e0000013d0000001f0530018f0000013502000041000000000202041a000001300220019700000005063002720000013b0000613d00000000070000190000000508700210000000000981034f000000000909043b00000000009804350000000107700039000000000867004b000001340000413d000000000705004b000001490000613d00000003055002100000000506600210000000000706043300000000075701cf000000000757022f000000000161034f000000000101043b0000010005500089000000000151022f00000000015101cf000000000171019f00000000001604350000000001000414000000040520008c0000020f0000c13d00000000030000310000001f0230018f0000000501300272000001580000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001510000413d000000000502004b000002360000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f0000000000210435000002360000013d000001430540009c0000023b0000c13d000000440230008c000002c20000413d0000000402100370000000000802043b000001300280009c000002c20000213d0000002402100370000000000402043b000001310240009c000002c20000213d00000023024000390000013205000041000000000632004b000000000600001900000000060580190000013202200197000000000702004b0000000005008019000001320220009c000000000506c019000000000205004b000002c20000c13d0000000405400039000000000251034f000000000202043b000001310620009c000000210000213d000000bf06200039000000200900008a000000000696016f000001310760009c000000210000213d000000400060043f000000800020043f00000000042400190000002404400039000000000334004b000002c20000213d0000002003500039000000000131034f0000001f0320018f00000005042002720000019d0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000001950000413d000700000009001d000000000503004b000001ad0000613d0000000504400210000000000141034f0000000303300210000000a004400039000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000140435000000a001200039000000000001043500000133010000410000000000100439000800000008001d00000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d0000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008030000290000000101200190000002c20000613d000000400100043d000600000001001d000001390110009c000000210000213d00000006040000290000006001400039000000400010043f00000040014000390000013a02000041000000000021043500000020014000390000013b02000041000000000021043500000027010000390000000000140435000000800200043d0000000001000414000000040330008c0000040d0000c13d000000010200003900000000040000310000041d0000013d0000012c030000410000012c0410009c0000000001038019000000c00110021004aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000001fe0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001f70000413d000000000604004b0000020c0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002640000613d000002360000013d0000012c040000410000012c0510009c0000000001048019000000c0011002100000006003300210000000000131019f04aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000002260000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b0000021f0000413d000000000604004b000002340000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002660000613d0000012c010000410000012c0230009c00000000030180190000006001300210000004ab0001042e000001440540009c0000026e0000c13d0000000004000416000000000404004b000002c20000c13d000000240330008c000002c20000413d0000000401100370000000000401043b000001300140009c000002c20000213d000000800020043f000000a00040043f0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000148011001c70000800d020000390000000103000039000700000004001d0000013f04000041000800000007001d04aa049b0000040f000000070400002900000008030000290000000101200190000002c20000613d000000000104004b000002c40000c13d000000400100043d00000064021000390000014a03000041000000000032043500000044021000390000014b03000041000000000032043500000024021000390000002603000039000000530000013d0000006001300210000004ac000104300000006001300210000004ac00010430000001450310009c000002750000c13d0000000001000416000000000101004b000002c20000c13d0000027d0000013d000001450140009c000002840000c13d0000000001000416000000000101004b000002c20000c13d000000a00020043f0000028d0000013d000001460110009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013002100197000000a00020043f0000002001000039000000800010043f000000c001000039000000400010043f0000015a01000041000004ab0001042e000001460140009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013001100197000000a00010043f0000002001000039000000800010043f000000c001000039000000400010043f000000800100003900000147020000410000015003000041000001500410009c000000000103801900000040011002100000015101100041000000000121019f000004ab0001042e0000013c01000041000000800010043f0000002001000039000000840010043f0000004201000039000000a40010043f0000015601000041000000c40010043f0000015701000041000000e40010043f0000015801000041000001040010043f0000015901000041000004ac000104300000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008080000290000000101200190000002c20000613d000000800100043d000000000101004b000002d00000c13d000000400100043d000001490210009c000000210000213d000002cb0000013d0000000001000019000004ac000104300000013601300197000000000114019f0000013d02000041000000000012041b000000400100043d000001490210009c000000210000213d0000002002100039000000400020043f00000000000104350000000002000019000002930000013d000000400900043d000001390190009c000000210000213d0000006001900039000000400010043f00000040019000390000013a02000041000000000021043500000020019000390000013b02000041000000000021043500000027010000390000000000190435000000800200043d0000000001000414000000040380008c000002e40000c13d00000001020000390000000004000031000002f70000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c70000000002080019000700000009001d04aa04a50000040f00000007090000290000000808000029000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b000003230000c13d0000000003030433000000000202004b000003530000c13d000000000203004b0000038c0000c13d000000400100043d0000013c0200004100000000002104350000000402100039000000200300003900000000003204350000000002090433000000240310003900000000002304350000004403100039000000000402004b000003140000613d000000000400001900000000053400190000002004400039000000000694001900000000060604330000000000650435000000000524004b0000030d0000413d0000001f04200039000000200500008a000000000454016f0000000002320019000000000002043500000044024000390000012c030000410000012c0420009c00000000020380190000012c0410009c000000000103801900000040011002100000006002200210000000000112019f000004ac00010430000001310140009c000000210000213d0000003f01400039000000200300008a000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000000a090019000000400010043f0000001f0540018f000000000143043600000001060003670000000504400272000003410000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000003390000413d000000000705004b000000080800002900000000090a0019000002fb0000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000002fb0000013d000000000103004b000002be0000c13d0000013301000041000000000010043900000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002be0000c13d000000400100043d00000044021000390000014e03000041000000000032043500000024021000390000001d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014f011001c7000004ac00010430000000400400043d000001390140009c000000210000213d0000006001400039000000400010043f00000040014000390000013a0200004100000000002104350000002701000039000200000004001d00000000021404360000013b01000041000100000002001d000000000012043500000000020504330000000001000414000000040330008c000003950000c13d00000001020000390000000003000031000003a90000013d0000012c020000410000012c0430009c00000000030280190000012c0410009c000000000102801900000040011002100000006002300210000000000112019f000004ac000104300000012c0300004100000004050000290000012c0450009c000000000503801900000040045002100000012c0520009c00000000020380190000006002200210000000000242019f0000012c0410009c0000000001038019000000c001100210000000000112019f000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c031001970000006001000039000000000403004b000003c90000c13d0000000001010433000000000202004b000003f70000c13d000000000201004b000004830000c13d000000400400043d000800000004001d0000013c01000041000000000014043500000004014000390000002002000039000000000021043500000002010000290000000003010433000700000003001d000000240140003900000000003104350000004402400039000000010100002904aa048d0000040f00000007010000290000001f01100039000000050110017f00000044011000390000012c020000410000012c0310009c00000000010280190000000804000029000004870000013d000001310130009c0000000504000029000000210000213d0000003f01300039000000000441016f000000400100043d0000000004410019000000000514004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d000000400040043f0000001f0430018f000000000931043600000001050003670000000503300272000003e60000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b000003de0000413d000300000009001d000000000604004b000003ac0000613d0000000503300210000000000535034f00000003033000290000000304400210000000000603043300000000064601cf000000000646022f000000000505043b0000010004400089000000000545022f00000000044501cf000000000464019f0000000000430435000003ac0000013d000000000101004b00000007020000290000000803000029000000e60000c13d0000013301000041000000000010043900000004003004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000000702000029000000e60000c13d000003650000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c7000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b0000043e0000c13d0000000003030433000000000202004b0000046b0000c13d000000000203004b0000038c0000c13d000000400100043d0000013c02000041000000000021043500000004021000390000002003000039000000000032043500000006070000290000000002070433000000240310003900000000002304350000004403100039000000000402004b0000043b0000613d000000000400001900000000053400190000002004400039000000000674001900000000060604330000000000650435000000000524004b000004340000413d0000001f042000390000000705000029000003160000013d000001310140009c0000000703000029000000210000213d0000003f01400039000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000400010043f0000001f0540018f0000000001430436000000010600036700000005044002720000045b0000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000004530000413d000000000705004b000004210000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000004210000013d000000000103004b0000047e0000c13d00000133010000410000000000100439000000080100002900000004001004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000003650000613d000000400100043d000001490210009c000000210000213d000002cb0000013d000000000001042f0000012c020000410000012c0310009c000000000102801900000003040000290000012c0340009c000000000402801900000040024002100000006001100210000000000121019f000004ac00010430000000000403004b000004970000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000004900000413d00000000012300190000000000010435000000000001042d000000000001042f0000049e002104210000000102000039000000000001042d0000000002000019000000000001042d000004a3002104230000000102000039000000000001042d0000000002000019000000000001042d000004a8002104250000000102000039000000000001042d0000000002000019000000000001042d000004aa00000432000004ab0001042e000004ac0001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcffffffffffffffffffffffff00000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c08c379a000000000000000000000000000000000000000000000000000000000b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610302000000000000000000000000000000000000400000000000000000000000007e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f0000000200000000000000000000000000000040000001000000000000000000ffffffff000000000000000000000000000000000000000000000000000000003659cfe6000000000000000000000000000000000000000000000000000000004f1ef286000000000000000000000000000000000000000000000000000000008f28397000000000000000000000000000000000000000000000000000000000f851a440000000000000000000000000000000000000000000000000000000005c60da1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000200000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf6464726573730000000000000000000000000000000000000000000000000000455243313936373a206e65772061646d696e20697320746865207a65726f206100000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffdf00000000000000000000000000000000000000000000002000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000006f74206120636f6e747261637400000000000000000000000000000000000000455243313936373a206e657720696d706c656d656e746174696f6e206973206e5472616e73706172656e745570677261646561626c6550726f78793a2061646d696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40000008000000000000000000000000000000000000000000000000000000020000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000007444ff0b02dc9864c7dbf97ccd7719c286d6972190eeb0285ea9e04a713977c0", + "linkReferences": {}, + "deployedLinkReferences": {}, + "factoryDeps": {} +} From 1e0df108611136e48d5aa6c9739041ed1014e0d8 Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:16:08 +0100 Subject: [PATCH 32/42] feat(l2): solidity 0.8.24 and zksolc 1.5.0 (#743) --- l2-contracts/contracts/ForceDeployUpgrader.sol | 2 +- l2-contracts/contracts/bridge/L2SharedBridge.sol | 2 +- l2-contracts/contracts/bridge/L2StandardERC20.sol | 2 +- l2-contracts/contracts/bridge/L2WrappedBaseToken.sol | 2 +- l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol | 2 +- l2-contracts/hardhat.config.ts | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/l2-contracts/contracts/ForceDeployUpgrader.sol b/l2-contracts/contracts/ForceDeployUpgrader.sol index 9abb22555..46f9e4fd8 100644 --- a/l2-contracts/contracts/ForceDeployUpgrader.sol +++ b/l2-contracts/contracts/ForceDeployUpgrader.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {IContractDeployer, DEPLOYER_SYSTEM_CONTRACT} from "./L2ContractHelper.sol"; diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index 1db972714..d4e7b7900 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {Initializable} from "@openzeppelin/contracts-v4/proxy/utils/Initializable.sol"; import {BeaconProxy} from "@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol"; diff --git a/l2-contracts/contracts/bridge/L2StandardERC20.sol b/l2-contracts/contracts/bridge/L2StandardERC20.sol index e28cf41b5..90db45814 100644 --- a/l2-contracts/contracts/bridge/L2StandardERC20.sol +++ b/l2-contracts/contracts/bridge/L2StandardERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; import {UpgradeableBeacon} from "@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol"; diff --git a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol index 1166fa008..8ff9f814e 100644 --- a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol +++ b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; diff --git a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol index e383d83c3..e93d5c987 100644 --- a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol +++ b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import {L2SharedBridge} from "../bridge/L2SharedBridge.sol"; import {L2StandardERC20} from "../bridge/L2StandardERC20.sol"; diff --git a/l2-contracts/hardhat.config.ts b/l2-contracts/hardhat.config.ts index c0aaca03e..282ab7b96 100644 --- a/l2-contracts/hardhat.config.ts +++ b/l2-contracts/hardhat.config.ts @@ -12,14 +12,14 @@ if (!process.env.CHAIN_ETH_NETWORK) { export default { zksolc: { - version: "1.3.18", + version: "1.5.0", compilerSource: "binary", settings: { isSystem: true, }, }, solidity: { - version: "0.8.20", + version: "0.8.24", }, defaultNetwork: "localhost", networks: { From f2d553b34f0eeb99e5668c33b57659d683cf99cb Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:17:06 +0100 Subject: [PATCH 33/42] feat(l1): added missing foundry lib symlinks (#741) --- l1-contracts/foundry.toml | 10 +++++----- l1-contracts/lib/forge-std | 1 + l1-contracts/lib/murky | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) create mode 120000 l1-contracts/lib/forge-std create mode 120000 l1-contracts/lib/murky diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index 04fd5c656..4d52d0400 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -1,7 +1,7 @@ [profile.default] src = "contracts" out = "out" -libs = ["node_modules", "../lib"] +libs = ["lib"] cache_path = "cache-forge" test = "test/foundry" solc_version = "0.8.24" @@ -20,9 +20,9 @@ fs_permissions = [ ignored_error_codes = ["missing-receive-ether", "code-size"] ignored_warnings_from = ["test", "contracts/dev-contracts"] remappings = [ - "forge-std/=../lib/forge-std/src/", - "murky/=../lib/murky/src/", + "forge-std/=lib/forge-std/src/", + "murky/=lib/murky/src/", "foundry-test/=test/foundry/", - "@openzeppelin/contracts-v4/=./lib/openzeppelin-contracts-v4/contracts/", - "@openzeppelin/contracts-upgradeable-v4/=./lib/openzeppelin-contracts-upgradeable-v4/contracts/", + "@openzeppelin/contracts-v4/=lib/openzeppelin-contracts-v4/contracts/", + "@openzeppelin/contracts-upgradeable-v4/=lib/openzeppelin-contracts-upgradeable-v4/contracts/", ] diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std new file mode 120000 index 000000000..edce15694 --- /dev/null +++ b/l1-contracts/lib/forge-std @@ -0,0 +1 @@ +../../lib/forge-std \ No newline at end of file diff --git a/l1-contracts/lib/murky b/l1-contracts/lib/murky new file mode 120000 index 000000000..a556a15e5 --- /dev/null +++ b/l1-contracts/lib/murky @@ -0,0 +1 @@ +../../lib/murky \ No newline at end of file From 383e1b0147f3d23f2cba416b1003b208f9724a6a Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:18:14 +0100 Subject: [PATCH 34/42] docs: update zkSync casing to ZKsync (#733) --- CONTRIBUTING.md | 2 +- README.md | 12 ++-- docs/Overview.md | 24 ++++---- gas-bound-caller/README.md | 2 +- .../test-contracts/SystemContractsCaller.sol | 2 +- l1-contracts/README.md | 6 +- .../contracts/bridge/L1ERC20Bridge.sol | 14 ++--- .../contracts/bridge/L1SharedBridge.sol | 32 +++++------ .../bridge/interfaces/IL1ERC20Bridge.sol | 4 +- .../bridge/interfaces/IL1SharedBridge.sol | 2 +- .../contracts/bridge/interfaces/IL2Bridge.sol | 2 +- .../contracts/bridge/interfaces/IWETH9.sol | 2 +- .../contracts/bridgehub/IBridgehub.sol | 2 +- l1-contracts/contracts/common/Config.sol | 6 +- .../contracts/common/Dependencies.sol | 2 +- .../contracts/common/L2ContractAddresses.sol | 2 +- l1-contracts/contracts/common/Messaging.sol | 2 +- .../contracts/common/ReentrancyGuard.sol | 2 +- .../common/interfaces/IL2ContractDeployer.sol | 4 +- .../common/libraries/L2ContractHelper.sol | 2 +- .../contracts/common/libraries/SemVer.sol | 2 +- .../common/libraries/UncheckedMath.sol | 2 +- .../common/libraries/UnsafeBytes.sol | 2 +- .../dev-contracts/RevertReceiveAccount.sol | 2 +- .../dev-contracts/RevertTransferERC20.sol | 2 +- .../contracts/governance/Governance.sol | 2 +- .../contracts/governance/IGovernance.sol | 2 +- .../IStateTransitionManager.sol | 2 +- .../state-transition/ValidatorTimelock.sol | 4 +- .../contracts/state-transition/Verifier.sol | 4 +- .../chain-deps/facets/Executor.sol | 2 +- .../chain-deps/facets/Mailbox.sol | 4 +- .../chain-interfaces/IAdmin.sol | 2 +- .../chain-interfaces/IDiamondInit.sol | 2 +- .../chain-interfaces/IExecutor.sol | 10 ++-- .../chain-interfaces/IGetters.sol | 2 +- .../chain-interfaces/ILegacyGetters.sol | 4 +- .../chain-interfaces/IMailbox.sol | 4 +- .../chain-interfaces/ITransactionFilterer.sol | 2 +- .../chain-interfaces/IVerifier.sol | 2 +- .../chain-interfaces/IZkSyncHyperchain.sol | 2 +- .../IZkSyncHyperchainBase.sol | 4 +- .../l2-deps/ISystemContext.sol | 2 +- .../state-transition/libraries/Diamond.sol | 2 +- .../state-transition/libraries/LibMap.sol | 2 +- .../state-transition/libraries/Merkle.sol | 2 +- .../libraries/PriorityQueue.sol | 2 +- .../libraries/TransactionValidator.sol | 6 +- .../contracts/vendor/AddressAliasHelper.sol | 2 +- l2-contracts/contracts/Dependencies.sol | 2 +- l2-contracts/contracts/L2ContractHelper.sol | 4 +- .../contracts/SystemContractsCaller.sol | 2 +- l2-contracts/contracts/TestnetPaymaster.sol | 2 +- .../bridge/interfaces/IL1ERC20Bridge.sol | 2 +- .../bridge/interfaces/IL1SharedBridge.sol | 2 +- .../bridge/interfaces/IL2SharedBridge.sol | 2 +- .../bridge/interfaces/IL2StandardToken.sol | 2 +- .../bridge/interfaces/IL2WrappedBaseToken.sol | 2 +- .../contracts/errors/L2ContractErrors.sol | 2 +- .../contracts/interfaces/IPaymaster.sol | 2 +- .../contracts/interfaces/IPaymasterFlow.sol | 2 +- .../contracts/vendor/AddressAliasHelper.sol | 2 +- system-contracts/README.md | 14 ++--- system-contracts/SystemContractsHashes.json | 56 +++++++++---------- system-contracts/bootloader/bootloader.yul | 24 ++++---- .../contracts/AccountCodeStorage.sol | 2 +- .../contracts/BootloaderUtilities.sol | 4 +- system-contracts/contracts/Constants.sol | 5 +- .../contracts/ContractDeployer.sol | 2 +- .../contracts/SystemContractErrors.sol | 3 +- .../contracts/abstract/SystemContractBase.sol | 2 +- .../contracts/interfaces/IAccount.sol | 2 +- .../interfaces/IAccountCodeStorage.sol | 2 +- .../contracts/interfaces/IBaseToken.sol | 2 +- .../interfaces/IBootloaderUtilities.sol | 2 +- .../contracts/interfaces/IComplexUpgrader.sol | 2 +- .../contracts/interfaces/ICompressor.sol | 2 +- .../interfaces/IContractDeployer.sol | 2 +- .../interfaces/IImmutableSimulator.sol | 2 +- .../interfaces/IKnownCodesStorage.sol | 2 +- .../contracts/interfaces/IL1Messenger.sol | 2 +- .../contracts/interfaces/IL2StandardToken.sol | 2 +- .../contracts/interfaces/IMailbox.sol | 2 +- .../contracts/interfaces/INonceHolder.sol | 2 +- .../contracts/interfaces/IPaymaster.sol | 2 +- .../contracts/interfaces/IPaymasterFlow.sol | 2 +- .../interfaces/IPubdataChunkPublisher.sol | 2 +- .../contracts/interfaces/ISystemContext.sol | 2 +- .../interfaces/ISystemContextDeprecated.sol | 2 +- .../contracts/libraries/EfficientCall.sol | 2 +- .../contracts/libraries/RLPEncoder.sol | 2 +- .../libraries/SystemContractHelper.sol | 2 +- .../libraries/SystemContractsCaller.sol | 4 +- .../contracts/libraries/TransactionHelper.sol | 16 +++--- .../libraries/UnsafeBytesCalldata.sol | 2 +- .../contracts/libraries/Utils.sol | 4 +- .../openzeppelin/token/ERC20/IERC20.sol | 2 +- .../token/ERC20/extensions/IERC20Permit.sol | 2 +- .../token/ERC20/utils/SafeERC20.sol | 2 +- .../contracts/openzeppelin/utils/Address.sol | 2 +- system-contracts/scripts/constants.ts | 2 +- system-contracts/scripts/deploy-preimages.ts | 6 +- system-contracts/scripts/utils.ts | 2 +- tools/data/verifier_contract_template.txt | 4 +- 104 files changed, 218 insertions(+), 220 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd3d45842..46bdeebac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ We aim to make it as easy as possible to contribute to the mission. This is stil and suggestions here too. Some resources to help: 1. [In-repo docs aimed at developers](docs) -2. [zkSync Era docs!](https://era.zksync.io/docs/) +2. [ZKsync Era docs!](https://era.zksync.io/docs/) 3. Company links can be found in the [repo's readme](README.md) ## Code of Conduct diff --git a/README.md b/README.md index 6e3e06aba..cc1425b5b 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -# zkSync Era: Smart Contracts +# ZKsync Era: Smart Contracts [![Logo](eraLogo.svg)](https://zksync.io/) -zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +ZKsync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring -or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +or re-auditing a single line of code. ZKsync Era also uses an LLVM-based compiler that will eventually let developers write smart contracts in C++, Rust and other popular languages. -This repository contains both L1 and L2 zkSync smart contracts. For their description see the +This repository contains both L1 and L2 ZKsync smart contracts. For their description see the [system overview](docs/Overview.md). ## Disclaimer @@ -17,7 +17,7 @@ others may not. ## License -zkSync Era contracts are distributed under the terms of the MIT license. +ZKsync Era contracts are distributed under the terms of the MIT license. See [LICENSE-MIT](LICENSE-MIT) for details. @@ -33,7 +33,7 @@ See [LICENSE-MIT](LICENSE-MIT) for details. ## Disclaimer -zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +ZKsync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! It is important to state that forking it now can potentially lead to missing important security updates, critical features, and performance improvements. diff --git a/docs/Overview.md b/docs/Overview.md index 6af3d407d..1db994729 100644 --- a/docs/Overview.md +++ b/docs/Overview.md @@ -1,6 +1,6 @@ # Overview -zkSync Era is a permissionless general-purpose ZK rollup. Similar to many L1 blockchains and sidechains it enables +ZKsync Era is a permissionless general-purpose ZK rollup. Similar to many L1 blockchains and sidechains it enables deployment and interaction with Turing-complete smart contracts. - L2 smart contracts are executed on a zkEVM. @@ -10,7 +10,7 @@ deployment and interaction with Turing-complete smart contracts. - There is no escape hatch mechanism yet, but there will be one. All data that is needed to restore the L2 state are also pushed on-chain. There are two approaches, publishing inputs of -L2 transactions on-chain and publishing the state transition diff. zkSync follows the second option. +L2 transactions on-chain and publishing the state transition diff. ZKsync follows the second option. See the [documentation](https://era.zksync.io/docs/dev/fundamentals/rollups.html) to read more! @@ -25,13 +25,13 @@ See the [documentation](https://era.zksync.io/docs/dev/fundamentals/rollups.html L2 blocks. - **Facet** - implementation contract. The word comes from the EIP-2535. - **Gas** - a unit that measures the amount of computational effort required to execute specific operations on the - zkSync Era network. + ZKsync Era network. ### L1 Smart contracts #### Diamond -Technically, this L1 smart contract acts as a connector between Ethereum (L1) and zkSync (L2). This contract checks the +Technically, this L1 smart contract acts as a connector between Ethereum (L1) and ZKsync (L2). This contract checks the validity proof and data availability, handles L2 <-> L1 communication, finalizes L2 state transition, and more. There are also important contracts deployed on the L2 that can also execute logic called _system contracts_. Using L2 @@ -73,7 +73,7 @@ execution of upgrades in the diamond proxy. This contract manages operations (calls with preconditions) for governance tasks. The contract allows for operations to be scheduled, executed, and canceled with appropriate permissions and delays. It is used for managing and coordinating -upgrades and changes in all zkSync Era governed contracts. +upgrades and changes in all ZKsync Era governed contracts. Each upgrade consists of two steps: @@ -122,8 +122,8 @@ function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Ad ``` For most of the rollups the address aliasing needs to prevent cross-chain exploits that would otherwise be possible if -we simply reused the same L1 addresses as the L2 sender. In zkSync Era address derivation rule is different from the -Ethereum, so cross-chain exploits are already impossible. However, zkSync Era may add full EVM support in the future, so +we simply reused the same L1 addresses as the L2 sender. In ZKsync Era address derivation rule is different from the +Ethereum, so cross-chain exploits are already impossible. However, ZKsync Era may add full EVM support in the future, so applying address aliasing leave room for future EVM compatibility. The L1 -> L2 communication is also used for bridging ether. The user should include a `msg.value` when initiating a @@ -253,8 +253,8 @@ the L1 recipient. #### ValidatorTimelock -An intermediate smart contract between the validator EOA account and the zkSync smart contract. Its primary purpose is -to provide a trustless means of delaying batch execution without modifying the main zkSync contract. zkSync actively +An intermediate smart contract between the validator EOA account and the ZKsync smart contract. Its primary purpose is +to provide a trustless means of delaying batch execution without modifying the main ZKsync contract. ZKsync actively monitors the chain activity and reacts to any suspicious activity by freezing the chain. This allows time for investigation and mitigation before resuming normal operations. @@ -264,12 +264,12 @@ the Alpha stage. This contract consists of four main functions `commitBatches`, `proveBatches`, `executeBatches`, and `revertBatches`, that can be called only by the validator. -When the validator calls `commitBatches`, the same calldata will be propagated to the zkSync contract (`DiamondProxy` +When the validator calls `commitBatches`, the same calldata will be propagated to the ZKsync contract (`DiamondProxy` through `call` where it invokes the `ExecutorFacet` through `delegatecall`), and also a timestamp is assigned to these batches to track the time these batches are committed by the validator to enforce a delay between committing and execution of batches. Then, the validator can prove the already committed batches regardless of the mentioned timestamp, -and again the same calldata (related to the `proveBatches` function) will be propagated to the zkSync contract. After, -the `delay` is elapsed, the validator is allowed to call `executeBatches` to propagate the same calldata to zkSync +and again the same calldata (related to the `proveBatches` function) will be propagated to the ZKsync contract. After, +the `delay` is elapsed, the validator is allowed to call `executeBatches` to propagate the same calldata to ZKsync contract. ### L2 specifics diff --git a/gas-bound-caller/README.md b/gas-bound-caller/README.md index 00f2868df..17b647539 100644 --- a/gas-bound-caller/README.md +++ b/gas-bound-caller/README.md @@ -46,4 +46,4 @@ Since `GasBoundCaller` would be the contract that calls the `_to` contract, the It should be deployed via a built-in CREATE2 factory on each individual chain. -The current address on both sepolia testnet and mainnet for zkSync Era is `0xc706EC7dfA5D4Dc87f29f859094165E8290530f5`. +The current address on both sepolia testnet and mainnet for ZKsync Era is `0xc706EC7dfA5D4Dc87f29f859094165E8290530f5`. diff --git a/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol b/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol index ca7c870c7..1f154e270 100644 --- a/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol +++ b/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol @@ -6,7 +6,7 @@ import {MSG_VALUE_SYSTEM_CONTRACT, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT} from "@mat import {Utils} from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/Utils.sol"; // Addresses used for the compiler to be replaced with the -// zkSync-specific opcodes during the compilation. +// ZKsync-specific opcodes during the compilation. // IMPORTANT: these are just compile-time constants and are used // only if used in-place by Yul optimizer. address constant TO_L1_CALL_ADDRESS = address((1 << 16) - 1); diff --git a/l1-contracts/README.md b/l1-contracts/README.md index 30ffc8399..8fb04bb86 100644 --- a/l1-contracts/README.md +++ b/l1-contracts/README.md @@ -1,10 +1,10 @@ -# zkSync Era: L1 Contracts +# ZKsync Era: L1 Contracts [![Logo](../eraLogo.svg)](https://zksync.io/) -zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +ZKsync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring -or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +or re-auditing a single line of code. ZKsync Era also uses an LLVM-based compiler that will eventually let developers write smart contracts in C++, Rust and other popular languages. ## L1 Contracts diff --git a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol index a3b6e1426..ccd4a2a88 100644 --- a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol @@ -16,7 +16,7 @@ import {Unauthorized, EmptyDeposit, TokensWithFeesNotSupported, WithdrawalAlread /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev /// @notice Smart contract that allows depositing ERC20 tokens from Ethereum to hyperchains -/// @dev It is a legacy bridge from zkSync Era, that was deprecated in favour of shared bridge. +/// @dev It is a legacy bridge from ZKsync Era, that was deprecated in favour of shared bridge. /// It is needed for backward compatibility with already integrated projects. contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { using SafeERC20 for IERC20; @@ -25,25 +25,25 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { IL1SharedBridge public immutable override SHARED_BRIDGE; /// @dev A mapping L2 batch number => message number => flag. - /// @dev Used to indicate that L2 -> L1 message was already processed for zkSync Era withdrawals. + /// @dev Used to indicate that L2 -> L1 message was already processed for ZKsync Era withdrawals. // slither-disable-next-line uninitialized-state mapping(uint256 l2BatchNumber => mapping(uint256 l2ToL1MessageNumber => bool isFinalized)) public isWithdrawalFinalized; /// @dev A mapping account => L1 token address => L2 deposit transaction hash => amount. - /// @dev Used for saving the number of deposited funds, to claim them in case the deposit transaction will fail in zkSync Era. + /// @dev Used for saving the number of deposited funds, to claim them in case the deposit transaction will fail in ZKsync Era. mapping(address account => mapping(address l1Token => mapping(bytes32 depositL2TxHash => uint256 amount))) public depositAmount; - /// @dev The address that is used as a L2 bridge counterpart in zkSync Era. + /// @dev The address that is used as a L2 bridge counterpart in ZKsync Era. // slither-disable-next-line uninitialized-state address public l2Bridge; - /// @dev The address that is used as a beacon for L2 tokens in zkSync Era. + /// @dev The address that is used as a beacon for L2 tokens in ZKsync Era. // slither-disable-next-line uninitialized-state address public l2TokenBeacon; - /// @dev Stores the hash of the L2 token proxy contract's bytecode on zkSync Era. + /// @dev Stores the hash of the L2 token proxy contract's bytecode on ZKsync Era. // slither-disable-next-line uninitialized-state bytes32 public l2TokenProxyBytecodeHash; @@ -78,7 +78,7 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { ERA LEGACY GETTERS //////////////////////////////////////////////////////////////*/ - /// @return The L2 token address that would be minted for deposit of the given L1 token on zkSync Era. + /// @return The L2 token address that would be minted for deposit of the given L1 token on ZKsync Era. function l2TokenAddress(address _l1Token) external view returns (address) { bytes32 constructorInputHash = keccak256(abi.encode(l2TokenBeacon, "")); bytes32 salt = bytes32(uint256(uint160(_l1Token))); diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index 2b5a8887a..eec3c2e69 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -40,20 +40,20 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @dev Era's chainID uint256 internal immutable ERA_CHAIN_ID; - /// @dev The address of zkSync Era diamond proxy contract. + /// @dev The address of ZKsync Era diamond proxy contract. address internal immutable ERA_DIAMOND_PROXY; - /// @dev Stores the first batch number on the zkSync Era Diamond Proxy that was settled after Diamond proxy upgrade. + /// @dev Stores the first batch number on the ZKsync Era Diamond Proxy that was settled after Diamond proxy upgrade. /// This variable is used to differentiate between pre-upgrade and post-upgrade Eth withdrawals. Withdrawals from batches older /// than this value are considered to have been finalized prior to the upgrade and handled separately. uint256 internal eraPostDiamondUpgradeFirstBatch; - /// @dev Stores the first batch number on the zkSync Era Diamond Proxy that was settled after L1ERC20 Bridge upgrade. + /// @dev Stores the first batch number on the ZKsync Era Diamond Proxy that was settled after L1ERC20 Bridge upgrade. /// This variable is used to differentiate between pre-upgrade and post-upgrade ERC20 withdrawals. Withdrawals from batches older /// than this value are considered to have been finalized prior to the upgrade and handled separately. uint256 internal eraPostLegacyBridgeUpgradeFirstBatch; - /// @dev Stores the zkSync Era batch number that processes the last deposit tx initiated by the legacy bridge + /// @dev Stores the ZKsync Era batch number that processes the last deposit tx initiated by the legacy bridge /// This variable (together with eraLegacyBridgeLastDepositTxNumber) is used to differentiate between pre-upgrade and post-upgrade deposits. Deposits processed in older batches /// than this value are considered to have been processed prior to the upgrade and handled separately. /// We use this both for Eth and erc20 token deposits, so we need to update the diamond and bridge simultaneously. @@ -98,7 +98,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _; } - /// @notice Checks that the message sender is the bridgehub or zkSync Era Diamond Proxy. + /// @notice Checks that the message sender is the bridgehub or ZKsync Era Diamond Proxy. modifier onlyBridgehubOrEra(uint256 _chainId) { if (msg.sender != address(BRIDGE_HUB) && (_chainId != ERA_CHAIN_ID || msg.sender != ERA_DIAMOND_PROXY)) { revert Unauthorized(msg.sender); @@ -148,7 +148,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @dev This sets the first post diamond upgrade batch for era, used to check old eth withdrawals - /// @param _eraPostDiamondUpgradeFirstBatch The first batch number on the zkSync Era Diamond Proxy that was settled after diamond proxy upgrade. + /// @param _eraPostDiamondUpgradeFirstBatch The first batch number on the ZKsync Era Diamond Proxy that was settled after diamond proxy upgrade. function setEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external onlyOwner { if (eraPostDiamondUpgradeFirstBatch != 0) { revert SharedBridgeValueAlreadySet(SharedBridgeKey.PostUpgradeFirstBatch); @@ -157,7 +157,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @dev This sets the first post upgrade batch for era, used to check old token withdrawals - /// @param _eraPostLegacyBridgeUpgradeFirstBatch The first batch number on the zkSync Era Diamond Proxy that was settled after legacy bridge upgrade. + /// @param _eraPostLegacyBridgeUpgradeFirstBatch The first batch number on the ZKsync Era Diamond Proxy that was settled after legacy bridge upgrade. function setEraPostLegacyBridgeUpgradeFirstBatch(uint256 _eraPostLegacyBridgeUpgradeFirstBatch) external onlyOwner { if (eraPostLegacyBridgeUpgradeFirstBatch != 0) { revert SharedBridgeValueAlreadySet(SharedBridgeKey.LegacyBridgeFirstBatch); @@ -166,7 +166,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @dev This sets the first post upgrade batch for era, used to check old withdrawals - /// @param _eraLegacyBridgeLastDepositBatch The the zkSync Era batch number that processes the last deposit tx initiated by the legacy bridge + /// @param _eraLegacyBridgeLastDepositBatch The the ZKsync Era batch number that processes the last deposit tx initiated by the legacy bridge /// @param _eraLegacyBridgeLastDepositTxNumber The tx number in the _eraLegacyBridgeLastDepositBatch of the last deposit tx initiated by the legacy bridge function setEraLegacyBridgeLastDepositTime( uint256 _eraLegacyBridgeLastDepositBatch, @@ -537,10 +537,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade emit ClaimedFailedDepositSharedBridge(_chainId, _depositSender, _l1Token, _amount); } - /// @dev Determines if an eth withdrawal was initiated on zkSync Era before the upgrade to the Shared Bridge. + /// @dev Determines if an eth withdrawal was initiated on ZKsync Era before the upgrade to the Shared Bridge. /// @param _chainId The chain ID of the transaction to check. /// @param _l2BatchNumber The L2 batch number for the withdrawal. - /// @return Whether withdrawal was initiated on zkSync Era before diamond proxy upgrade. + /// @return Whether withdrawal was initiated on ZKsync Era before diamond proxy upgrade. function _isEraLegacyEthWithdrawal(uint256 _chainId, uint256 _l2BatchNumber) internal view returns (bool) { if ((_chainId == ERA_CHAIN_ID) && eraPostDiamondUpgradeFirstBatch == 0) { revert SharedBridgeValueNotSet(SharedBridgeKey.PostUpgradeFirstBatch); @@ -548,10 +548,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraPostDiamondUpgradeFirstBatch); } - /// @dev Determines if a token withdrawal was initiated on zkSync Era before the upgrade to the Shared Bridge. + /// @dev Determines if a token withdrawal was initiated on ZKsync Era before the upgrade to the Shared Bridge. /// @param _chainId The chain ID of the transaction to check. /// @param _l2BatchNumber The L2 batch number for the withdrawal. - /// @return Whether withdrawal was initiated on zkSync Era before Legacy Bridge upgrade. + /// @return Whether withdrawal was initiated on ZKsync Era before Legacy Bridge upgrade. function _isEraLegacyTokenWithdrawal(uint256 _chainId, uint256 _l2BatchNumber) internal view returns (bool) { if ((_chainId == ERA_CHAIN_ID) && eraPostLegacyBridgeUpgradeFirstBatch == 0) { revert SharedBridgeValueNotSet(SharedBridgeKey.LegacyBridgeFirstBatch); @@ -559,11 +559,11 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraPostLegacyBridgeUpgradeFirstBatch); } - /// @dev Determines if a deposit was initiated on zkSync Era before the upgrade to the Shared Bridge. + /// @dev Determines if a deposit was initiated on ZKsync Era before the upgrade to the Shared Bridge. /// @param _chainId The chain ID of the transaction to check. /// @param _l2BatchNumber The L2 batch number for the deposit where it was processed. /// @param _l2TxNumberInBatch The L2 transaction number in the batch, in which the deposit was processed. - /// @return Whether deposit was initiated on zkSync Era before Shared Bridge upgrade. + /// @return Whether deposit was initiated on ZKsync Era before Shared Bridge upgrade. function _isEraLegacyDeposit( uint256 _chainId, uint256 _l2BatchNumber, @@ -632,7 +632,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } isWithdrawalFinalized[_chainId][_l2BatchNumber][_l2MessageIndex] = true; - // Handling special case for withdrawal from zkSync Era initiated before Shared Bridge. + // Handling special case for withdrawal from ZKsync Era initiated before Shared Bridge. if (_isEraLegacyEthWithdrawal(_chainId, _l2BatchNumber)) { // Checks that the withdrawal wasn't finalized already. bool alreadyFinalized = IGetters(ERA_DIAMOND_PROXY).isEthWithdrawalFinalized( @@ -866,7 +866,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade }); } - /// @notice Withdraw funds from the initiated deposit, that failed when finalizing on zkSync Era chain. + /// @notice Withdraw funds from the initiated deposit, that failed when finalizing on ZKsync Era chain. /// This function is specifically designed for maintaining backward-compatibility with legacy `claimFailedDeposit` /// method in `L1ERC20Bridge`. /// diff --git a/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol index 615536de0..722eeedc1 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IL1SharedBridge} from "./IL1SharedBridge.sol"; @@ -7,7 +7,7 @@ import {IL1SharedBridge} from "./IL1SharedBridge.sol"; /// @title L1 Bridge contract legacy interface /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev -/// @notice Legacy Bridge interface before hyperchain migration, used for backward compatibility with zkSync Era +/// @notice Legacy Bridge interface before hyperchain migration, used for backward compatibility with ZKsync Era interface IL1ERC20Bridge { event DepositInitiated( bytes32 indexed l2DepositTxHash, diff --git a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol index 3a0838312..8038d6bdb 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; diff --git a/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol index 87b0c6c9f..39c6b423f 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @author Matter Labs diff --git a/l1-contracts/contracts/bridge/interfaces/IWETH9.sol b/l1-contracts/contracts/bridge/interfaces/IWETH9.sol index 2634cc5d5..e1536f4fb 100644 --- a/l1-contracts/contracts/bridge/interfaces/IWETH9.sol +++ b/l1-contracts/contracts/bridge/interfaces/IWETH9.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; interface IWETH9 { diff --git a/l1-contracts/contracts/bridgehub/IBridgehub.sol b/l1-contracts/contracts/bridgehub/IBridgehub.sol index 31c89f289..4216a6840 100644 --- a/l1-contracts/contracts/bridgehub/IBridgehub.sol +++ b/l1-contracts/contracts/bridgehub/IBridgehub.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol"; diff --git a/l1-contracts/contracts/common/Config.sol b/l1-contracts/contracts/common/Config.sol index a39d27f97..c0e05f1fc 100644 --- a/l1-contracts/contracts/common/Config.sol +++ b/l1-contracts/contracts/common/Config.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @dev `keccak256("")` @@ -21,10 +21,10 @@ bytes32 constant L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH = 0x72abee45b59e344af8a6e5202 // TODO: change constant to the real root hash of empty Merkle tree (SMA-184) bytes32 constant DEFAULT_L2_LOGS_TREE_ROOT_HASH = bytes32(0); -/// @dev Denotes the type of the zkSync transaction that came from L1. +/// @dev Denotes the type of the ZKsync transaction that came from L1. uint256 constant PRIORITY_OPERATION_L2_TX_TYPE = 255; -/// @dev Denotes the type of the zkSync transaction that is used for system upgrades. +/// @dev Denotes the type of the ZKsync transaction that is used for system upgrades. uint256 constant SYSTEM_UPGRADE_L2_TX_TYPE = 254; /// @dev The maximal allowed difference between protocol minor versions in an upgrade. The 100 gap is needed diff --git a/l1-contracts/contracts/common/Dependencies.sol b/l1-contracts/contracts/common/Dependencies.sol index 017b6177e..fceaa77dd 100644 --- a/l1-contracts/contracts/common/Dependencies.sol +++ b/l1-contracts/contracts/common/Dependencies.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /* solhint-disable-next-line no-unused-import */ diff --git a/l1-contracts/contracts/common/L2ContractAddresses.sol b/l1-contracts/contracts/common/L2ContractAddresses.sol index e8dbb1c83..571ef3d76 100644 --- a/l1-contracts/contracts/common/L2ContractAddresses.sol +++ b/l1-contracts/contracts/common/L2ContractAddresses.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @dev The formal address of the initial program of the system: the bootloader diff --git a/l1-contracts/contracts/common/Messaging.sol b/l1-contracts/contracts/common/Messaging.sol index 526d526dd..a7a2db944 100644 --- a/l1-contracts/contracts/common/Messaging.sol +++ b/l1-contracts/contracts/common/Messaging.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @dev The enum that represents the transaction execution status diff --git a/l1-contracts/contracts/common/ReentrancyGuard.sol b/l1-contracts/contracts/common/ReentrancyGuard.sol index 7d3899658..b1f8e556a 100644 --- a/l1-contracts/contracts/common/ReentrancyGuard.sol +++ b/l1-contracts/contracts/common/ReentrancyGuard.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {SlotOccupied, NotInitializedReentrancyGuard, Reentrancy} from "./L1ContractErrors.sol"; diff --git a/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol index 99890dcca..3d5b597df 100644 --- a/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol +++ b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /** * @author Matter Labs - * @notice System smart contract that is responsible for deploying other smart contracts on a zkSync hyperchain. + * @notice System smart contract that is responsible for deploying other smart contracts on a ZKsync hyperchain. */ interface IL2ContractDeployer { /// @notice A struct that describes a forced deployment on an address. diff --git a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol index e21e7de72..21199f069 100644 --- a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol +++ b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {BytecodeError, MalformedBytecode, LengthIsNotDivisibleBy32} from "../L1ContractErrors.sol"; diff --git a/l1-contracts/contracts/common/libraries/SemVer.sol b/l1-contracts/contracts/common/libraries/SemVer.sol index 8d9fd10ac..c46051626 100644 --- a/l1-contracts/contracts/common/libraries/SemVer.sol +++ b/l1-contracts/contracts/common/libraries/SemVer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @dev The number of bits dedicated to the "patch" portion of the protocol version. diff --git a/l1-contracts/contracts/common/libraries/UncheckedMath.sol b/l1-contracts/contracts/common/libraries/UncheckedMath.sol index 91c3e652c..a41a9c6ea 100644 --- a/l1-contracts/contracts/common/libraries/UncheckedMath.sol +++ b/l1-contracts/contracts/common/libraries/UncheckedMath.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /** diff --git a/l1-contracts/contracts/common/libraries/UnsafeBytes.sol b/l1-contracts/contracts/common/libraries/UnsafeBytes.sol index 3b8fc3cb5..d20bcbac8 100644 --- a/l1-contracts/contracts/common/libraries/UnsafeBytes.sol +++ b/l1-contracts/contracts/common/libraries/UnsafeBytes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /** diff --git a/l1-contracts/contracts/dev-contracts/RevertReceiveAccount.sol b/l1-contracts/contracts/dev-contracts/RevertReceiveAccount.sol index 31575de1b..663afdfdc 100644 --- a/l1-contracts/contracts/dev-contracts/RevertReceiveAccount.sol +++ b/l1-contracts/contracts/dev-contracts/RevertReceiveAccount.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; /// @title RevertReceiveAccount - An account which reverts receiving funds depending on the flag -/// @dev Used for testing failed withdrawals from the zkSync smart contract +/// @dev Used for testing failed withdrawals from the ZKsync smart contract contract RevertReceiveAccount { // add this to be excluded from coverage report function test() internal virtual {} diff --git a/l1-contracts/contracts/dev-contracts/RevertTransferERC20.sol b/l1-contracts/contracts/dev-contracts/RevertTransferERC20.sol index bd018276d..dcc1f71f7 100644 --- a/l1-contracts/contracts/dev-contracts/RevertTransferERC20.sol +++ b/l1-contracts/contracts/dev-contracts/RevertTransferERC20.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.24; import {TestnetERC20Token} from "./TestnetERC20Token.sol"; /// @title RevertTransferERC20Token - A ERC20 token contract which can revert transfers depending on a flag -/// @dev Used for testing failed ERC-20 withdrawals from the zkSync smart contract +/// @dev Used for testing failed ERC-20 withdrawals from the ZKsync smart contract contract RevertTransferERC20 is TestnetERC20Token { // add this to be excluded from coverage report function test() internal override {} diff --git a/l1-contracts/contracts/governance/Governance.sol b/l1-contracts/contracts/governance/Governance.sol index 45aa431da..790b79a26 100644 --- a/l1-contracts/contracts/governance/Governance.sol +++ b/l1-contracts/contracts/governance/Governance.sol @@ -12,7 +12,7 @@ import {ZeroAddress, Unauthorized, OperationMustBeReady, OperationMustBePending, /// @notice This contract manages operations (calls with preconditions) for governance tasks. /// The contract allows for operations to be scheduled, executed, and canceled with /// appropriate permissions and delays. It is used for managing and coordinating upgrades -/// and changes in all zkSync hyperchain governed contracts. +/// and changes in all ZKsync hyperchain governed contracts. /// /// Operations can be proposed as either fully transparent upgrades with on-chain data, /// or "shadow" upgrades where upgrade data is not published on-chain before execution. Proposed operations diff --git a/l1-contracts/contracts/governance/IGovernance.sol b/l1-contracts/contracts/governance/IGovernance.sol index e2a600175..2b03ed4c9 100644 --- a/l1-contracts/contracts/governance/IGovernance.sol +++ b/l1-contracts/contracts/governance/IGovernance.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @title Governance contract interface diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index d0111cf82..fec1c31fd 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {Diamond} from "./libraries/Diamond.sol"; diff --git a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol index 32d92b7b1..61576f74c 100644 --- a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol +++ b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol @@ -14,7 +14,7 @@ import {Unauthorized, TimeNotReached, ZeroAddress} from "../common/L1ContractErr /// @dev The primary purpose of this contract is to provide a trustless means of delaying batch execution without /// modifying the main hyperchain diamond contract. As such, even if this contract is compromised, it will not impact the main /// contract. -/// @dev zkSync actively monitors the chain activity and reacts to any suspicious activity by freezing the chain. +/// @dev ZKsync actively monitors the chain activity and reacts to any suspicious activity by freezing the chain. /// This allows time for investigation and mitigation before resuming normal operations. /// @dev The contract overloads all of the 4 methods, that are used in state transition. When the batch is committed, /// the timestamp is stored for it. Later, when the owner calls the batch execution, the contract checks that batch @@ -210,7 +210,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { // Note: if the `commitBatchTimestamp` is zero, that means either: // * The batch was committed, but not through this contract. - // * The batch wasn't committed at all, so execution will fail in the zkSync contract. + // * The batch wasn't committed at all, so execution will fail in the ZKsync contract. // We allow executing such batches. if (block.timestamp < commitBatchTimestamp + delay) { diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index cfc1f848b..a74ecb12c 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -8,14 +8,14 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @author Matter Labs /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. -/// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. +/// Modifications have been made to optimize the proof system for ZKsync hyperchain circuits. /// @dev Contract was generated from a verification key with a hash of 0x14f97b81e54b35fe673d8708cc1a19e1ea5b5e348e12d31e39824ed4f42bbca2 /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: /// * Original Plonk Article: https://eprint.iacr.org/2019/953.pdf /// * Original LookUp Article: https://eprint.iacr.org/2020/315.pdf -/// * Plonk for zkSync v1.1: https://github.com/matter-labs/solidity_plonk_verifier/raw/recursive/bellman_vk_codegen_recursive/RecursivePlonkUnrolledForEthereum.pdf +/// * Plonk for ZKsync v1.1: https://github.com/matter-labs/solidity_plonk_verifier/raw/recursive/bellman_vk_codegen_recursive/RecursivePlonkUnrolledForEthereum.pdf /// The notation used in the code is the same as in the papers. /* solhint-enable max-line-length */ contract Verifier is IVerifier { diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index f47870345..07995642b 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -16,7 +16,7 @@ import {BatchNumberMismatch, TimeNotReached, TooManyBlobs, ValueMismatch, Invali // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; -/// @title zkSync hyperchain Executor contract capable of processing events emitted in the zkSync hyperchain protocol. +/// @title ZKsync hyperchain Executor contract capable of processing events emitted in the ZKsync hyperchain protocol. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol index 1f380941c..43f6b04e7 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -25,7 +25,7 @@ import {OnlyEraSupported, BatchNotExecuted, HashedLogIsDefault, BaseTokenGasPric // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; -/// @title zkSync Mailbox contract providing interfaces for L1 <-> L2 interaction. +/// @title ZKsync Mailbox contract providing interfaces for L1 <-> L2 interaction. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { @@ -299,7 +299,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { request.refundRecipient = AddressAliasHelper.actualRefundRecipient(request.refundRecipient, request.sender); // Change the sender address if it is a smart contract to prevent address collision between L1 and L2. - // Please note, currently zkSync address derivation is different from Ethereum one, but it may be changed in the future. + // Please note, currently ZKsync address derivation is different from Ethereum one, but it may be changed in the future. // solhint-disable avoid-tx-origin // slither-disable-next-line tx-origin if (request.sender != tx.origin) { diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol index 79c034f36..643c6114d 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "../chain-interfaces/IZkSyncHyperchainBase.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol index e222a623e..189ae69fa 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IVerifier, VerifierParams} from "./IVerifier.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol index 7679be75e..d74e4288b 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "./IZkSyncHyperchainBase.sol"; @@ -75,7 +75,7 @@ uint256 constant MAX_NUMBER_OF_BLOBS = 6; /// than the maximal number of blobs supported by the contract (`MAX_NUMBER_OF_BLOBS`). uint256 constant TOTAL_BLOBS_IN_COMMITMENT = 16; -/// @title The interface of the zkSync Executor contract capable of processing events emitted in the zkSync protocol. +/// @title The interface of the ZKsync Executor contract capable of processing events emitted in the ZKsync protocol. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev interface IExecutor is IZkSyncHyperchainBase { @@ -87,7 +87,7 @@ interface IExecutor is IZkSyncHyperchainBase { /// @param priorityOperationsHash Hash of all priority operations from this batch /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant - /// @param commitment Verified input for the zkSync circuit + /// @param commitment Verified input for the ZKsync circuit // solhint-disable-next-line gas-struct-packing struct StoredBatchInfo { uint64 batchNumber; @@ -195,7 +195,7 @@ interface IExecutor is IZkSyncHyperchainBase { /// @notice Event emitted when a batch is committed /// @param batchNumber Number of the batch committed /// @param batchHash Hash of the L2 batch - /// @param commitment Calculated input for the zkSync circuit + /// @param commitment Calculated input for the ZKsync circuit /// @dev It has the name "BlockCommit" and not "BatchCommit" due to backward compatibility considerations event BlockCommit(uint256 indexed batchNumber, bytes32 indexed batchHash, bytes32 indexed commitment); @@ -208,7 +208,7 @@ interface IExecutor is IZkSyncHyperchainBase { /// @notice Event emitted when a batch is executed /// @param batchNumber Number of the batch executed /// @param batchHash Hash of the L2 batch - /// @param commitment Verified input for the zkSync circuit + /// @param commitment Verified input for the ZKsync circuit /// @dev It has the name "BlockExecution" and not "BatchExecution" due to backward compatibility considerations event BlockExecution(uint256 indexed batchNumber, bytes32 indexed batchHash, bytes32 indexed commitment); diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol index 38e2adbfe..4d06f9e8e 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {PriorityOperation} from "../libraries/PriorityQueue.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol b/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol index 4d6941edf..cb62f5087 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/ILegacyGetters.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "./IZkSyncHyperchainBase.sol"; /// @author Matter Labs -/// @dev This interface contains getters for the zkSync contract that should not be used, +/// @dev This interface contains getters for the ZKsync contract that should not be used, /// but still are kept for backward compatibility. /// @custom:security-contact security@matterlabs.dev interface ILegacyGetters is IZkSyncHyperchainBase { diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol index 065b3819d..9daffebcf 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IZkSyncHyperchainBase} from "./IZkSyncHyperchainBase.sol"; import {L2CanonicalTransaction, L2Log, L2Message, TxStatus, BridgehubL2TransactionRequest} from "../../common/Messaging.sol"; -/// @title The interface of the zkSync Mailbox contract that provides interfaces for L1 <-> L2 interaction. +/// @title The interface of the ZKsync Mailbox contract that provides interfaces for L1 <-> L2 interaction. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev interface IMailbox is IZkSyncHyperchainBase { diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol b/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol index 49dee07fd..a3776cacd 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/ITransactionFilterer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @title The interface of the L1 -> L2 transaction filterer. diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol index dbca3bf0c..97872c370 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IVerifier.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @notice Part of the configuration parameters of ZKP circuits diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol index bf9a88a5e..14aa123b0 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IAdmin} from "./IAdmin.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol index 15fda726d..24fe3b482 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: UNLICENSED -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; -/// @title The interface of the zkSync contract, responsible for the main zkSync logic. +/// @title The interface of the ZKsync contract, responsible for the main ZKsync logic. /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev interface IZkSyncHyperchainBase { diff --git a/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol b/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol index 6aa1b09ff..d09e76491 100644 --- a/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol +++ b/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; interface ISystemContext { diff --git a/l1-contracts/contracts/state-transition/libraries/Diamond.sol b/l1-contracts/contracts/state-transition/libraries/Diamond.sol index 6d8416fde..b43a673c5 100644 --- a/l1-contracts/contracts/state-transition/libraries/Diamond.sol +++ b/l1-contracts/contracts/state-transition/libraries/Diamond.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {SafeCast} from "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; diff --git a/l1-contracts/contracts/state-transition/libraries/LibMap.sol b/l1-contracts/contracts/state-transition/libraries/LibMap.sol index 9bedb1cce..2cbad0b78 100644 --- a/l1-contracts/contracts/state-transition/libraries/LibMap.sol +++ b/l1-contracts/contracts/state-transition/libraries/LibMap.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @notice Library for storage of packed unsigned integers. diff --git a/l1-contracts/contracts/state-transition/libraries/Merkle.sol b/l1-contracts/contracts/state-transition/libraries/Merkle.sol index 79287d00b..57701f338 100644 --- a/l1-contracts/contracts/state-transition/libraries/Merkle.sol +++ b/l1-contracts/contracts/state-transition/libraries/Merkle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; diff --git a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol index 762350039..141cd40c0 100644 --- a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol +++ b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {QueueIsEmpty} from "../../common/L1ContractErrors.sol"; diff --git a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol index 485aef9a2..f196053f4 100644 --- a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol +++ b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {Math} from "@openzeppelin/contracts-v4/utils/math/Math.sol"; @@ -8,7 +8,7 @@ import {L2CanonicalTransaction} from "../../common/Messaging.sol"; import {TX_SLOT_OVERHEAD_L2_GAS, MEMORY_OVERHEAD_GAS, L1_TX_INTRINSIC_L2_GAS, L1_TX_DELTA_544_ENCODING_BYTES, L1_TX_DELTA_FACTORY_DEPS_L2_GAS, L1_TX_MIN_L2_GAS_BASE, L1_TX_INTRINSIC_PUBDATA, L1_TX_DELTA_FACTORY_DEPS_PUBDATA} from "../../common/Config.sol"; import {TooMuchGas, InvalidUpgradeTxn, UpgradeTxVerifyParam, PubdataGreaterThanLimit, ValidateTxnNotEnoughGas, TxnBodyGasLimitNotEnoughGas} from "../../common/L1ContractErrors.sol"; -/// @title zkSync Library for validating L1 -> L2 transactions +/// @title ZKsync Library for validating L1 -> L2 transactions /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev library TransactionValidator { @@ -157,7 +157,7 @@ library TransactionValidator { /// @notice Based on the total L2 gas limit and several other parameters of the transaction /// returns the part of the L2 gas that will be spent on the batch's overhead. /// @dev The details of how this function works can be checked in the documentation - /// of the fee model of zkSync. The appropriate comments are also present + /// of the fee model of ZKsync. The appropriate comments are also present /// in the Rust implementation description of function `get_maximal_allowed_overhead`. /// @param _encodingLength The length of the binary encoding of the transaction in bytes function getOverheadForTransaction( diff --git a/l1-contracts/contracts/vendor/AddressAliasHelper.sol b/l1-contracts/contracts/vendor/AddressAliasHelper.sol index e5bc1da07..ad80f3483 100644 --- a/l1-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l1-contracts/contracts/vendor/AddressAliasHelper.sol @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; library AddressAliasHelper { diff --git a/l2-contracts/contracts/Dependencies.sol b/l2-contracts/contracts/Dependencies.sol index 591cb9fd9..8a606d45a 100644 --- a/l2-contracts/contracts/Dependencies.sol +++ b/l2-contracts/contracts/Dependencies.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /* solhint-disable-next-line no-unused-import */ diff --git a/l2-contracts/contracts/L2ContractHelper.sol b/l2-contracts/contracts/L2ContractHelper.sol index 60442bad0..842d4b4f4 100644 --- a/l2-contracts/contracts/L2ContractHelper.sol +++ b/l2-contracts/contracts/L2ContractHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** @@ -114,7 +114,7 @@ library L2ContractHelper { } } -/// @notice Structure used to represent a zkSync transaction. +/// @notice Structure used to represent a ZKsync transaction. struct Transaction { // The type of the transaction. uint256 txType; diff --git a/l2-contracts/contracts/SystemContractsCaller.sol b/l2-contracts/contracts/SystemContractsCaller.sol index 79161eaaf..ba3136792 100644 --- a/l2-contracts/contracts/SystemContractsCaller.sol +++ b/l2-contracts/contracts/SystemContractsCaller.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // solhint-disable one-contract-per-file -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {MSG_VALUE_SYSTEM_CONTRACT} from "./L2ContractHelper.sol"; diff --git a/l2-contracts/contracts/TestnetPaymaster.sol b/l2-contracts/contracts/TestnetPaymaster.sol index 36087352d..54558fe3b 100644 --- a/l2-contracts/contracts/TestnetPaymaster.sol +++ b/l2-contracts/contracts/TestnetPaymaster.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; diff --git a/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol b/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol index 02a16b990..84d412245 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /// @author Matter Labs diff --git a/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol b/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol index 5f196f1a5..cc468ab87 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /// @title L1 Bridge contract interface diff --git a/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol b/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol index 71e569795..ee31f6691 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /// @author Matter Labs diff --git a/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol b/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol index 4c2aaa323..6fefafa63 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2StandardToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IL2StandardToken { diff --git a/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol b/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol index df447e0f8..ae7e1a916 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2WrappedBaseToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IL2WrappedBaseToken { diff --git a/l2-contracts/contracts/errors/L2ContractErrors.sol b/l2-contracts/contracts/errors/L2ContractErrors.sol index 59fc9eaaa..c5177f3eb 100644 --- a/l2-contracts/contracts/errors/L2ContractErrors.sol +++ b/l2-contracts/contracts/errors/L2ContractErrors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; // 0x1f73225f diff --git a/l2-contracts/contracts/interfaces/IPaymaster.sol b/l2-contracts/contracts/interfaces/IPaymaster.sol index f7246457c..ed7e5c50f 100644 --- a/l2-contracts/contracts/interfaces/IPaymaster.sol +++ b/l2-contracts/contracts/interfaces/IPaymaster.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {Transaction} from "../L2ContractHelper.sol"; diff --git a/l2-contracts/contracts/interfaces/IPaymasterFlow.sol b/l2-contracts/contracts/interfaces/IPaymasterFlow.sol index 75e94a323..207aee24e 100644 --- a/l2-contracts/contracts/interfaces/IPaymasterFlow.sol +++ b/l2-contracts/contracts/interfaces/IPaymasterFlow.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/l2-contracts/contracts/vendor/AddressAliasHelper.sol b/l2-contracts/contracts/vendor/AddressAliasHelper.sol index 0dec0b9ee..6adab1d92 100644 --- a/l2-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l2-contracts/contracts/vendor/AddressAliasHelper.sol @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; library AddressAliasHelper { diff --git a/system-contracts/README.md b/system-contracts/README.md index 1449c936f..4058a356b 100644 --- a/system-contracts/README.md +++ b/system-contracts/README.md @@ -1,10 +1,10 @@ -# zkSync Era: System Contracts +# ZKsync Era: System Contracts [![Logo](../eraLogo.svg)](https://zksync.io/) -zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +ZKsync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring -or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +or re-auditing a single line of code. ZKsync Era also uses an LLVM-based compiler that will eventually let developers write smart contracts in C++, Rust and other popular languages. ## system-contracts @@ -17,7 +17,7 @@ the most commonly used contracts: each deployed contract is known. This contract also defines the derivation address. Whenever a contract is deployed, a ContractDeployed event is emitted. -`L1Messenger` This contract is used to send messages from zkSync to Ethereum. For each message sent, the L1MessageSent +`L1Messenger` This contract is used to send messages from ZKsync to Ethereum. For each message sent, the L1MessageSent event is emitted. `NonceHolder` This contract stores account nonces. The account nonces are stored in a single place for efficiency (the @@ -43,7 +43,7 @@ Update the system contracts hashes: `yarn sc calculate-hashes:fix` ### Run tests -The tests of the system contracts utilize the zkSync test node. In order to run the tests, execute the following commands in the root of the repository: +The tests of the system contracts utilize the ZKsync test node. In order to run the tests, execute the following commands in the root of the repository: ``` yarn test-node @@ -150,7 +150,7 @@ changes. ## License -The zkSync Era system-contracts are distributed under the terms of the MIT license. +The ZKsync Era system-contracts are distributed under the terms of the MIT license. See [LICENSE-MIT](LICENSE-MIT) for details. @@ -166,7 +166,7 @@ See [LICENSE-MIT](LICENSE-MIT) for details. ## Disclaimer -zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +ZKsync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! It is important to state that forking it now can potentially lead to missing important security updates, critical features, and performance improvements. diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 9d17edc7d..2e885b9f5 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,49 +3,49 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x0100005d39637f175e59ed8b149fb5767eaa1e1668ec9e884a13ad656c625748", - "sourceCodeHash": "0xcf59b8e87c4e6a45172938d0f991c301717556141e03a6c43f30db220b4b8093" + "bytecodeHash": "0x0100005d05a277543946914759aa4a6c403604b828f80d00b900c669c3d224e1", + "sourceCodeHash": "0x2e0e09d57a04bd1e722d8bf8c6423fdf3f8bca44e5e8c4f6684f987794be066e" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007c72a6c3838b90ba1574a7f0b9ead2ccc53b7429e94055eb4e29f9cdd62", - "sourceCodeHash": "0x2605e2d28cf99dbde11aa545e7fa9b6343f988b7173283f7dfd54780e9947ce9" + "bytecodeHash": "0x010007c7bb63f64649098bf75f4baa588db20f445b4d20b7cca972d5d8f973ce", + "sourceCodeHash": "0x0f1213c4b95acb71f4ab5d4082cc1aeb2bd5017e1cccd46afc66e53268609d85" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x0100004dee09025db93936ca0913936a6ef363256c2427e7c6c646ea5aeb8631", + "bytecodeHash": "0x0100004da9f3aa5e4febcc53522cb7ee6949369fde25dd79e977752b82b9fd5d", "sourceCodeHash": "0x796046a914fb676ba2bbd337b2924311ee2177ce54571c18a2c3945755c83614" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x0100014f7c7a4728b9960e1146b1ab129cf4df893f523a45bf2c1a6713ece7be", + "bytecodeHash": "0x0100014fb4f05ae09288cbcf4fa7a09ca456910f6e69be5ac2c2dfc8d71d1576", "sourceCodeHash": "0xc6f7cd8b21aae52ed3dd5083c09b438a7af142a4ecda6067c586770e8be745a5" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010004e54238d31df887052849f439609045c2f21aa4e311e381be824749da74", - "sourceCodeHash": "0x2b52178555e74f3696f9ae08fdce14c6046c3b18e0f02f0187609ca8a3bba471" + "bytecodeHash": "0x010004e5d52d692822d5c54ac87de3297f39be0e4a6f72f2830ae5ac856684ee", + "sourceCodeHash": "0x82f81fbf5fb007a9cac97462d50907ca5d7a1af62d82d2645e093ed8647a5209" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x0100004931dda7bd294161ad0ef0e228d4b4afc937cab9af4a2d938935fb6ea0", + "bytecodeHash": "0x010000495bd172e90725e6bfafe73e36a288d616d4673f5347eeb819a78bf546", "sourceCodeHash": "0x114d9322a9ca654989f3e0b3b21f1311dbc4db84f443d054cd414f6414d84de3" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x0100055da70d970f98ca4677a4b2fcecef5354f345cc5c6d13a78339e5fd87a9", + "bytecodeHash": "0x0100055dba11508480be023137563caec69debc85f826cb3a4b68246a7cabe30", "sourceCodeHash": "0xebffe840ebbd9329edb1ebff8ca50f6935e7dabcc67194a896fcc2e968d46dfb" }, { @@ -59,56 +59,56 @@ "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x01000039575b3cb0a5e96a80d89738a7cafa7e7995e7e4857f83c8982f5ff866", + "bytecodeHash": "0x01000039785a8e0d342a49b6b6c6e156801b816434d93bee85d33f56d56b4f9a", "sourceCodeHash": "0x9659e69f7db09e8f60a8bb95314b1ed26afcc689851665cf27f5408122f60c98" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100006f232f5cf3c8ffde9230c1af56f3129f69d9851a8d29751613a385418f", + "bytecodeHash": "0x0100006f0f209c9e6d06b1327db1257b15fa7a8b9864ee5ccd12cd3f8bc40ac9", "sourceCodeHash": "0xb39b5b81168653e0c5062f7b8e1d6d15a4e186df3317f192f0cb2fc3a74f5448" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002956ca323790f0c8b855ccc115fe48fa127189d80de464eaf956acda5a3", + "bytecodeHash": "0x010002955993e8ff8190e388e94a6bb791fbe9c6388e5011c52cb587a4ebf05e", "sourceCodeHash": "0xa8768fdaac6d8804782f14e2a51bbe2b6be31dee9103b6d02d149ea8dc46eb6a" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x0100010348a5ee59718d33426818b6d5a20a50efe68aecf7053304aeff82b7aa", + "bytecodeHash": "0x01000103174a90beadc2cffe3e81bdb7b8a576174e888809c1953175fd3015b4", "sourceCodeHash": "0x8bdd2b4d0b53dba84c9f0af250bbaa2aad10b3de6747bba957f0bd3721090dfa" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x0100005d426224423feeefe85bc7c7a02f65d01eb7e088c6978e421d78cfea72", + "bytecodeHash": "0x0100005da36075675b98f85fe90df11c1d526f6b12925da3a55a8b9c02aaac5f", "sourceCodeHash": "0x082f3dcbc2fe4d93706c86aae85faa683387097d1b676e7ebd00f71ee0f13b71" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000d91567c5bd154d2350868fb366fbb131e51087799cc5da6a7bc9f40a92", + "bytecodeHash": "0x010000d97de8c14cd36b1ce06cd7f44a09f6093ec8eb4041629c0fc2116d0c73", "sourceCodeHash": "0xcd0c0366effebf2c98c58cf96322cc242a2d1c675620ef5514b7ed1f0a869edc" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x0100004731b1807f406a678ca56a14d29917e2de60fca30cc7fa01169418f3ce", + "bytecodeHash": "0x010000470e396f376539289b7975b6866914a8a0994008a02987edac8be81db7", "sourceCodeHash": "0xd7161e2c8092cf57b43c6220bc605c0e7e540bddcde1af24e2d90f75633b098e" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001a5a3730f0455b91c43e1b4cdd96cbffbdb60c161eb16586908a5e740d8", + "bytecodeHash": "0x010001a5eabf9e28288b7ab7e1db316148021347460cfb4314570956867d5af5", "sourceCodeHash": "0xf308743981ef5cea2f7a3332b8e51695a5e47e811a63974437fc1cceee475e7a" }, { @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb94018874dce8c4f3b254625cffc7032c37f85c6b743d30cbac87c934", - "sourceCodeHash": "0x42b9c4235bd0b3de0beff158d7d848381990c55907daeaa3a9c8b6d66b53c0f3" + "bytecodeHash": "0x010003cbe23de2836aebbf2466f6899f7b19ad6dc5ff6e3ce10c83b16cad1b90", + "sourceCodeHash": "0xa7ac131c18e0b890282de1c328802a9c9c454c0c09d0bd015a06abb411556638" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x0100092dd79e0d7171d5dfe246e20c2d3f2d8b1ba8104ba1199e0c1a4b8af9ef", - "sourceCodeHash": "0xe538d080f0071f7f31ab1ea013fccec31560450d67e2859257d627100a5fcd07" + "bytecodeHash": "0x0100092d97e147d5fb59598c2d3ab1bb9bcada3fbc538f05fde153731d0e34aa", + "sourceCodeHash": "0x31b38c5e26c4d6acad6cbbb5677648818ab930d146354814666cb855a595f23a" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008b3ffe296bc8b565f555fa15f8aca08d9b88f5b06c15d72094cf5d779b6", - "sourceCodeHash": "0xcc36539d29f136bccd80fea0c3f9976cfc9e238972930b2aca98e6ad2e38fd1c" + "bytecodeHash": "0x010008b3324dc1065661a15eaefc44278fb555d6a561621c2c73935e7eb6d680", + "sourceCodeHash": "0xc9b10f7ceedf8883248be7d0e265fe076419df02bd59b8cbd701e92bced01472" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x010009339296f1ba9bd8b81e7152125a8286c4e7f9c3e194e35fc325a9e5c7d2", - "sourceCodeHash": "0xaac0c38a7b033eec41e2533c04b3541099c0c6ee70eb4acd8eea69edd1ef936a" + "bytecodeHash": "0x010009339beeb192c26f6cb18a67f446a578f10c145c8af344fe67b2772e4311", + "sourceCodeHash": "0xd4b0391e9d227e782934520d98eb66226d79ad1a6cfe422e624d7eee0d1e8bfc" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008c37ecadea8b003884eb9d81fdfb7161b3b309504e5318f15da19c500d8", - "sourceCodeHash": "0x64618bc0fd4affe7fd2a0fa6a5a16d16be2df194bbe3e0ad6d54f1878a4a6d95" + "bytecodeHash": "0x010008c314c516939d65ffcab410b9dcff5e7be81c4561adf171818984efc39c", + "sourceCodeHash": "0xdd2fb790fb11009d203b7933123cc51bfd00b7e96cc90006c05e2d31a5581477" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index e5daed9e0..a9a3a1725 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -620,10 +620,10 @@ object "Bootloader" { switch isETHCall case 1 { let gasLimitForTx, reservedGas := getGasLimitForTx( - innerTxDataOffset, - transactionIndex, + innerTxDataOffset, + transactionIndex, gasPerPubdata, - L2_TX_INTRINSIC_GAS(), + L2_TX_INTRINSIC_GAS(), L2_TX_INTRINSIC_PUBDATA() ) @@ -1279,7 +1279,7 @@ object "Bootloader" { /// @param gasLimitForTx The L2 gas limit for the transaction validation & execution. /// @param gasPrice The L2 gas price that should be used by the transaction. /// @param basePubdataSpent The amount of pubdata spent at the beginning of the transaction. - /// @param reservedGas The amount of gas reserved for the pubdata. + /// @param reservedGas The amount of gas reserved for the pubdata. /// @param gasPerPubdata The price of each byte of pubdata in L2 gas. /// @return gasLeft The gas left after the validation step. function l2TxValidation( @@ -1343,7 +1343,7 @@ object "Bootloader" { /// @param txDataOffset The offset to the ABI-encoded Transaction struct. /// @param gasLeft The gas left after the validation step. /// @param basePubdataSpent The amount of pubdata spent at the beginning of the transaction. - /// @param reservedGas The amount of gas reserved for the pubdata. + /// @param reservedGas The amount of gas reserved for the pubdata. /// @param gasPerPubdata The price of each byte of pubdata in L2 gas. /// @return success Whether or not the execution step was successful. /// @return gasSpentOnExecute The gas spent on the transaction execution. @@ -1440,7 +1440,7 @@ object "Bootloader" { /// @param abi The nearCall ABI. It is implicitly used as gasLimit for the call of this function. /// @param txDataOffset The offset to the ABI-encoded Transaction struct. /// @param basePubdataSpent The amount of pubdata spent at the beginning of the transaction. - /// @param reservedGas The amount of gas reserved for the pubdata. + /// @param reservedGas The amount of gas reserved for the pubdata. /// @param gasPerPubdata The price of each byte of pubdata in L2 gas. function ZKSYNC_NEAR_CALL_executeL2Tx( abi, @@ -1483,7 +1483,7 @@ object "Bootloader" { /// @param abi The nearCall ABI. It is implicitly used as gasLimit for the call of this function. /// @param txDataOffset The offset to the ABI-encoded Transaction struct. /// @param basePubdataSpent The amount of pubdata spent at the beginning of the transaction. - /// @param reservedGas The amount of gas reserved for the pubdata. + /// @param reservedGas The amount of gas reserved for the pubdata. /// @param gasPerPubdata The price of each byte of pubdata in L2 gas. function ZKSYNC_NEAR_CALL_markFactoryDepsL2( abi, @@ -1835,7 +1835,7 @@ object "Bootloader" { debugLog("from", from) debugLog("gasPrice", gasPrice) - // We assume that addresses of smart contracts on zkSync and Ethereum + // We assume that addresses of smart contracts on ZKsync and Ethereum // never overlap, so no need to check whether `from` is an EOA here. debugLog("setting tx origin", from) @@ -2268,7 +2268,7 @@ object "Bootloader" { /// @param maxRefundedGas The maximum number of gas the bootloader can be refunded. /// @param basePubdataSpent The amount of pubdata spent at the beginning of the transaction. /// @param gasPerPubdata The price of each byte of pubdata in L2 gas. - /// @param reservedGas The amount of gas reserved for the pubdata. + /// @param reservedGas The amount of gas reserved for the pubdata. /// This is the `maximum` number because it does not take into account the number of gas that /// can be spent by the paymaster itself. function ZKSYNC_NEAR_CALL_callPostOp( @@ -2552,7 +2552,7 @@ object "Bootloader" { } /// - /// zkSync-specific utilities: + /// ZKsync-specific utilities: /// /// @dev Returns an ABI that can be used for low-level @@ -2789,7 +2789,7 @@ object "Bootloader" { let spentErgs := getErgsSpentForPubdata(basePubdataSpent, gasPerPubdata) debugLog("spentErgsPubdata", spentErgs) let allowedGasLimit := add(computeGas, reservedGas) - + ret := lt(allowedGasLimit, spentErgs) } @@ -3579,7 +3579,7 @@ object "Bootloader" { } /// @dev Asks operator for the refund for the transaction. The function provides - /// the operator with the proposed refund gas by the bootloader, + /// the operator with the proposed refund gas by the bootloader, /// total spent gas on the pubdata and gas per 1 byte of pubdata. /// This function is called before the refund stage, because at that point /// only the operator knows how close does a transaction diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 03a128ad6..4c55279c4 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -14,7 +14,7 @@ import {Unauthorized, InvalidCodeHash, CodeHashReason} from "./SystemContractErr * @dev Code hash is not strictly a hash, it's a structure where the first byte denotes the version of the hash, * the second byte denotes whether the contract is constructed, and the next two bytes denote the length in 32-byte words. * And then the next 28 bytes are the truncated hash. - * @dev In this version of zkSync, the first byte of the hash MUST be 1. + * @dev In this version of ZKsync, the first byte of the hash MUST be 1. * @dev The length of each bytecode MUST be odd. It's internal code format requirements, due to padding of SHA256 function. * @dev It is also assumed that all the bytecode hashes are *known*, i.e. the full bytecodes * were published on L1 as calldata. This contract trusts the ContractDeployer and the KnownCodesStorage diff --git a/system-contracts/contracts/BootloaderUtilities.sol b/system-contracts/contracts/BootloaderUtilities.sol index 384f6a121..4fd38da74 100644 --- a/system-contracts/contracts/BootloaderUtilities.sol +++ b/system-contracts/contracts/BootloaderUtilities.sol @@ -177,7 +177,7 @@ contract BootloaderUtilities is IBootloaderUtilities { // Otherwise the length is not encoded at all. } - // On zkSync, access lists are always zero length (at least for now). + // On ZKsync, access lists are always zero length (at least for now). bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); bytes memory rEncoded; @@ -276,7 +276,7 @@ contract BootloaderUtilities is IBootloaderUtilities { // Otherwise the length is not encoded at all. } - // On zkSync, access lists are always zero length (at least for now). + // On ZKsync, access lists are always zero length (at least for now). bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); bytes memory rEncoded; diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index 6be56db16..00145480b 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT - -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol"; @@ -16,7 +15,7 @@ import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol"; import {IBootloaderUtilities} from "./interfaces/IBootloaderUtilities.sol"; import {IPubdataChunkPublisher} from "./interfaces/IPubdataChunkPublisher.sol"; -/// @dev All the system contracts introduced by zkSync have their addresses +/// @dev All the system contracts introduced by ZKsync have their addresses /// started from 2^15 in order to avoid collision with Ethereum precompiles. uint160 constant SYSTEM_CONTRACTS_OFFSET = {{SYSTEM_CONTRACTS_OFFSET}}; // 2^15 diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index a61eae096..8e9bda169 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -15,7 +15,7 @@ import {Unauthorized, InvalidNonceOrderingChange, ValueMismatch, EmptyBytes32, N /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev - * @notice System smart contract that is responsible for deploying other smart contracts on zkSync. + * @notice System smart contract that is responsible for deploying other smart contracts on ZKsync. * @dev The contract is responsible for generating the address of the deployed smart contract, * incrementing the deployment nonce and making sure that the constructor is never called twice in a contract. * Note, contracts with bytecode that have already been published to L1 once diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol index f95879643..b5dfc8276 100644 --- a/system-contracts/contracts/SystemContractErrors.sol +++ b/system-contracts/contracts/SystemContractErrors.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT - -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; // 0x86bb51b8 diff --git a/system-contracts/contracts/abstract/SystemContractBase.sol b/system-contracts/contracts/abstract/SystemContractBase.sol index bb461df21..89966a576 100644 --- a/system-contracts/contracts/abstract/SystemContractBase.sol +++ b/system-contracts/contracts/abstract/SystemContractBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {SystemContractHelper} from "../libraries/SystemContractHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IAccount.sol b/system-contracts/contracts/interfaces/IAccount.sol index dad81b1b2..cebe91d17 100644 --- a/system-contracts/contracts/interfaces/IAccount.sol +++ b/system-contracts/contracts/interfaces/IAccount.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {Transaction} from "../libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol index 0115393a1..5183e77f6 100644 --- a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol +++ b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IAccountCodeStorage { diff --git a/system-contracts/contracts/interfaces/IBaseToken.sol b/system-contracts/contracts/interfaces/IBaseToken.sol index b5a4cf912..fc32c7b83 100644 --- a/system-contracts/contracts/interfaces/IBaseToken.sol +++ b/system-contracts/contracts/interfaces/IBaseToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IBaseToken { diff --git a/system-contracts/contracts/interfaces/IBootloaderUtilities.sol b/system-contracts/contracts/interfaces/IBootloaderUtilities.sol index 4437c9807..e900bfb5e 100644 --- a/system-contracts/contracts/interfaces/IBootloaderUtilities.sol +++ b/system-contracts/contracts/interfaces/IBootloaderUtilities.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {Transaction} from "../libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IComplexUpgrader.sol b/system-contracts/contracts/interfaces/IComplexUpgrader.sol index 8ed670a10..3b1468417 100644 --- a/system-contracts/contracts/interfaces/IComplexUpgrader.sol +++ b/system-contracts/contracts/interfaces/IComplexUpgrader.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/interfaces/ICompressor.sol b/system-contracts/contracts/interfaces/ICompressor.sol index 077f30a2b..854aa7904 100644 --- a/system-contracts/contracts/interfaces/ICompressor.sol +++ b/system-contracts/contracts/interfaces/ICompressor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; // The bitmask by applying which to the compressed state diff metadata we retrieve its operation. diff --git a/system-contracts/contracts/interfaces/IContractDeployer.sol b/system-contracts/contracts/interfaces/IContractDeployer.sol index e8ce701eb..6e0bac3dc 100644 --- a/system-contracts/contracts/interfaces/IContractDeployer.sol +++ b/system-contracts/contracts/interfaces/IContractDeployer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IContractDeployer { diff --git a/system-contracts/contracts/interfaces/IImmutableSimulator.sol b/system-contracts/contracts/interfaces/IImmutableSimulator.sol index cb7027fa1..840053849 100644 --- a/system-contracts/contracts/interfaces/IImmutableSimulator.sol +++ b/system-contracts/contracts/interfaces/IImmutableSimulator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; struct ImmutableData { diff --git a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol index 39687ddfc..551cfb0d8 100644 --- a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol +++ b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/interfaces/IL1Messenger.sol b/system-contracts/contracts/interfaces/IL1Messenger.sol index 808b5a082..88e2c81d8 100644 --- a/system-contracts/contracts/interfaces/IL1Messenger.sol +++ b/system-contracts/contracts/interfaces/IL1Messenger.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /// @dev The log passed from L2 diff --git a/system-contracts/contracts/interfaces/IL2StandardToken.sol b/system-contracts/contracts/interfaces/IL2StandardToken.sol index 3439ba3c6..d67a3ea1f 100644 --- a/system-contracts/contracts/interfaces/IL2StandardToken.sol +++ b/system-contracts/contracts/interfaces/IL2StandardToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IL2StandardToken { diff --git a/system-contracts/contracts/interfaces/IMailbox.sol b/system-contracts/contracts/interfaces/IMailbox.sol index 703612039..a9dcdad05 100644 --- a/system-contracts/contracts/interfaces/IMailbox.sol +++ b/system-contracts/contracts/interfaces/IMailbox.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; interface IMailbox { diff --git a/system-contracts/contracts/interfaces/INonceHolder.sol b/system-contracts/contracts/interfaces/INonceHolder.sol index 30af5d100..ce3b0279d 100644 --- a/system-contracts/contracts/interfaces/INonceHolder.sol +++ b/system-contracts/contracts/interfaces/INonceHolder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/interfaces/IPaymaster.sol b/system-contracts/contracts/interfaces/IPaymaster.sol index 68d520eee..1c8af5b28 100644 --- a/system-contracts/contracts/interfaces/IPaymaster.sol +++ b/system-contracts/contracts/interfaces/IPaymaster.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {Transaction} from "../libraries/TransactionHelper.sol"; diff --git a/system-contracts/contracts/interfaces/IPaymasterFlow.sol b/system-contracts/contracts/interfaces/IPaymasterFlow.sol index 0458c3026..4c9683fd4 100644 --- a/system-contracts/contracts/interfaces/IPaymasterFlow.sol +++ b/system-contracts/contracts/interfaces/IPaymasterFlow.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol b/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol index 15faadf66..47893abdb 100644 --- a/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol +++ b/system-contracts/contracts/interfaces/IPubdataChunkPublisher.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/interfaces/ISystemContext.sol b/system-contracts/contracts/interfaces/ISystemContext.sol index 9926d197d..6b9a37fce 100644 --- a/system-contracts/contracts/interfaces/ISystemContext.sol +++ b/system-contracts/contracts/interfaces/ISystemContext.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol b/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol index a7f3740be..ac5153270 100644 --- a/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol +++ b/system-contracts/contracts/interfaces/ISystemContextDeprecated.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/libraries/EfficientCall.sol b/system-contracts/contracts/libraries/EfficientCall.sol index 8f203b02a..27fea6396 100644 --- a/system-contracts/contracts/libraries/EfficientCall.sol +++ b/system-contracts/contracts/libraries/EfficientCall.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {SystemContractHelper, ADDRESS_MASK} from "./SystemContractHelper.sol"; diff --git a/system-contracts/contracts/libraries/RLPEncoder.sol b/system-contracts/contracts/libraries/RLPEncoder.sol index b21969731..16eaa4053 100644 --- a/system-contracts/contracts/libraries/RLPEncoder.sol +++ b/system-contracts/contracts/libraries/RLPEncoder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol index 0f832dc79..e8469e308 100644 --- a/system-contracts/contracts/libraries/SystemContractHelper.sol +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; diff --git a/system-contracts/contracts/libraries/SystemContractsCaller.sol b/system-contracts/contracts/libraries/SystemContractsCaller.sol index 14f361c6f..9497b0c52 100644 --- a/system-contracts/contracts/libraries/SystemContractsCaller.sol +++ b/system-contracts/contracts/libraries/SystemContractsCaller.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {MSG_VALUE_SYSTEM_CONTRACT, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT} from "../Constants.sol"; import {Utils} from "./Utils.sol"; // Addresses used for the compiler to be replaced with the -// zkSync-specific opcodes during the compilation. +// ZKsync-specific opcodes during the compilation. // IMPORTANT: these are just compile-time constants and are used // only if used in-place by Yul optimizer. address constant TO_L1_CALL_ADDRESS = address((1 << 16) - 1); diff --git a/system-contracts/contracts/libraries/TransactionHelper.sol b/system-contracts/contracts/libraries/TransactionHelper.sol index e34599d39..467eb57f9 100644 --- a/system-contracts/contracts/libraries/TransactionHelper.sol +++ b/system-contracts/contracts/libraries/TransactionHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {IERC20} from "../openzeppelin/token/ERC20/IERC20.sol"; @@ -11,7 +11,7 @@ import {RLPEncoder} from "./RLPEncoder.sol"; import {EfficientCall} from "./EfficientCall.sol"; import {UnsupportedTxType, InvalidInput, UnsupportedPaymasterFlow} from "../SystemContractErrors.sol"; -/// @dev The type id of zkSync's EIP-712-signed transaction. +/// @dev The type id of ZKsync's EIP-712-signed transaction. uint8 constant EIP_712_TX_TYPE = 0x71; /// @dev The type id of legacy transactions. @@ -21,7 +21,7 @@ uint8 constant EIP_2930_TX_TYPE = 0x01; /// @dev The type id of EIP1559 transactions. uint8 constant EIP_1559_TX_TYPE = 0x02; -/// @notice Structure used to represent a zkSync transaction. +/// @notice Structure used to represent a ZKsync transaction. struct Transaction { // The type of the transaction. uint256 txType; @@ -114,7 +114,7 @@ library TransactionHelper { } } - /// @notice Encode hash of the zkSync native transaction type. + /// @notice Encode hash of the ZKsync native transaction type. /// @return keccak256 hash of the EIP-712 encoded representation of transaction function _encodeHashEIP712Transaction(Transaction calldata _transaction) private view returns (bytes32) { bytes32 structHash = keccak256( @@ -223,7 +223,7 @@ library TransactionHelper { // Hash of EIP2930 transactions is encoded the following way: // H(0x01 || RLP(chain_id, nonce, gas_price, gas_limit, destination, amount, data, access_list)) // - // Note, that on zkSync access lists are not supported and should always be empty. + // Note, that on ZKsync access lists are not supported and should always be empty. // Encode all fixed-length params to avoid "stack too deep error" bytes memory encodedFixedLengthParams; @@ -261,7 +261,7 @@ library TransactionHelper { // Otherwise the length is not encoded at all. } - // On zkSync, access lists are always zero length (at least for now). + // On ZKsync, access lists are always zero length (at least for now). bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); bytes memory encodedListLength; @@ -295,7 +295,7 @@ library TransactionHelper { // Hash of EIP1559 transactions is encoded the following way: // H(0x02 || RLP(chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list)) // - // Note, that on zkSync access lists are not supported and should always be empty. + // Note, that on ZKsync access lists are not supported and should always be empty. // Encode all fixed-length params to avoid "stack too deep error" bytes memory encodedFixedLengthParams; @@ -335,7 +335,7 @@ library TransactionHelper { // Otherwise the length is not encoded at all. } - // On zkSync, access lists are always zero length (at least for now). + // On ZKsync, access lists are always zero length (at least for now). bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0); bytes memory encodedListLength; diff --git a/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol b/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol index 4c72d3542..82b4c5c1d 100644 --- a/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol +++ b/system-contracts/contracts/libraries/UnsafeBytesCalldata.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; /** diff --git a/system-contracts/contracts/libraries/Utils.sol b/system-contracts/contracts/libraries/Utils.sol index b4a843d9b..fc23de94b 100644 --- a/system-contracts/contracts/libraries/Utils.sol +++ b/system-contracts/contracts/libraries/Utils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; import {EfficientCall} from "./EfficientCall.sol"; @@ -8,7 +8,7 @@ import {MalformedBytecode, BytecodeError, Overflow} from "../SystemContractError /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev - * @dev Common utilities used in zkSync system contracts + * @dev Common utilities used in ZKsync system contracts */ library Utils { /// @dev Bit mask of bytecode hash "isConstructor" marker diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol b/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol index dc3ad760b..18b39a7a9 100644 --- a/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol +++ b/system-contracts/contracts/openzeppelin/token/ERC20/IERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol b/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol index d98bfbce9..5e0875438 100644 --- a/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol +++ b/system-contracts/contracts/openzeppelin/token/ERC20/extensions/IERC20Permit.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** diff --git a/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol b/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol index 2c94d1b59..a23e6d1f7 100644 --- a/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol +++ b/system-contracts/contracts/openzeppelin/token/ERC20/utils/SafeERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; import {IERC20} from "../IERC20.sol"; diff --git a/system-contracts/contracts/openzeppelin/utils/Address.sol b/system-contracts/contracts/openzeppelin/utils/Address.sol index 9669a9c14..5d6de78c4 100644 --- a/system-contracts/contracts/openzeppelin/utils/Address.sol +++ b/system-contracts/contracts/openzeppelin/utils/Address.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) -// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.1; /** diff --git a/system-contracts/scripts/constants.ts b/system-contracts/scripts/constants.ts index 406b4cb6e..b354c36ab 100644 --- a/system-contracts/scripts/constants.ts +++ b/system-contracts/scripts/constants.ts @@ -184,7 +184,7 @@ export const EIP712_DOMAIN = { name: "zkSync", version: "2", chainId: CHAIN_ID, - // zkSync contract doesn't verify EIP712 signatures. + // ZKsync contract doesn't verify EIP712 signatures. }; export interface TransactionData { diff --git a/system-contracts/scripts/deploy-preimages.ts b/system-contracts/scripts/deploy-preimages.ts index 7a4a96880..0029f56a0 100644 --- a/system-contracts/scripts/deploy-preimages.ts +++ b/system-contracts/scripts/deploy-preimages.ts @@ -103,7 +103,7 @@ class ZkSyncDeployer { this.nonce += 1; } - // Returns the current default account bytecode on zkSync + // Returns the current default account bytecode on ZKsync async currentDefaultAccountBytecode(): Promise { const zkSync = await this.deployer.zkWallet.getMainContract(); return await zkSync.getL2DefaultAccountBytecodeHash(); @@ -114,7 +114,7 @@ class ZkSyncDeployer { const bytecodeHash = ethers.utils.hexlify(hashBytecode(defaultAccountBytecode)); const currentDefaultAccountBytecode = ethers.utils.hexlify(await this.currentDefaultAccountBytecode()); - // If the bytecode is not the same as the one deployed on zkSync, we need to add it to the deployment + // If the bytecode is not the same as the one deployed on ZKsync, we need to add it to the deployment if (bytecodeHash.toLowerCase() !== currentDefaultAccountBytecode) { this.defaultAccountToUpgrade = { name: DEFAULT_ACCOUNT_CONTRACT_NAME, @@ -161,7 +161,7 @@ class ZkSyncDeployer { const bytecodeHash = ethers.utils.hexlify(hashBytecode(bootloaderCode)); const currentBootloaderBytecode = ethers.utils.hexlify(await this.currentBootloaderBytecode()); - // If the bytecode is not the same as the one deployed on zkSync, we need to add it to the deployment + // If the bytecode is not the same as the one deployed on ZKsync, we need to add it to the deployment if (bytecodeHash.toLowerCase() !== currentBootloaderBytecode) { this.bootloaderToUpgrade = { name: BOOTLOADER_CONTRACT_NAME, diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts index e06c14e50..4c1060ee2 100644 --- a/system-contracts/scripts/utils.ts +++ b/system-contracts/scripts/utils.ts @@ -84,7 +84,7 @@ export async function outputSystemContracts(): Promise { return await Promise.all(upgradeParamsPromises); } -// Script that publishes preimages for all the system contracts on zkSync +// Script that publishes preimages for all the system contracts on ZKsync // and outputs the JSON that can be used for performing the necessary upgrade const DEFAULT_L2_TX_GAS_LIMIT = 2097152; diff --git a/tools/data/verifier_contract_template.txt b/tools/data/verifier_contract_template.txt index 972123961..5ef32b2c5 100644 --- a/tools/data/verifier_contract_template.txt +++ b/tools/data/verifier_contract_template.txt @@ -8,14 +8,14 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @author Matter Labs /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. -/// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. +/// Modifications have been made to optimize the proof system for ZKsync hyperchain circuits. /// @dev Contract was generated from a verification key with a hash of 0x{{vk_hash}} /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: /// * Original Plonk Article: https://eprint.iacr.org/2019/953.pdf /// * Original LookUp Article: https://eprint.iacr.org/2020/315.pdf -/// * Plonk for zkSync v1.1: https://github.com/matter-labs/solidity_plonk_verifier/raw/recursive/bellman_vk_codegen_recursive/RecursivePlonkUnrolledForEthereum.pdf +/// * Plonk for ZKsync v1.1: https://github.com/matter-labs/solidity_plonk_verifier/raw/recursive/bellman_vk_codegen_recursive/RecursivePlonkUnrolledForEthereum.pdf /// The notation used in the code is the same as in the papers. /* solhint-enable max-line-length */ contract Verifier is IVerifier { From dba02125a95096e7b1b13672736c4e759fb78099 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Wed, 28 Aug 2024 17:18:41 -0400 Subject: [PATCH 35/42] chore(contracts): add missing spdx licenses (#732) --- .../IZkSyncHyperchainBase.sol | 4 +- .../l2-deps/ISystemContext.sol | 4 +- l1-contracts/deploy-scripts/AcceptAdmin.s.sol | 2 +- .../deploy-scripts/DeployL2Contracts.sol | 2 + .../deploy-scripts/DeployPaymaster.s.sol | 3 +- .../Bridgehub/experimental_bridge.t.sol | 2 +- system-contracts/SystemContractsHashes.json | 56 +++++++++---------- system-contracts/bootloader/bootloader.yul | 2 + system-contracts/contracts/EventWriter.yul | 2 + .../contracts/precompiles/CodeOracle.yul | 2 + .../contracts/precompiles/EcAdd.yul | 2 + .../contracts/precompiles/EcMul.yul | 2 + .../contracts/precompiles/EcPairing.yul | 2 + .../contracts/precompiles/Ecrecover.yul | 2 + .../contracts/precompiles/Keccak256.yul | 2 + .../contracts/precompiles/P256Verify.yul | 2 + .../contracts/precompiles/SHA256.yul | 2 + .../test-contracts/Keccak256Mock.yul | 2 + .../test-contracts/CodeOracleTest.sol | 2 +- .../contracts/test-contracts/TransferTest.sol | 2 +- 20 files changed, 62 insertions(+), 37 deletions(-) diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol index 24fe3b482..3cd646cc9 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchainBase.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: UNLICENSED -// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. +// SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @title The interface of the ZKsync contract, responsible for the main ZKsync logic. diff --git a/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol b/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol index d09e76491..d3244b74b 100644 --- a/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol +++ b/l1-contracts/contracts/state-transition/l2-deps/ISystemContext.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: UNLICENSED -// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. +// SPDX-License-Identifier: MIT +// We use a floating point pragma here so it can be used within other projects that interact with the zkSync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; interface ISystemContext { diff --git a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol index bb601457b..3a40b4d78 100644 --- a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol +++ b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import {Script} from "forge-std/Script.sol"; diff --git a/l1-contracts/deploy-scripts/DeployL2Contracts.sol b/l1-contracts/deploy-scripts/DeployL2Contracts.sol index 0d7c1e0bb..6e3b5248b 100644 --- a/l1-contracts/deploy-scripts/DeployL2Contracts.sol +++ b/l1-contracts/deploy-scripts/DeployL2Contracts.sol @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + pragma solidity ^0.8.21; import {Script} from "forge-std/Script.sol"; diff --git a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol index 08374e3d1..eec87fbb0 100644 --- a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol +++ b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol @@ -1,4 +1,5 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT + pragma solidity ^0.8.21; import {Script} from "forge-std/Script.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol index 27174089b..b454a5299 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol @@ -1,4 +1,4 @@ -//SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.24; diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 2e885b9f5..18da55393 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -115,98 +115,98 @@ "contractName": "EventWriter", "bytecodePath": "contracts-preprocessed/artifacts/EventWriter.yul.zbin", "sourceCodePath": "contracts-preprocessed/EventWriter.yul", - "bytecodeHash": "0x010000159a3a08da3ac57cdefec0e9e30da60456bc5643134cf16d6957bcf1ac", - "sourceCodeHash": "0x55cfee65f174350edfd690c949bc0a29458f25da11f1d5f90b57621567df1fc3" + "bytecodeHash": "0x010000159b30cba9e2096353695b63ca5cbf566416a545a6bcb2ff2e4e672f98", + "sourceCodeHash": "0xfcf4828bcc109dea5f88c38f428d9ac5e18d5a2767fa4909277802c7e38c1f93" }, { "contractName": "CodeOracle", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/CodeOracle.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/CodeOracle.yul", - "bytecodeHash": "0x01000023b02bbb21baf1367835e56ae17b82688527dc8f78caf34b12e670ee65", - "sourceCodeHash": "0x55692fab0ef8b5bab3f6fb77aec84f3d1f1cdf97c0640b327d10594ea61218d2" + "bytecodeHash": "0x01000023d652655672eafbb0adc385bd423a4a59f752a28f3dde16e74fa205e3", + "sourceCodeHash": "0x476063e7907f2b7a532c4da6f606fa07186b5a10d77af8fdd83dbea3d9f23f93" }, { "contractName": "EcAdd", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcAdd.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/EcAdd.yul", - "bytecodeHash": "0x010000872dd7e2dc1b34416c174086aa84fd80c78acc7b670214da955bd55728", - "sourceCodeHash": "0xc04879ed27207cd276997a856b6507d6d003801a2ee4c4bb4491f0032370895f" + "bytecodeHash": "0x01000087be6181fcb16bebb0567c58b658eec345822aec1d42d471e84f758b85", + "sourceCodeHash": "0xdfec1c5f8c6a93df1c8821f1ac15058a18a640bcbdeb67dc4a017f2153ff1c86" }, { "contractName": "EcMul", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcMul.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/EcMul.yul", - "bytecodeHash": "0x010000bd8bd7ab008f76e359dc296ff5fe0e8a95fedce1d570943e90143acdfd", - "sourceCodeHash": "0xb142465167a02139087fda7640ff859489b33081dcc7c2a8089da5b480bcb58c" + "bytecodeHash": "0x010000bd553a916fcda3726f7b6b3ccfc17887166982915ced63abc78ba43b66", + "sourceCodeHash": "0x0e3f320c8a9532425b85809bf0a2136e707046a01bf20491ec03c77887516c43" }, { "contractName": "EcPairing", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcPairing.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/EcPairing.yul", - "bytecodeHash": "0x01000f1b3432a32f9fba2115f5dd3b0ee8127e7bf2c609d57d3e231f19119c43", - "sourceCodeHash": "0x149f025b222369ab65b9995a6d61df8b557b23f8b52a05f21dc2164839befb18" + "bytecodeHash": "0x01000f1b5f8dd50a00b502d2663746a49a81a01857b6ee1e1b38c9959142b299", + "sourceCodeHash": "0x5d008cedc44e0e52c2567fd2b877916b2ec5e7c80294cf99b66485e50a6f2c12" }, { "contractName": "Ecrecover", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Ecrecover.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/Ecrecover.yul", - "bytecodeHash": "0x0100001112e34172b2bc31574d155893a087a1cf4b608cf9895a2201ea7bd6ee", - "sourceCodeHash": "0xe2334f04fa8003d448c7e6bfb345e644f2c851328aa5b49cb30acf45d6e0bbcf" + "bytecodeHash": "0x010000113d6b03e34605f26aa1fc6fb8953561eb55bb5ea192a5a38f7de3053b", + "sourceCodeHash": "0x21e03ab7a5f518a21258669c82506b1d4d1141f8fd4f30bb385f9730580ddd3c" }, { "contractName": "Keccak256", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Keccak256.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/Keccak256.yul", - "bytecodeHash": "0x0100000f248e111a1b587fef850dc4585c39af2dd505bc8a0d5cc6d3fcc7ed3c", - "sourceCodeHash": "0x3e6b02b36eb6d8cebe19ae258c2aed531f9be6c261ae02d301ba31b2cd388776" + "bytecodeHash": "0x0100000ff991d5847f1e9c10c5969d0f03b34a25411ad86d5cb3e0d9c3931e0b", + "sourceCodeHash": "0xb454e7760732ce1fffc75174c8cf54dca422206cf1e52a29d274b310b574f26d" }, { "contractName": "P256Verify", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/P256Verify.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/P256Verify.yul", - "bytecodeHash": "0x0100001169cd6aa311c1bc9bbe2e7dd085720c96bb197e3223be7e9c66e46ef9", - "sourceCodeHash": "0x4fa14862937a646a2440a8ef5c4358b59e3e53dff5f11a65a1167cd31894b94c" + "bytecodeHash": "0x010000116595cfcc96291f95d47ede2ce630f25ccbd7428f00dc7f8135fb565a", + "sourceCodeHash": "0x976b68d0362307313fd1aaea309eaa2d849187f37da451618c70dd3a6ac3cf3c" }, { "contractName": "SHA256", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/SHA256.yul.zbin", "sourceCodePath": "contracts-preprocessed/precompiles/SHA256.yul", - "bytecodeHash": "0x0100001752dc8a1a374a6346781205017b7b594d97c28812265865f3a45fcb45", - "sourceCodeHash": "0x6de4b57a9cca1cfda7a8edbf6f3e06aafa32c70458a3cc09972b548714ec51d3" + "bytecodeHash": "0x010000171e4e61b14feacd43cb555bffa5f194d38117132957708dcef83ac15a", + "sourceCodeHash": "0xfd4290467e26e992f39db9ca132e78ce99ce042b0254a368f1d7832dc94ddefb" }, { "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cbe23de2836aebbf2466f6899f7b19ad6dc5ff6e3ce10c83b16cad1b90", - "sourceCodeHash": "0xa7ac131c18e0b890282de1c328802a9c9c454c0c09d0bd015a06abb411556638" + "bytecodeHash": "0x010003cbe67434b2848054322cbc311385851bbfbf70d17f92cd5f1f9836b25e", + "sourceCodeHash": "0x006fdf461899dec5fdb34301c23e6819eb93e275907cbfc67d73fccfb47cae68" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x0100092d97e147d5fb59598c2d3ab1bb9bcada3fbc538f05fde153731d0e34aa", - "sourceCodeHash": "0x31b38c5e26c4d6acad6cbbb5677648818ab930d146354814666cb855a595f23a" + "bytecodeHash": "0x0100092d9b8ae575bca569f68fe60fbef1dc7d4aad6aa02cc4836f56afcf0a38", + "sourceCodeHash": "0x8a858319bac2924a3dee778218a7fe5e23898db0d87b02d7b783f94c5a02d257" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008b3324dc1065661a15eaefc44278fb555d6a561621c2c73935e7eb6d680", - "sourceCodeHash": "0xc9b10f7ceedf8883248be7d0e265fe076419df02bd59b8cbd701e92bced01472" + "bytecodeHash": "0x010008b3e1b8bdd393f2f8d6f5c994c8b9c287df7310dee75d0c52a245fc7cb1", + "sourceCodeHash": "0x89f5ad470f10e755fa57b82507518e571c24409a328bc33aeba26e9518ad1c3e" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x010009339beeb192c26f6cb18a67f446a578f10c145c8af344fe67b2772e4311", - "sourceCodeHash": "0xd4b0391e9d227e782934520d98eb66226d79ad1a6cfe422e624d7eee0d1e8bfc" + "bytecodeHash": "0x01000933061c23d700f3f647c45068e22f5506ff33bb516ac13f11069b163986", + "sourceCodeHash": "0x769448c4fd2b65c43d758ca5f34dd29d9b9dd3000fd0ec89cffcaf8d365a64fd" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008c314c516939d65ffcab410b9dcff5e7be81c4561adf171818984efc39c", - "sourceCodeHash": "0xdd2fb790fb11009d203b7933123cc51bfd00b7e96cc90006c05e2d31a5581477" + "bytecodeHash": "0x010008c3be57ae5800e077b6c2056d9d75ad1a7b4f0ce583407961cc6fe0b678", + "sourceCodeHash": "0x908bc6ddb34ef89b125e9637239a1149deacacd91255781d82a65a542a39036e" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index a9a3a1725..e995e7151 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + object "Bootloader" { code { } diff --git a/system-contracts/contracts/EventWriter.yul b/system-contracts/contracts/EventWriter.yul index 4cd4a3814..c85151b90 100644 --- a/system-contracts/contracts/EventWriter.yul +++ b/system-contracts/contracts/EventWriter.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/system-contracts/contracts/precompiles/CodeOracle.yul b/system-contracts/contracts/precompiles/CodeOracle.yul index 820b8df70..63b386788 100644 --- a/system-contracts/contracts/precompiles/CodeOracle.yul +++ b/system-contracts/contracts/precompiles/CodeOracle.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/system-contracts/contracts/precompiles/EcAdd.yul b/system-contracts/contracts/precompiles/EcAdd.yul index 5771df8f9..8b7f25618 100644 --- a/system-contracts/contracts/precompiles/EcAdd.yul +++ b/system-contracts/contracts/precompiles/EcAdd.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + object "EcAdd" { code { return(0, 0) diff --git a/system-contracts/contracts/precompiles/EcMul.yul b/system-contracts/contracts/precompiles/EcMul.yul index 84838ec2a..63fd0bc42 100644 --- a/system-contracts/contracts/precompiles/EcMul.yul +++ b/system-contracts/contracts/precompiles/EcMul.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + object "EcMul" { code { return(0, 0) diff --git a/system-contracts/contracts/precompiles/EcPairing.yul b/system-contracts/contracts/precompiles/EcPairing.yul index 6ea6e92de..5e8011bcc 100644 --- a/system-contracts/contracts/precompiles/EcPairing.yul +++ b/system-contracts/contracts/precompiles/EcPairing.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + object "EcPairing" { code { return(0, 0) diff --git a/system-contracts/contracts/precompiles/Ecrecover.yul b/system-contracts/contracts/precompiles/Ecrecover.yul index cbb8fcc0f..9c64d509f 100644 --- a/system-contracts/contracts/precompiles/Ecrecover.yul +++ b/system-contracts/contracts/precompiles/Ecrecover.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/system-contracts/contracts/precompiles/Keccak256.yul b/system-contracts/contracts/precompiles/Keccak256.yul index 8eaa53671..397ee89bb 100644 --- a/system-contracts/contracts/precompiles/Keccak256.yul +++ b/system-contracts/contracts/precompiles/Keccak256.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/system-contracts/contracts/precompiles/P256Verify.yul b/system-contracts/contracts/precompiles/P256Verify.yul index 8cd14beb2..80b782209 100644 --- a/system-contracts/contracts/precompiles/P256Verify.yul +++ b/system-contracts/contracts/precompiles/P256Verify.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/system-contracts/contracts/precompiles/SHA256.yul b/system-contracts/contracts/precompiles/SHA256.yul index ff52632cd..8173502ef 100644 --- a/system-contracts/contracts/precompiles/SHA256.yul +++ b/system-contracts/contracts/precompiles/SHA256.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/system-contracts/contracts/precompiles/test-contracts/Keccak256Mock.yul b/system-contracts/contracts/precompiles/test-contracts/Keccak256Mock.yul index b37eb69ca..e3cb9ac1e 100644 --- a/system-contracts/contracts/precompiles/test-contracts/Keccak256Mock.yul +++ b/system-contracts/contracts/precompiles/test-contracts/Keccak256Mock.yul @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MIT + /** * @author Matter Labs * @notice The contract used to emulate EVM's keccak256 opcode. diff --git a/system-contracts/contracts/test-contracts/CodeOracleTest.sol b/system-contracts/contracts/test-contracts/CodeOracleTest.sol index f022fb77b..31de9d366 100644 --- a/system-contracts/contracts/test-contracts/CodeOracleTest.sol +++ b/system-contracts/contracts/test-contracts/CodeOracleTest.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; diff --git a/system-contracts/contracts/test-contracts/TransferTest.sol b/system-contracts/contracts/test-contracts/TransferTest.sol index 1b9e9bd75..ca76a9932 100644 --- a/system-contracts/contracts/test-contracts/TransferTest.sol +++ b/system-contracts/contracts/test-contracts/TransferTest.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; From 874bc6ba940de9d37b474d1e3dda2fe4e869dfbe Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 29 Aug 2024 10:06:51 -0400 Subject: [PATCH 36/42] fix(scrips): read bytecode from foundry not hardhat (#750) --- .../PrepareZKChainRegistrationCalldata.s.sol | 3 +-- l1-contracts/deploy-scripts/Utils.sol | 13 ++++++++++++- l2-contracts/foundry.toml | 4 ++-- l2-contracts/lib/openzeppelin-contracts | 1 - l2-contracts/lib/openzeppelin-contracts-upgradeable | 1 - .../lib/openzeppelin-contracts-upgradeable-v4 | 1 + l2-contracts/lib/openzeppelin-contracts-v4 | 1 + 7 files changed, 17 insertions(+), 7 deletions(-) delete mode 120000 l2-contracts/lib/openzeppelin-contracts delete mode 120000 l2-contracts/lib/openzeppelin-contracts-upgradeable create mode 120000 l2-contracts/lib/openzeppelin-contracts-upgradeable-v4 create mode 120000 l2-contracts/lib/openzeppelin-contracts-v4 diff --git a/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol b/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol index 3810805c8..0a7e20a53 100644 --- a/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol +++ b/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -// solhint-disable no-console +// solhint-disable no-console, gas-struct-packing, gas-custom-errors import {Script, console2 as console} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; @@ -13,7 +13,6 @@ import {AddressAliasHelper} from "contracts/vendor/AddressAliasHelper.sol"; import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; -import {IERC20} from "forge-std/interfaces/IERC20.sol"; import {Utils} from "./Utils.sol"; /** diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 24011951b..17449da7e 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -285,7 +285,7 @@ library Utils { } /** - * @dev Read hardhat bytecodes + * @dev Read foundry bytecodes */ function readFoundryBytecode(string memory artifactPath) internal view returns (bytes memory) { string memory root = vm.projectRoot(); @@ -295,6 +295,17 @@ library Utils { return bytecode; } + /** + * @dev Read hardhat bytecodes + */ + function readHardhatBytecode(string memory artifactPath) internal view returns (bytes memory) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, artifactPath); + string memory json = vm.readFile(path); + bytes memory bytecode = vm.parseJsonBytes(json, ".bytecode"); + return bytecode; + } + function executeUpgrade( address _governor, bytes32 _salt, diff --git a/l2-contracts/foundry.toml b/l2-contracts/foundry.toml index d34805bfe..deb178a12 100644 --- a/l2-contracts/foundry.toml +++ b/l2-contracts/foundry.toml @@ -5,8 +5,8 @@ libs = ["lib"] cache_path = "cache-forge" evm_version = "paris" remappings = [ - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", - "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", + "@openzeppelin/contracts-v4/=lib/openzeppelin-contracts-v4/contracts/", + "@openzeppelin/contracts-upgradeable-v4/=lib/openzeppelin-contracts-upgradeable-v4/contracts/", ] [profile.default.zksync] diff --git a/l2-contracts/lib/openzeppelin-contracts b/l2-contracts/lib/openzeppelin-contracts deleted file mode 120000 index 99aa45507..000000000 --- a/l2-contracts/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -../../lib/openzeppelin-contracts \ No newline at end of file diff --git a/l2-contracts/lib/openzeppelin-contracts-upgradeable b/l2-contracts/lib/openzeppelin-contracts-upgradeable deleted file mode 120000 index f1fc7a76a..000000000 --- a/l2-contracts/lib/openzeppelin-contracts-upgradeable +++ /dev/null @@ -1 +0,0 @@ -../../lib/openzeppelin-contracts-upgradeable \ No newline at end of file diff --git a/l2-contracts/lib/openzeppelin-contracts-upgradeable-v4 b/l2-contracts/lib/openzeppelin-contracts-upgradeable-v4 new file mode 120000 index 000000000..0551b6016 --- /dev/null +++ b/l2-contracts/lib/openzeppelin-contracts-upgradeable-v4 @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-upgradeable-v4 \ No newline at end of file diff --git a/l2-contracts/lib/openzeppelin-contracts-v4 b/l2-contracts/lib/openzeppelin-contracts-v4 new file mode 120000 index 000000000..693e94537 --- /dev/null +++ b/l2-contracts/lib/openzeppelin-contracts-v4 @@ -0,0 +1 @@ +../../lib/openzeppelin-contracts-v4 \ No newline at end of file From 7f2c27afa0af89105e69071f2513112c2bcaac72 Mon Sep 17 00:00:00 2001 From: Raid5594 <52794079+Raid5594@users.noreply.github.com> Date: Tue, 3 Sep 2024 19:43:12 +0400 Subject: [PATCH 37/42] Small PR to Fix "Ethers" and "ETH" encoding (#762) Co-authored-by: Raid Ateir --- l1-contracts/contracts/bridge/L1SharedBridge.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index eec3c2e69..56b621c18 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -413,8 +413,8 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @dev Receives and parses (name, symbol, decimals) from the token contract function _getERC20Getters(address _token) internal view returns (bytes memory) { if (_token == ETH_TOKEN_ADDRESS) { - bytes memory name = bytes("Ether"); - bytes memory symbol = bytes("ETH"); + bytes memory name = abi.encode("Ether"); + bytes memory symbol = abi.encode("ETH"); bytes memory decimals = abi.encode(uint8(18)); return abi.encode(name, symbol, decimals); // when depositing eth to a non-eth based chain it is an ERC20 } From 3d6e02f9a802ac6a8f6bfe8f52fce81e72ce0bbe Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:19:21 +0300 Subject: [PATCH 38/42] Set foundry optimizer_runs (#770) --- l1-contracts/foundry.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index 4d52d0400..57dd0744a 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -26,3 +26,5 @@ remappings = [ "@openzeppelin/contracts-v4/=lib/openzeppelin-contracts-v4/contracts/", "@openzeppelin/contracts-upgradeable-v4/=lib/openzeppelin-contracts-upgradeable-v4/contracts/", ] +optimizer = true +optimizer_runs = 9999999 From 1fba03d3c6c5e3412f19b9960c1931efc6b17380 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Fri, 27 Sep 2024 12:21:02 -0400 Subject: [PATCH 39/42] merging main (#824) --- gas-bound-caller/package.json | 3 +- .../contracts/bridge/L1SharedBridge.sol | 53 +- .../bridge/interfaces/IL1SharedBridge.sol | 15 + .../contracts/bridgehub/Bridgehub.sol | 2 +- .../config-deploy-l2-config.toml | 1 + l1-contracts/deploy-scripts/DeployL1.s.sol | 4 + .../deploy-scripts/DeployL2Contracts.sol | 165 +++++- .../deploy-scripts/RegisterHyperchain.s.sol | 26 +- l1-contracts/deploy-scripts/Utils.sol | 10 + .../dev/SetupLegacyBridge.s.sol | 161 ++++++ .../Bridgehub/experimental_bridge.t.sol | 17 +- .../L1SharedBridge/L1SharedBridgeAdmin.t.sol | 26 + .../L1SharedBridge/L1SharedBridgeFails.t.sol | 6 +- .../_L1SharedBridge_Shared.t.sol | 8 +- l2-contracts/contracts/ConsensusRegistry.sol | 486 +++++++++++++++++ .../contracts/dev-contracts/Multicall3.sol | 237 +++++++++ .../interfaces/IConsensusRegistry.sol | 161 ++++++ l2-contracts/package.json | 3 +- l2-contracts/src/deploy-consensus-registry.ts | 90 ++++ l2-contracts/src/utils.ts | 21 + l2-contracts/test/consensusRegistry.test.ts | 499 ++++++++++++++++++ system-contracts/package.json | 3 +- .../scripts/verify-on-explorer.ts | 2 +- yarn.lock | 6 +- 24 files changed, 1945 insertions(+), 60 deletions(-) create mode 100644 l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol create mode 100644 l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeAdmin.t.sol create mode 100644 l2-contracts/contracts/ConsensusRegistry.sol create mode 100644 l2-contracts/contracts/dev-contracts/Multicall3.sol create mode 100644 l2-contracts/contracts/interfaces/IConsensusRegistry.sol create mode 100644 l2-contracts/src/deploy-consensus-registry.ts create mode 100644 l2-contracts/test/consensusRegistry.test.ts diff --git a/gas-bound-caller/package.json b/gas-bound-caller/package.json index af91e7593..96593e37a 100644 --- a/gas-bound-caller/package.json +++ b/gas-bound-caller/package.json @@ -14,7 +14,8 @@ "ethers": "^5.7.0", "fast-glob": "^3.3.2", "hardhat": "=2.22.2", - "preprocess": "^3.2.0" + "preprocess": "^3.2.0", + "zksync-ethers": "^5.9.0" }, "devDependencies": { "@matterlabs/hardhat-zksync-chai-matchers": "^0.2.0", diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index 56b621c18..eaddcccc7 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -90,6 +90,12 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// NOTE: this function may be removed in the future, don't rely on it! mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) public chainBalance; + /// @dev Admin has the ability to register new chains within the shared bridge. + address public admin; + + /// @dev The pending admin, i.e. the candidate to the admin role. + address public pendingAdmin; + /// @notice Checks that the message sender is the bridgehub. modifier onlyBridgehub() { if (msg.sender != address(BRIDGE_HUB)) { @@ -122,6 +128,12 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _; } + /// @notice Checks that the message sender is either the owner or admin. + modifier onlyOwnerOrAdmin() { + require(msg.sender == owner() || msg.sender == admin, "ShB not owner or admin"); + _; + } + /// @dev Contract is expected to be used as proxy implementation. /// @dev Initialize the implementation to prevent Parity hack. constructor( @@ -147,6 +159,31 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _transferOwnership(_owner); } + /// @inheritdoc IL1SharedBridge + /// @dev Please note, if the owner wants to enforce the admin change it must execute both `setPendingAdmin` and + /// `acceptAdmin` atomically. Otherwise `admin` can set different pending admin and so fail to accept the admin rights. + function setPendingAdmin(address _newPendingAdmin) external onlyOwnerOrAdmin { + // Save previous value into the stack to put it into the event later + address oldPendingAdmin = pendingAdmin; + // Change pending admin + pendingAdmin = _newPendingAdmin; + emit NewPendingAdmin(oldPendingAdmin, _newPendingAdmin); + } + + /// @inheritdoc IL1SharedBridge + /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. + function acceptAdmin() external { + address currentPendingAdmin = pendingAdmin; + require(msg.sender == currentPendingAdmin, "ShB not pending admin"); // Only proposed by current admin address can claim the admin rights + + address previousAdmin = admin; + admin = currentPendingAdmin; + delete pendingAdmin; + + emit NewPendingAdmin(currentPendingAdmin, address(0)); + emit NewAdmin(previousAdmin, currentPendingAdmin); + } + /// @dev This sets the first post diamond upgrade batch for era, used to check old eth withdrawals /// @param _eraPostDiamondUpgradeFirstBatch The first batch number on the ZKsync Era Diamond Proxy that was settled after diamond proxy upgrade. function setEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external onlyOwner { @@ -236,7 +273,21 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @dev Initializes the l2Bridge address by governance for a specific chain. - function initializeChainGovernance(uint256 _chainId, address _l2BridgeAddress) external onlyOwner { + /// @param _chainId The chain ID for which the l2Bridge address is being initialized. + /// @param _l2BridgeAddress The address of the L2 bridge contract. + function initializeChainGovernance(uint256 _chainId, address _l2BridgeAddress) external onlyOwnerOrAdmin { + require(l2BridgeAddress[_chainId] == address(0), "ShB: l2 bridge already set"); + require(_l2BridgeAddress != address(0), "ShB: l2 bridge 0"); + l2BridgeAddress[_chainId] = _l2BridgeAddress; + } + + /// @dev Reinitializes the l2Bridge address by governance for a specific chain. + /// @dev Only accessible to the owner of the bridge to prevent malicious admin from changing the bridge address for + /// an existing chain. + /// @param _chainId The chain ID for which the l2Bridge address is being initialized. + /// @param _l2BridgeAddress The address of the L2 bridge contract. + function reinitializeChainGovernance(uint256 _chainId, address _l2BridgeAddress) external onlyOwner { + require(l2BridgeAddress[_chainId] != address(0), "ShB: l2 bridge not yet set"); l2BridgeAddress[_chainId] = _l2BridgeAddress; } diff --git a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol index 8038d6bdb..cc58d160f 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol @@ -10,6 +10,13 @@ import {IL1ERC20Bridge} from "./IL1ERC20Bridge.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev interface IL1SharedBridge { + /// @notice pendingAdmin is changed + /// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero address + event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin); + + /// @notice Admin changed + event NewAdmin(address indexed oldAdmin, address indexed newAdmin); + event LegacyDepositInitiated( uint256 indexed chainId, bytes32 indexed l2DepositTxHash, @@ -151,4 +158,12 @@ interface IL1SharedBridge { function bridgehubConfirmL2Transaction(uint256 _chainId, bytes32 _txDataHash, bytes32 _txHash) external; function receiveEth(uint256 _chainId) external payable; + + /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one. + /// @notice New admin can accept admin rights by calling `acceptAdmin` function. + /// @param _newPendingAdmin Address of the new admin + function setPendingAdmin(address _newPendingAdmin) external; + + /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. + function acceptAdmin() external; } diff --git a/l1-contracts/contracts/bridgehub/Bridgehub.sol b/l1-contracts/contracts/bridgehub/Bridgehub.sol index 0f1ccbfab..89001c2cd 100644 --- a/l1-contracts/contracts/bridgehub/Bridgehub.sol +++ b/l1-contracts/contracts/bridgehub/Bridgehub.sol @@ -119,7 +119,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus } /// @notice token can be any contract with the appropriate interface/functionality - function addToken(address _token) external onlyOwner { + function addToken(address _token) external onlyOwnerOrAdmin { if (tokenIsRegistered[_token]) { revert TokenAlreadyRegistered(_token); } diff --git a/l1-contracts/deploy-script-config-template/config-deploy-l2-config.toml b/l1-contracts/deploy-script-config-template/config-deploy-l2-config.toml index 67e46ae38..fae9cc907 100644 --- a/l1-contracts/deploy-script-config-template/config-deploy-l2-config.toml +++ b/l1-contracts/deploy-script-config-template/config-deploy-l2-config.toml @@ -4,3 +4,4 @@ l1_shared_bridge = "0x2ae37d8130b82c7e79b3863a39027178e073eedb" bridgehub = "0xea785a9c91a07ed69b83eb165f4ce2c30ecb4c0b" governance = "0x6a08d69675af7755569a1a25ef37e795493473a1" erc20_bridge = "0x84fbda16bd5f2d66d7fbaec5e8d816e7b7014595" +consensus_registry_owner = "0xD64e136566a9E04eb05B30184fF577F52682D182" diff --git a/l1-contracts/deploy-scripts/DeployL1.s.sol b/l1-contracts/deploy-scripts/DeployL1.s.sol index 098aee5bc..416ffd6a3 100644 --- a/l1-contracts/deploy-scripts/DeployL1.s.sol +++ b/l1-contracts/deploy-scripts/DeployL1.s.sol @@ -593,12 +593,15 @@ contract DeployL1Script is Script { Bridgehub bridgehub = Bridgehub(addresses.bridgehub.bridgehubProxy); bridgehub.transferOwnership(addresses.governance); + bridgehub.setPendingAdmin(addresses.chainAdmin); L1SharedBridge sharedBridge = L1SharedBridge(addresses.bridges.sharedBridgeProxy); sharedBridge.transferOwnership(addresses.governance); + sharedBridge.setPendingAdmin(addresses.chainAdmin); StateTransitionManager stm = StateTransitionManager(addresses.stateTransition.stateTransitionProxy); stm.transferOwnership(addresses.governance); + stm.setPendingAdmin(addresses.chainAdmin); vm.stopBroadcast(); console.log("Owners updated"); @@ -709,6 +712,7 @@ contract DeployL1Script is Script { addresses.blobVersionedHashRetriever ); vm.serializeAddress("deployed_addresses", "validator_timelock_addr", addresses.validatorTimelock); + vm.serializeAddress("deployed_addresses", "chain_admin", addresses.chainAdmin); vm.serializeString("deployed_addresses", "bridgehub", bridgehub); vm.serializeString("deployed_addresses", "state_transition", stateTransition); string memory deployedAddresses = vm.serializeString("deployed_addresses", "bridges", bridges); diff --git a/l1-contracts/deploy-scripts/DeployL2Contracts.sol b/l1-contracts/deploy-scripts/DeployL2Contracts.sol index 6e3b5248b..554ed940c 100644 --- a/l1-contracts/deploy-scripts/DeployL2Contracts.sol +++ b/l1-contracts/deploy-scripts/DeployL2Contracts.sol @@ -22,10 +22,16 @@ contract DeployL2Script is Script { address l1SharedBridgeProxy; address governance; address erc20BridgeProxy; + // The owner of the contract sets the validator/attester weights. + // Can be the developer multisig wallet on mainnet. + address consensusRegistryOwner; uint256 chainId; uint256 eraChainId; address l2SharedBridgeImplementation; address l2SharedBridgeProxy; + address consensusRegistryImplementation; + address consensusRegistryProxy; + address multicall3; address forceDeployUpgraderAddress; } @@ -35,29 +41,51 @@ contract DeployL2Script is Script { bytes l2StandardErc20Bytecode; bytes l2SharedBridgeBytecode; bytes l2SharedBridgeProxyBytecode; + bytes consensusRegistryBytecode; + bytes consensusRegistryProxyBytecode; + bytes multicall3Bytecode; bytes forceDeployUpgrader; } function run() public { + deploy(false); + } + + function runWithLegacyBridge() public { + deploy(true); + } + + function deploy(bool legacyBridge) public { initializeConfig(); - loadContracts(); + loadContracts(legacyBridge); deployFactoryDeps(); deploySharedBridge(); - deploySharedBridgeProxy(); + deploySharedBridgeProxy(legacyBridge); initializeChain(); deployForceDeployer(); + deployConsensusRegistry(); + deployConsensusRegistryProxy(); + deployMulticall3(); saveOutput(); } + function runDeployLegacySharedBridge() public { + deploySharedBridge(true); + } + function runDeploySharedBridge() public { + deploySharedBridge(false); + } + + function deploySharedBridge(bool legacyBridge) internal { initializeConfig(); - loadContracts(); + loadContracts(legacyBridge); deployFactoryDeps(); deploySharedBridge(); - deploySharedBridgeProxy(); + deploySharedBridgeProxy(legacyBridge); initializeChain(); saveOutput(); @@ -65,14 +93,24 @@ contract DeployL2Script is Script { function runDefaultUpgrader() public { initializeConfig(); - loadContracts(); + loadContracts(false); deployForceDeployer(); saveOutput(); } - function loadContracts() internal { + function runDeployConsensusRegistry() public { + initializeConfig(); + loadContracts(false); + + deployConsensusRegistry(); + deployConsensusRegistryProxy(); + + saveOutput(); + } + + function loadContracts(bool legacyBridge) internal { //HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode( "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" @@ -84,15 +122,33 @@ contract DeployL2Script is Script { "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" ); - contracts.l2SharedBridgeBytecode = Utils.readFoundryBytecode( - "/../l2-contracts/zkout/L2SharedBridge.sol/L2SharedBridge.json" - ); + if (legacyBridge) { + contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/dev-contracts/DevL2SharedBridge.sol/DevL2SharedBridge.json" + ); + } else { + contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json" + ); + } contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode( "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" ); - contracts.forceDeployUpgrader = Utils.readFoundryBytecode( - "/../l2-contracts/zkout/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" + + contracts.consensusRegistryBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/ConsensusRegistry.sol/ConsensusRegistry.json" + ); + contracts.consensusRegistryProxyBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" + ); + + contracts.multicall3Bytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/dev-contracts/Multicall3.sol/Multicall3.json" + ); + + contracts.forceDeployUpgrader = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" ); } @@ -104,6 +160,7 @@ contract DeployL2Script is Script { config.governance = toml.readAddress("$.governance"); config.l1SharedBridgeProxy = toml.readAddress("$.l1_shared_bridge"); config.erc20BridgeProxy = toml.readAddress("$.erc20_bridge"); + config.consensusRegistryOwner = toml.readAddress("$.consensus_registry_owner"); config.chainId = toml.readUint("$.chain_id"); config.eraChainId = toml.readUint("$.era_chain_id"); } @@ -111,6 +168,9 @@ contract DeployL2Script is Script { function saveOutput() internal { vm.serializeAddress("root", "l2_shared_bridge_implementation", config.l2SharedBridgeImplementation); vm.serializeAddress("root", "l2_shared_bridge_proxy", config.l2SharedBridgeProxy); + vm.serializeAddress("root", "consensus_registry_implementation", config.consensusRegistryImplementation); + vm.serializeAddress("root", "consensus_registry_proxy", config.consensusRegistryProxy); + vm.serializeAddress("root", "multicall3", config.multicall3); string memory toml = vm.serializeAddress("root", "l2_default_upgrader", config.forceDeployUpgraderAddress); string memory root = vm.projectRoot(); string memory path = string.concat(root, "/script-out/output-deploy-l2-contracts.toml"); @@ -157,13 +217,20 @@ contract DeployL2Script is Script { }); } - function deploySharedBridgeProxy() internal { + function deploySharedBridgeProxy(bool legacyBridge) internal { address l2GovernorAddress = AddressAliasHelper.applyL1ToL2Alias(config.governance); bytes32 l2StandardErc20BytecodeHash = L2ContractHelper.hashL2Bytecode(contracts.beaconProxy); + string memory functionSignature; + + if (legacyBridge) { + functionSignature = "initializeDevBridge(address,address,bytes32,address)"; + } else { + functionSignature = "initialize(address,address,bytes32,address)"; + } // solhint-disable-next-line func-named-parameters bytes memory proxyInitializationParams = abi.encodeWithSignature( - "initialize(address,address,bytes32,address)", + functionSignature, config.l1SharedBridgeProxy, config.erc20BridgeProxy, l2StandardErc20BytecodeHash, @@ -188,16 +255,78 @@ contract DeployL2Script is Script { }); } + // Deploy the ConsensusRegistry implementation and save its address into the config. + function deployConsensusRegistry() internal { + // ConsensusRegistry.sol doesn't have a constructor, just an initializer. + bytes memory constructorData = ""; + + config.consensusRegistryImplementation = Utils.deployThroughL1({ + bytecode: contracts.consensusRegistryBytecode, + constructorargs: constructorData, + create2salt: "", + l2GasLimit: Utils.MAX_PRIORITY_TX_GAS, + factoryDeps: new bytes[](0), + chainId: config.chainId, + bridgehubAddress: config.bridgehubAddress, + l1SharedBridgeProxy: config.l1SharedBridgeProxy + }); + } + + function deployMulticall3() internal { + // Multicall3 doesn't have a constructor. + bytes memory constructorData = ""; + + config.multicall3 = Utils.deployThroughL1({ + bytecode: contracts.multicall3Bytecode, + constructorargs: constructorData, + create2salt: "", + l2GasLimit: Utils.MAX_PRIORITY_TX_GAS, + factoryDeps: new bytes[](0), + chainId: config.chainId, + bridgehubAddress: config.bridgehubAddress, + l1SharedBridgeProxy: config.l1SharedBridgeProxy + }); + } + + // Deploy a transparent upgradable proxy for the already deployed consensus registry + // implementation and save its address into the config. + function deployConsensusRegistryProxy() internal { + // Admin for the proxy + address l2GovernorAddress = AddressAliasHelper.applyL1ToL2Alias(config.governance); + + // Call ConsensusRegistry::initialize with the initial owner. + // solhint-disable-next-line func-named-parameters + bytes memory proxyInitializationParams = abi.encodeWithSignature( + "initialize(address)", + config.consensusRegistryOwner + ); + + bytes memory consensusRegistryProxyConstructorData = abi.encode( + config.consensusRegistryImplementation, // _logic + l2GovernorAddress, // admin_ + proxyInitializationParams // _data + ); + + config.consensusRegistryProxy = Utils.deployThroughL1({ + bytecode: contracts.consensusRegistryProxyBytecode, + constructorargs: consensusRegistryProxyConstructorData, + create2salt: "", + l2GasLimit: Utils.MAX_PRIORITY_TX_GAS, + factoryDeps: new bytes[](0), + chainId: config.chainId, + bridgehubAddress: config.bridgehubAddress, + l1SharedBridgeProxy: config.l1SharedBridgeProxy + }); + } + function initializeChain() internal { L1SharedBridge bridge = L1SharedBridge(config.l1SharedBridgeProxy); - Utils.executeUpgrade({ - _governor: bridge.owner(), - _salt: bytes32(0), + Utils.chainAdminMulticall({ + _chainAdmin: bridge.admin(), _target: config.l1SharedBridgeProxy, _data: abi.encodeCall(bridge.initializeChainGovernance, (config.chainId, config.l2SharedBridgeProxy)), - _value: 0, - _delay: 0 + _value: 0 }); } } diff --git a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol index e0039b969..bbc01226d 100644 --- a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol +++ b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol @@ -7,8 +7,7 @@ import {Script, console2 as console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; import {stdToml} from "forge-std/StdToml.sol"; -import {Ownable} from "@openzeppelin/contracts-v4/access/Ownable.sol"; -import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; +import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; import {Governance} from "contracts/governance/Governance.sol"; @@ -119,20 +118,17 @@ contract RegisterHyperchainScript is Script { } function registerTokenOnBridgehub() internal { - IBridgehub bridgehub = IBridgehub(config.bridgehub); - Ownable ownable = Ownable(config.bridgehub); + Bridgehub bridgehub = Bridgehub(config.bridgehub); if (bridgehub.tokenIsRegistered(config.baseToken)) { console.log("Token already registered on Bridgehub"); } else { bytes memory data = abi.encodeCall(bridgehub.addToken, (config.baseToken)); - Utils.executeUpgrade({ - _governor: ownable.owner(), - _salt: bytes32(config.bridgehubCreateNewChainSalt), + Utils.chainAdminMulticall({ + _chainAdmin: bridgehub.admin(), _target: config.bridgehub, _data: data, - _value: 0, - _delay: 0 + _value: 0 }); console.log("Token registered on Bridgehub"); } @@ -157,8 +153,7 @@ contract RegisterHyperchainScript is Script { } function registerHyperchain() internal { - IBridgehub bridgehub = IBridgehub(config.bridgehub); - Ownable ownable = Ownable(config.bridgehub); + Bridgehub bridgehub = Bridgehub(config.bridgehub); vm.recordLogs(); bytes memory data = abi.encodeCall( @@ -173,14 +168,7 @@ contract RegisterHyperchainScript is Script { ) ); - Utils.executeUpgrade({ - _governor: ownable.owner(), - _salt: bytes32(config.bridgehubCreateNewChainSalt), - _target: config.bridgehub, - _data: data, - _value: 0, - _delay: 0 - }); + Utils.chainAdminMulticall({_chainAdmin: bridgehub.admin(), _target: config.bridgehub, _data: data, _value: 0}); console.log("Hyperchain registered"); // Get new diamond proxy address from emitted events diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 17449da7e..fa2bb194c 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -12,6 +12,7 @@ import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; import {L2_DEPLOYER_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol"; import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; +import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; library Utils { // Cheatcodes address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. @@ -306,6 +307,15 @@ library Utils { return bytecode; } + function chainAdminMulticall(address _chainAdmin, address _target, bytes memory _data, uint256 _value) internal { + IChainAdmin chainAdmin = IChainAdmin(_chainAdmin); + + IChainAdmin.Call[] memory calls = new IChainAdmin.Call[](1); + calls[0] = IChainAdmin.Call({target: _target, value: _value, data: _data}); + vm.broadcast(); + chainAdmin.multicall(calls, true); + } + function executeUpgrade( address _governor, bytes32 _salt, diff --git a/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol b/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol new file mode 100644 index 000000000..e178824b1 --- /dev/null +++ b/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {Script} from "forge-std/Script.sol"; +import {stdToml} from "forge-std/StdToml.sol"; +import {Utils} from "./../Utils.sol"; +import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; +import {DummyL1ERC20Bridge} from "contracts/dev-contracts/DummyL1ERC20Bridge.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; + +/// This scripts is only for developer +contract SetupLegacyBridge is Script { + using stdToml for string; + + Config internal config; + Addresses internal addresses; + + struct Config { + uint256 chainId; + address l2SharedBridgeAddress; + bytes32 create2FactorySalt; + } + + struct Addresses { + address create2FactoryAddr; + address bridgehub; + address diamondProxy; + address sharedBridgeProxy; + address transparentProxyAdmin; + address erc20BridgeProxy; + address tokenWethAddress; + address erc20BridgeProxyImpl; + address sharedBridgeProxyImpl; + } + + function run() public { + initializeConfig(); + deploySharedBridgeImplementation(); + upgradeImplementation(addresses.sharedBridgeProxy, addresses.sharedBridgeProxyImpl); + deployDummyErc20Bridge(); + upgradeImplementation(addresses.erc20BridgeProxy, addresses.erc20BridgeProxyImpl); + setParamsForDummyBridge(); + } + + function initializeConfig() internal { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-config/setup-legacy-bridge.toml"); + string memory toml = vm.readFile(path); + + addresses.bridgehub = toml.readAddress("$.bridgehub"); + addresses.diamondProxy = toml.readAddress("$.diamond_proxy"); + addresses.sharedBridgeProxy = toml.readAddress("$.shared_bridge_proxy"); + addresses.transparentProxyAdmin = toml.readAddress("$.transparent_proxy_admin"); + addresses.erc20BridgeProxy = toml.readAddress("$.erc20bridge_proxy"); + addresses.tokenWethAddress = toml.readAddress("$.token_weth_address"); + addresses.create2FactoryAddr = toml.readAddress("$.create2factory_addr"); + config.chainId = toml.readUint("$.chain_id"); + config.l2SharedBridgeAddress = toml.readAddress("$.l2shared_bridge_address"); + config.create2FactorySalt = toml.readBytes32("$.create2factory_salt"); + } + + // We need to deploy new shared bridge for changing chain id and diamond proxy address + function deploySharedBridgeImplementation() internal { + bytes memory bytecode = abi.encodePacked( + type(L1SharedBridge).creationCode, + // solhint-disable-next-line func-named-parameters + abi.encode(addresses.tokenWethAddress, addresses.bridgehub, config.chainId, addresses.diamondProxy) + ); + + address contractAddress = deployViaCreate2(bytecode); + addresses.sharedBridgeProxyImpl = contractAddress; + } + + function deployDummyErc20Bridge() internal { + bytes memory bytecode = abi.encodePacked( + type(DummyL1ERC20Bridge).creationCode, + // solhint-disable-next-line func-named-parameters + abi.encode(addresses.sharedBridgeProxy) + ); + address contractAddress = deployViaCreate2(bytecode); + addresses.erc20BridgeProxyImpl = contractAddress; + } + + function upgradeImplementation(address proxy, address implementation) internal { + bytes memory proxyAdminUpgradeData = abi.encodeCall( + ProxyAdmin.upgrade, + (ITransparentUpgradeableProxy(proxy), implementation) + ); + ProxyAdmin _proxyAdmin = ProxyAdmin(addresses.transparentProxyAdmin); + address governance = _proxyAdmin.owner(); + + Utils.executeUpgrade({ + _governor: address(governance), + _salt: bytes32(0), + _target: address(addresses.transparentProxyAdmin), + _data: proxyAdminUpgradeData, + _value: 0, + _delay: 0 + }); + } + + function setParamsForDummyBridge() internal { + (address l2TokenBeacon, bytes32 l2TokenBeaconHash) = calculateTokenBeaconAddress(); + DummyL1ERC20Bridge bridge = DummyL1ERC20Bridge(addresses.erc20BridgeProxy); + vm.broadcast(); + bridge.setValues(config.l2SharedBridgeAddress, l2TokenBeacon, l2TokenBeaconHash); + } + + function calculateTokenBeaconAddress() + internal + returns (address tokenBeaconAddress, bytes32 tokenBeaconBytecodeHash) + { + bytes memory l2StandardTokenCode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" + ); + (address l2StandardToken, ) = calculateL2Create2Address( + config.l2SharedBridgeAddress, + l2StandardTokenCode, + bytes32(0), + "" + ); + + bytes memory beaconProxy = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json" + ); + tokenBeaconBytecodeHash = L2ContractHelper.hashL2Bytecode(beaconProxy); + + bytes memory upgradableBeacon = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" + ); + + (tokenBeaconAddress, ) = calculateL2Create2Address( + config.l2SharedBridgeAddress, + upgradableBeacon, + bytes32(0), + abi.encode(l2StandardToken) + ); + } + + function calculateL2Create2Address( + address sender, + bytes memory bytecode, + bytes32 create2salt, + bytes memory constructorargs + ) internal returns (address create2Address, bytes32 bytecodeHash) { + bytecodeHash = L2ContractHelper.hashL2Bytecode(bytecode); + + create2Address = L2ContractHelper.computeCreate2Address( + sender, + create2salt, + bytecodeHash, + keccak256(constructorargs) + ); + } + + function deployViaCreate2(bytes memory _bytecode) internal returns (address) { + return Utils.deployViaCreate2(_bytecode, config.create2FactorySalt, addresses.create2FactoryAddr); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol index b454a5299..43826e6ac 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol @@ -339,16 +339,13 @@ contract ExperimentalBridgeTest is Test { bridgeHub.addToken(randomAddress); } - function test_addToken_cannotBeCalledByRandomAddress( - address randomAddress, - address randomCaller, - uint256 randomValue - ) public useRandomToken(randomValue) { - if (randomCaller != bridgeOwner) { - vm.prank(randomCaller); - vm.expectRevert(bytes("Ownable: caller is not the owner")); - bridgeHub.addToken(randomAddress); - } + function test_addToken_cannotBeCalledByRandomAddress(address randomAddress, address randomCaller) public { + vm.assume(randomCaller != bridgeOwner); + vm.assume(randomCaller != bridgeHub.admin()); + + vm.prank(randomCaller); + vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, randomCaller)); + bridgeHub.addToken(randomAddress); assertTrue(!bridgeHub.tokenIsRegistered(randomAddress), "This random address is not registered as a token"); diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeAdmin.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeAdmin.t.sol new file mode 100644 index 000000000..af97e3ed2 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeAdmin.t.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {L1SharedBridgeTest} from "./_L1SharedBridge_Shared.t.sol"; + +/// We are testing all the specified revert and require cases. +contract L1SharedBridgeAdminTest is L1SharedBridgeTest { + uint256 internal randomChainId = 123456; + + function testAdminCanInitializeChainGovernance() public { + address randomL2Bridge = makeAddr("randomL2Bridge"); + + vm.prank(admin); + sharedBridge.initializeChainGovernance(randomChainId, randomL2Bridge); + + assertEq(sharedBridge.l2BridgeAddress(randomChainId), randomL2Bridge); + } + + function testAdminCanNotReinitializeChainGovernance() public { + address randomNewBridge = makeAddr("randomNewBridge"); + + vm.expectRevert("Ownable: caller is not the owner"); + vm.prank(admin); + sharedBridge.reinitializeChainGovernance(randomChainId, randomNewBridge); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol index 3c9272b46..63eb02aca 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol @@ -22,7 +22,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { vm.expectRevert(ZeroAddress.selector); new TransparentUpgradeableProxy( address(sharedBridgeImpl), - admin, + proxyAdmin, // solhint-disable-next-line func-named-parameters abi.encodeWithSelector(L1SharedBridge.initialize.selector, address(0), eraPostUpgradeFirstBatch) ); @@ -59,7 +59,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { function test_bridgehubDeposit_Eth_l2BridgeNotDeployed() public { vm.prank(owner); - sharedBridge.initializeChainGovernance(chainId, address(0)); + sharedBridge.reinitializeChainGovernance(chainId, address(0)); vm.deal(bridgehubAddress, amount); vm.prank(bridgehubAddress); vm.mockCall( @@ -544,7 +544,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { address refundRecipient = address(0); vm.prank(owner); - sharedBridge.initializeChainGovernance(eraChainId, address(0)); + sharedBridge.reinitializeChainGovernance(eraChainId, address(0)); vm.expectRevert(abi.encodeWithSelector(L2BridgeNotSet.selector, eraChainId)); vm.prank(l1ERC20BridgeAddress); diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol index 0b917efca..1b785ae84 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol @@ -69,6 +69,7 @@ contract L1SharedBridgeTest is Test { address owner; address admin; + address proxyAdmin; address zkSync; address alice; address bob; @@ -90,6 +91,7 @@ contract L1SharedBridgeTest is Test { function setUp() public { owner = makeAddr("owner"); admin = makeAddr("admin"); + proxyAdmin = makeAddr("proxyAdmin"); // zkSync = makeAddr("zkSync"); bridgehubAddress = makeAddr("bridgehub"); alice = makeAddr("alice"); @@ -119,7 +121,7 @@ contract L1SharedBridgeTest is Test { }); TransparentUpgradeableProxy sharedBridgeProxy = new TransparentUpgradeableProxy( address(sharedBridgeImpl), - admin, + proxyAdmin, abi.encodeWithSelector(L1SharedBridge.initialize.selector, owner) ); sharedBridge = L1SharedBridge(payable(sharedBridgeProxy)); @@ -135,6 +137,10 @@ contract L1SharedBridgeTest is Test { sharedBridge.initializeChainGovernance(chainId, l2SharedBridge); vm.prank(owner); sharedBridge.initializeChainGovernance(eraChainId, l2SharedBridge); + vm.prank(owner); + sharedBridge.setPendingAdmin(admin); + vm.prank(admin); + sharedBridge.acceptAdmin(); } function _setSharedBridgeDepositHappened(uint256 _chainId, bytes32 _txHash, bytes32 _txDataHash) internal { diff --git a/l2-contracts/contracts/ConsensusRegistry.sol b/l2-contracts/contracts/ConsensusRegistry.sol new file mode 100644 index 000000000..de5af6340 --- /dev/null +++ b/l2-contracts/contracts/ConsensusRegistry.sol @@ -0,0 +1,486 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable-v4/access/Ownable2StepUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable-v4/proxy/utils/Initializable.sol"; +import {IConsensusRegistry} from "./interfaces/IConsensusRegistry.sol"; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +/// @title ConsensusRegistry +/// @dev Manages consensus nodes and committees for the L2 consensus protocol, +/// owned by Matter Labs Multisig. Nodes act as both validators and attesters, +/// each playing a distinct role in the consensus process. This contract facilitates +/// the rotation of validator and attester committees, which represent a subset of nodes +/// expected to actively participate in the consensus process during a specific time window. +/// @dev Designed for use with a proxy for upgradability. +contract ConsensusRegistry is IConsensusRegistry, Initializable, Ownable2StepUpgradeable { + /// @dev An array to keep track of node owners. + address[] public nodeOwners; + /// @dev A mapping of node owners => nodes. + mapping(address => Node) public nodes; + /// @dev A mapping for enabling efficient lookups when checking whether a given attester public key exists. + mapping(bytes32 => bool) public attesterPubKeyHashes; + /// @dev A mapping for enabling efficient lookups when checking whether a given validator public key exists. + mapping(bytes32 => bool) public validatorPubKeyHashes; + /// @dev Counter that increments with each new commit to the attester committee. + uint32 public attestersCommit; + /// @dev Counter that increments with each new commit to the validator committee. + uint32 public validatorsCommit; + + modifier onlyOwnerOrNodeOwner(address _nodeOwner) { + if (owner() != msg.sender && _nodeOwner != msg.sender) { + revert UnauthorizedOnlyOwnerOrNodeOwner(); + } + _; + } + + function initialize(address _initialOwner) external initializer { + if (_initialOwner == address(0)) { + revert InvalidInputNodeOwnerAddress(); + } + _transferOwnership(_initialOwner); + } + + /// @notice Adds a new node to the registry. + /// @dev Fails if node owner already exists. + /// @dev Fails if a validator/attester with the same public key already exists. + /// @param _nodeOwner The address of the new node's owner. + /// @param _validatorWeight The voting weight of the validator. + /// @param _validatorPubKey The BLS12-381 public key of the validator. + /// @param _validatorPoP The proof-of-possession (PoP) of the validator's public key. + /// @param _attesterWeight The voting weight of the attester. + /// @param _attesterPubKey The ECDSA public key of the attester. + function add( + address _nodeOwner, + uint32 _validatorWeight, + BLS12_381PublicKey calldata _validatorPubKey, + BLS12_381Signature calldata _validatorPoP, + uint32 _attesterWeight, + Secp256k1PublicKey calldata _attesterPubKey + ) external onlyOwner { + // Verify input. + _verifyInputAddress(_nodeOwner); + _verifyInputBLS12_381PublicKey(_validatorPubKey); + _verifyInputBLS12_381Signature(_validatorPoP); + _verifyInputSecp256k1PublicKey(_attesterPubKey); + + // Verify storage. + _verifyNodeOwnerDoesNotExist(_nodeOwner); + bytes32 attesterPubKeyHash = _hashAttesterPubKey(_attesterPubKey); + _verifyAttesterPubKeyDoesNotExist(attesterPubKeyHash); + bytes32 validatorPubKeyHash = _hashValidatorPubKey(_validatorPubKey); + _verifyValidatorPubKeyDoesNotExist(validatorPubKeyHash); + + uint32 nodeOwnerIdx = uint32(nodeOwners.length); + nodeOwners.push(_nodeOwner); + nodes[_nodeOwner] = Node({ + attesterLatest: AttesterAttr({ + active: true, + removed: false, + weight: _attesterWeight, + pubKey: _attesterPubKey + }), + attesterSnapshot: AttesterAttr({ + active: false, + removed: false, + weight: 0, + pubKey: Secp256k1PublicKey({tag: bytes1(0), x: bytes32(0)}) + }), + attesterLastUpdateCommit: attestersCommit, + validatorLatest: ValidatorAttr({ + active: true, + removed: false, + weight: _validatorWeight, + pubKey: _validatorPubKey, + proofOfPossession: _validatorPoP + }), + validatorSnapshot: ValidatorAttr({ + active: false, + removed: false, + weight: 0, + pubKey: BLS12_381PublicKey({a: bytes32(0), b: bytes32(0), c: bytes32(0)}), + proofOfPossession: BLS12_381Signature({a: bytes32(0), b: bytes16(0)}) + }), + validatorLastUpdateCommit: validatorsCommit, + nodeOwnerIdx: nodeOwnerIdx + }); + attesterPubKeyHashes[attesterPubKeyHash] = true; + validatorPubKeyHashes[validatorPubKeyHash] = true; + + emit NodeAdded({ + nodeOwner: _nodeOwner, + validatorWeight: _validatorWeight, + validatorPubKey: _validatorPubKey, + validatorPoP: _validatorPoP, + attesterWeight: _attesterWeight, + attesterPubKey: _attesterPubKey + }); + } + + /// @notice Deactivates a node, preventing it from participating in committees. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner to be inactivated. + function deactivate(address _nodeOwner) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.active = false; + _ensureValidatorSnapshot(node); + node.validatorLatest.active = false; + + emit NodeDeactivated(_nodeOwner); + } + + /// @notice Activates a previously inactive node, allowing it to participate in committees. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner to be activated. + function activate(address _nodeOwner) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.active = true; + _ensureValidatorSnapshot(node); + node.validatorLatest.active = true; + + emit NodeActivated(_nodeOwner); + } + + /// @notice Removes a node from the registry. + /// @dev Only callable by the contract owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner to be removed. + function remove(address _nodeOwner) external onlyOwner { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.removed = true; + _ensureValidatorSnapshot(node); + node.validatorLatest.removed = true; + + emit NodeRemoved(_nodeOwner); + } + + /// @notice Changes the validator weight of a node in the registry. + /// @dev Only callable by the contract owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose validator weight will be changed. + /// @param _weight The new validator weight to assign to the node. + function changeValidatorWeight(address _nodeOwner, uint32 _weight) external onlyOwner { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureValidatorSnapshot(node); + node.validatorLatest.weight = _weight; + + emit NodeValidatorWeightChanged(_nodeOwner, _weight); + } + + /// @notice Changes the attester weight of a node in the registry. + /// @dev Only callable by the contract owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose attester weight will be changed. + /// @param _weight The new attester weight to assign to the node. + function changeAttesterWeight(address _nodeOwner, uint32 _weight) external onlyOwner { + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + _ensureAttesterSnapshot(node); + node.attesterLatest.weight = _weight; + + emit NodeAttesterWeightChanged(_nodeOwner, _weight); + } + + /// @notice Changes the validator's public key and proof-of-possession in the registry. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose validator key and PoP will be changed. + /// @param _pubKey The new BLS12-381 public key to assign to the node's validator. + /// @param _pop The new proof-of-possession (PoP) to assign to the node's validator. + function changeValidatorKey( + address _nodeOwner, + BLS12_381PublicKey calldata _pubKey, + BLS12_381Signature calldata _pop + ) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyInputBLS12_381PublicKey(_pubKey); + _verifyInputBLS12_381Signature(_pop); + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + bytes32 prevHash = _hashValidatorPubKey(node.validatorLatest.pubKey); + delete validatorPubKeyHashes[prevHash]; + bytes32 newHash = _hashValidatorPubKey(_pubKey); + _verifyValidatorPubKeyDoesNotExist(newHash); + validatorPubKeyHashes[newHash] = true; + _ensureValidatorSnapshot(node); + node.validatorLatest.pubKey = _pubKey; + node.validatorLatest.proofOfPossession = _pop; + + emit NodeValidatorKeyChanged(_nodeOwner, _pubKey, _pop); + } + + /// @notice Changes the attester's public key of a node in the registry. + /// @dev Only callable by the contract owner or the node owner. + /// @dev Verifies that the node owner exists in the registry. + /// @param _nodeOwner The address of the node's owner whose attester public key will be changed. + /// @param _pubKey The new ECDSA public key to assign to the node's attester. + function changeAttesterKey( + address _nodeOwner, + Secp256k1PublicKey calldata _pubKey + ) external onlyOwnerOrNodeOwner(_nodeOwner) { + _verifyInputSecp256k1PublicKey(_pubKey); + _verifyNodeOwnerExists(_nodeOwner); + (Node storage node, bool deleted) = _getNodeAndDeleteIfRequired(_nodeOwner); + if (deleted) { + return; + } + + bytes32 prevHash = _hashAttesterPubKey(node.attesterLatest.pubKey); + delete attesterPubKeyHashes[prevHash]; + bytes32 newHash = _hashAttesterPubKey(_pubKey); + _verifyAttesterPubKeyDoesNotExist(newHash); + attesterPubKeyHashes[newHash] = true; + + _ensureAttesterSnapshot(node); + node.attesterLatest.pubKey = _pubKey; + + emit NodeAttesterKeyChanged(_nodeOwner, _pubKey); + } + + /// @notice Adds a new commit to the attester committee. + /// @dev Implicitly updates the attester committee by affecting readers based on the current state of a node's attester attributes: + /// - If "attestersCommit" > "node.attesterLastUpdateCommit", read "node.attesterLatest". + /// - If "attestersCommit" == "node.attesterLastUpdateCommit", read "node.attesterSnapshot". + /// @dev Only callable by the contract owner. + function commitAttesterCommittee() external onlyOwner { + ++attestersCommit; + + emit AttestersCommitted(attestersCommit); + } + + /// @notice Adds a new commit to the validator committee. + /// @dev Implicitly updates the validator committee by affecting readers based on the current state of a node's validator attributes: + /// - If "validatorsCommit" > "node.validatorLastUpdateCommit", read "node.validatorLatest". + /// - If "validatorsCommit" == "node.validatorLastUpdateCommit", read "node.validatorSnapshot". + /// @dev Only callable by the contract owner. + function commitValidatorCommittee() external onlyOwner { + ++validatorsCommit; + + emit ValidatorsCommitted(validatorsCommit); + } + + /// @notice Returns an array of `AttesterAttr` structs representing the current attester committee. + /// @dev Collects active and non-removed attesters based on the latest commit to the committee. + function getAttesterCommittee() public view returns (CommitteeAttester[] memory) { + uint256 len = nodeOwners.length; + CommitteeAttester[] memory committee = new CommitteeAttester[](len); + uint256 count = 0; + + for (uint256 i = 0; i < len; ++i) { + Node storage node = nodes[nodeOwners[i]]; + AttesterAttr memory attester = attestersCommit > node.attesterLastUpdateCommit + ? node.attesterLatest + : node.attesterSnapshot; + if (attester.active && !attester.removed) { + committee[count] = CommitteeAttester({weight: attester.weight, pubKey: attester.pubKey}); + ++count; + } + } + + // Resize the array. + assembly { + mstore(committee, count) + } + return committee; + } + + /// @notice Returns an array of `ValidatorAttr` structs representing the current attester committee. + /// @dev Collects active and non-removed validators based on the latest commit to the committee. + function getValidatorCommittee() public view returns (CommitteeValidator[] memory) { + uint256 len = nodeOwners.length; + CommitteeValidator[] memory committee = new CommitteeValidator[](len); + uint256 count = 0; + + for (uint256 i = 0; i < len; ++i) { + Node storage node = nodes[nodeOwners[i]]; + ValidatorAttr memory validator = validatorsCommit > node.validatorLastUpdateCommit + ? node.validatorLatest + : node.validatorSnapshot; + if (validator.active && !validator.removed) { + committee[count] = CommitteeValidator({ + weight: validator.weight, + pubKey: validator.pubKey, + proofOfPossession: validator.proofOfPossession + }); + ++count; + } + } + + // Resize the array. + assembly { + mstore(committee, count) + } + return committee; + } + + function numNodes() public view returns (uint256) { + return nodeOwners.length; + } + + function _getNodeAndDeleteIfRequired(address _nodeOwner) private returns (Node storage, bool) { + Node storage node = nodes[_nodeOwner]; + bool pendingDeletion = _isNodePendingDeletion(node); + if (pendingDeletion) { + _deleteNode(_nodeOwner, node); + } + return (node, pendingDeletion); + } + + function _isNodePendingDeletion(Node storage _node) private returns (bool) { + bool attesterRemoved = (attestersCommit > _node.attesterLastUpdateCommit) + ? _node.attesterLatest.removed + : _node.attesterSnapshot.removed; + bool validatorRemoved = (validatorsCommit > _node.validatorLastUpdateCommit) + ? _node.validatorLatest.removed + : _node.validatorSnapshot.removed; + return attesterRemoved && validatorRemoved; + } + + function _deleteNode(address _nodeOwner, Node storage _node) private { + // Delete from array by swapping the last node owner (gas-efficient, not preserving order). + address lastNodeOwner = nodeOwners[nodeOwners.length - 1]; + nodeOwners[_node.nodeOwnerIdx] = lastNodeOwner; + nodeOwners.pop(); + // Update the node owned by the last node owner. + nodes[lastNodeOwner].nodeOwnerIdx = _node.nodeOwnerIdx; + + // Delete from the remaining mapping. + delete attesterPubKeyHashes[_hashAttesterPubKey(_node.attesterLatest.pubKey)]; + delete validatorPubKeyHashes[_hashValidatorPubKey(_node.validatorLatest.pubKey)]; + delete nodes[_nodeOwner]; + + emit NodeDeleted(_nodeOwner); + } + + function _ensureAttesterSnapshot(Node storage _node) private { + if (_node.attesterLastUpdateCommit < attestersCommit) { + _node.attesterSnapshot = _node.attesterLatest; + _node.attesterLastUpdateCommit = attestersCommit; + } + } + + function _ensureValidatorSnapshot(Node storage _node) private { + if (_node.validatorLastUpdateCommit < validatorsCommit) { + _node.validatorSnapshot = _node.validatorLatest; + _node.validatorLastUpdateCommit = validatorsCommit; + } + } + + function _isNodeOwnerExists(address _nodeOwner) private view returns (bool) { + BLS12_381PublicKey storage pubKey = nodes[_nodeOwner].validatorLatest.pubKey; + if (pubKey.a == bytes32(0) && pubKey.b == bytes32(0) && pubKey.c == bytes32(0)) { + return false; + } + return true; + } + + function _verifyNodeOwnerExists(address _nodeOwner) private view { + if (!_isNodeOwnerExists(_nodeOwner)) { + revert NodeOwnerDoesNotExist(); + } + } + + function _verifyNodeOwnerDoesNotExist(address _nodeOwner) private view { + if (_isNodeOwnerExists(_nodeOwner)) { + revert NodeOwnerExists(); + } + } + + function _hashAttesterPubKey(Secp256k1PublicKey storage _pubKey) private view returns (bytes32) { + return keccak256(abi.encode(_pubKey.tag, _pubKey.x)); + } + + function _hashAttesterPubKey(Secp256k1PublicKey calldata _pubKey) private pure returns (bytes32) { + return keccak256(abi.encode(_pubKey.tag, _pubKey.x)); + } + + function _hashValidatorPubKey(BLS12_381PublicKey storage _pubKey) private view returns (bytes32) { + return keccak256(abi.encode(_pubKey.a, _pubKey.b, _pubKey.c)); + } + + function _hashValidatorPubKey(BLS12_381PublicKey calldata _pubKey) private pure returns (bytes32) { + return keccak256(abi.encode(_pubKey.a, _pubKey.b, _pubKey.c)); + } + + function _verifyInputAddress(address _nodeOwner) private pure { + if (_nodeOwner == address(0)) { + revert InvalidInputNodeOwnerAddress(); + } + } + + function _verifyAttesterPubKeyDoesNotExist(bytes32 _hash) private view { + if (attesterPubKeyHashes[_hash]) { + revert AttesterPubKeyExists(); + } + } + + function _verifyValidatorPubKeyDoesNotExist(bytes32 _hash) private { + if (validatorPubKeyHashes[_hash]) { + revert ValidatorPubKeyExists(); + } + } + + function _verifyInputBLS12_381PublicKey(BLS12_381PublicKey calldata _pubKey) private pure { + if (_isEmptyBLS12_381PublicKey(_pubKey)) { + revert InvalidInputBLS12_381PublicKey(); + } + } + + function _verifyInputBLS12_381Signature(BLS12_381Signature calldata _pop) private pure { + if (_isEmptyBLS12_381Signature(_pop)) { + revert InvalidInputBLS12_381Signature(); + } + } + + function _verifyInputSecp256k1PublicKey(Secp256k1PublicKey calldata _pubKey) private pure { + if (_isEmptySecp256k1PublicKey(_pubKey)) { + revert InvalidInputSecp256k1PublicKey(); + } + } + + function _isEmptyBLS12_381PublicKey(BLS12_381PublicKey calldata _pubKey) private pure returns (bool) { + return _pubKey.a == bytes32(0) && _pubKey.b == bytes32(0) && _pubKey.c == bytes32(0); + } + + function _isEmptyBLS12_381Signature(BLS12_381Signature calldata _pop) private pure returns (bool) { + return _pop.a == bytes32(0) && _pop.b == bytes16(0); + } + + function _isEmptySecp256k1PublicKey(Secp256k1PublicKey calldata _pubKey) private pure returns (bool) { + return _pubKey.tag == bytes1(0) && _pubKey.x == bytes32(0); + } +} diff --git a/l2-contracts/contracts/dev-contracts/Multicall3.sol b/l2-contracts/contracts/dev-contracts/Multicall3.sol new file mode 100644 index 000000000..aaa8b8012 --- /dev/null +++ b/l2-contracts/contracts/dev-contracts/Multicall3.sol @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +/// @title Multicall3 +/// @notice Aggregate results from multiple function calls +/// @dev Multicall & Multicall2 backwards-compatible +/// @dev Aggregate methods are marked `payable` to save 24 gas per call +/// @author Michael Elliot +/// @author Joshua Levine +/// @author Nick Johnson +/// @author Andreas Bigger +/// @author Matt Solomon +contract Multicall3 { + // add this to be excluded from coverage report + function test() internal virtual {} + + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + /// @notice Backwards-compatible call aggregation with Multicall + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return returnData An array of bytes containing the responses + function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData) { + blockNumber = block.number; + uint256 length = calls.length; + returnData = new bytes[](length); + Call calldata call; + for (uint256 i = 0; i < length; ) { + bool success; + call = calls[i]; + (success, returnData[i]) = call.target.call(call.callData); + require(success, "Multicall3: call failed"); + unchecked { + ++i; + } + } + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls without requiring success + /// @param requireSuccess If true, require all calls to succeed + /// @param calls An array of Call structs + /// @return returnData An array of Result structs + function tryAggregate( + bool requireSuccess, + Call[] calldata calls + ) public payable returns (Result[] memory returnData) { + uint256 length = calls.length; + returnData = new Result[](length); + Call calldata call; + for (uint256 i = 0; i < length; ) { + Result memory result = returnData[i]; + call = calls[i]; + (result.success, result.returnData) = call.target.call(call.callData); + if (requireSuccess) require(result.success, "Multicall3: call failed"); + unchecked { + ++i; + } + } + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls and allow failures using tryAggregate + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return blockHash The hash of the block where the calls were executed + /// @return returnData An array of Result structs + function tryBlockAndAggregate( + bool requireSuccess, + Call[] calldata calls + ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { + blockNumber = block.number; + blockHash = blockhash(block.number); + returnData = tryAggregate(requireSuccess, calls); + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls and allow failures using tryAggregate + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return blockHash The hash of the block where the calls were executed + /// @return returnData An array of Result structs + function blockAndAggregate( + Call[] calldata calls + ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { + (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls); + } + + /// @notice Aggregate calls, ensuring each returns success if required + /// @param calls An array of Call3 structs + /// @return returnData An array of Result structs + function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) { + uint256 length = calls.length; + returnData = new Result[](length); + Call3 calldata calli; + for (uint256 i = 0; i < length; ) { + Result memory result = returnData[i]; + calli = calls[i]; + (result.success, result.returnData) = calli.target.call(calli.callData); + assembly { + // Revert if the call fails and failure is not allowed + // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` + if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { + // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) + mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // set data offset + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // set length of revert string + mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) + // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) + mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) + revert(0x00, 0x64) + } + } + unchecked { + ++i; + } + } + } + + /// @notice Aggregate calls with a msg value + /// @notice Reverts if msg.value is less than the sum of the call values + /// @param calls An array of Call3Value structs + /// @return returnData An array of Result structs + function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) { + uint256 valAccumulator; + uint256 length = calls.length; + returnData = new Result[](length); + Call3Value calldata calli; + for (uint256 i = 0; i < length; ) { + Result memory result = returnData[i]; + calli = calls[i]; + uint256 val = calli.value; + // Humanity will be a Type V Kardashev Civilization before this overflows - andreas + // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256 + unchecked { + valAccumulator += val; + } + (result.success, result.returnData) = calli.target.call{value: val}(calli.callData); + assembly { + // Revert if the call fails and failure is not allowed + // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` + if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { + // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) + mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // set data offset + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // set length of revert string + mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) + // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) + mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) + revert(0x00, 0x84) + } + } + unchecked { + ++i; + } + } + // Finally, make sure the msg.value = SUM(call[0...i].value) + require(msg.value == valAccumulator, "Multicall3: value mismatch"); + } + + /// @notice Returns the block hash for the given block number + /// @param blockNumber The block number + function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { + blockHash = blockhash(blockNumber); + } + + /// @notice Returns the block number + function getBlockNumber() public view returns (uint256 blockNumber) { + blockNumber = block.number; + } + + /// @notice Returns the block coinbase + function getCurrentBlockCoinbase() public view returns (address coinbase) { + coinbase = block.coinbase; + } + + /// @notice Returns the block difficulty + function getCurrentBlockDifficulty() public view returns (uint256 difficulty) { + difficulty = block.prevrandao; + } + + /// @notice Returns the block gas limit + function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { + gaslimit = block.gaslimit; + } + + /// @notice Returns the block timestamp + function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { + timestamp = block.timestamp; + } + + /// @notice Returns the (ETH) balance of a given address + function getEthBalance(address addr) public view returns (uint256 balance) { + balance = addr.balance; + } + + /// @notice Returns the block hash of the last block + function getLastBlockHash() public view returns (bytes32 blockHash) { + unchecked { + blockHash = blockhash(block.number - 1); + } + } + + /// @notice Gets the base fee of the given block + /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain + function getBasefee() public view returns (uint256 basefee) { + basefee = block.basefee; + } + + /// @notice Returns the chain id + function getChainId() public view returns (uint256 chainid) { + chainid = block.chainid; + } +} diff --git a/l2-contracts/contracts/interfaces/IConsensusRegistry.sol b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol new file mode 100644 index 000000000..34afc0abe --- /dev/null +++ b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +/// @title ConsensusRegistry contract interface +interface IConsensusRegistry { + /// @dev Represents a consensus node. + /// @param attesterLastUpdateCommit The latest `attestersCommit` where the node's attester attributes were updated. + /// @param attesterLatest Attester attributes to read if `node.attesterLastUpdateCommit` < `attestersCommit`. + /// @param attesterSnapshot Attester attributes to read if `node.attesterLastUpdateCommit` == `attestersCommit`. + /// @param validatorLastUpdateCommit The latest `validatorsCommit` where the node's validator attributes were updated. + /// @param validatorLatest Validator attributes to read if `node.validatorLastUpdateCommit` < `validatorsCommit`. + /// @param validatorSnapshot Validator attributes to read if `node.validatorLastUpdateCommit` == `validatorsCommit`. + /// @param nodeOwnerIdx Index of the node owner within the array of node owners. + struct Node { + uint32 attesterLastUpdateCommit; + uint32 validatorLastUpdateCommit; + uint32 nodeOwnerIdx; + AttesterAttr attesterLatest; + AttesterAttr attesterSnapshot; + ValidatorAttr validatorLatest; + ValidatorAttr validatorSnapshot; + } + + /// @dev Represents the attester attributes of a consensus node. + /// @param active A flag stating if the attester is active. + /// @param removed A flag stating if the attester has been removed (and is pending a deletion). + /// @param weight Attester's voting weight. + /// @param pubKey Attester's Secp256k1 public key. + struct AttesterAttr { + bool active; + bool removed; + uint32 weight; + Secp256k1PublicKey pubKey; + } + + /// @dev Represents an attester within a committee. + /// @param weight Attester's voting weight. + /// @param pubKey Attester's Secp256k1 public key. + struct CommitteeAttester { + uint32 weight; + Secp256k1PublicKey pubKey; + } + + /// @dev Represents the validator attributes of a consensus node. + /// @param active A flag stating if the validator is active. + /// @param removed A flag stating if the validator has been removed (and is pending a deletion). + /// @param weight Validator's voting weight. + /// @param pubKey Validator's BLS12-381 public key. + /// @param proofOfPossession Validator's Proof-of-possession (a signature over the public key). + struct ValidatorAttr { + bool active; + bool removed; + uint32 weight; + BLS12_381PublicKey pubKey; + BLS12_381Signature proofOfPossession; + } + + /// @dev Represents a validator within a committee. + /// @param weight Validator's voting weight. + /// @param pubKey Validator's BLS12-381 public key. + /// @param proofOfPossession Validator's Proof-of-possession (a signature over the public key). + struct CommitteeValidator { + uint32 weight; + BLS12_381PublicKey pubKey; + BLS12_381Signature proofOfPossession; + } + + /// @dev Represents BLS12_381 public key. + /// @param a First component of the BLS12-381 public key. + /// @param b Second component of the BLS12-381 public key. + /// @param c Third component of the BLS12-381 public key. + struct BLS12_381PublicKey { + bytes32 a; + bytes32 b; + bytes32 c; + } + + /// @dev Represents BLS12_381 signature. + /// @param a First component of the BLS12-381 signature. + /// @param b Second component of the BLS12-381 signature. + struct BLS12_381Signature { + bytes32 a; + bytes16 b; + } + + /// @dev Represents Secp256k1 public key. + /// @param tag Y-coordinate's even/odd indicator of the Secp256k1 public key. + /// @param x X-coordinate component of the Secp256k1 public key. + struct Secp256k1PublicKey { + bytes1 tag; + bytes32 x; + } + + error UnauthorizedOnlyOwnerOrNodeOwner(); + error NodeOwnerExists(); + error NodeOwnerDoesNotExist(); + error NodeOwnerNotFound(); + error ValidatorPubKeyExists(); + error AttesterPubKeyExists(); + error InvalidInputNodeOwnerAddress(); + error InvalidInputBLS12_381PublicKey(); + error InvalidInputBLS12_381Signature(); + error InvalidInputSecp256k1PublicKey(); + + event NodeAdded( + address indexed nodeOwner, + uint32 validatorWeight, + BLS12_381PublicKey validatorPubKey, + BLS12_381Signature validatorPoP, + uint32 attesterWeight, + Secp256k1PublicKey attesterPubKey + ); + event NodeDeactivated(address indexed nodeOwner); + event NodeActivated(address indexed nodeOwner); + event NodeRemoved(address indexed nodeOwner); + event NodeDeleted(address indexed nodeOwner); + event NodeValidatorWeightChanged(address indexed nodeOwner, uint32 newWeight); + event NodeAttesterWeightChanged(address indexed nodeOwner, uint32 newWeight); + event NodeValidatorKeyChanged(address indexed nodeOwner, BLS12_381PublicKey newPubKey, BLS12_381Signature newPoP); + event NodeAttesterKeyChanged(address indexed nodeOwner, Secp256k1PublicKey newPubKey); + event ValidatorsCommitted(uint32 commit); + event AttestersCommitted(uint32 commit); + + function add( + address _nodeOwner, + uint32 _validatorWeight, + BLS12_381PublicKey calldata _validatorPubKey, + BLS12_381Signature calldata _validatorPoP, + uint32 _attesterWeight, + Secp256k1PublicKey calldata _attesterPubKey + ) external; + + function deactivate(address _nodeOwner) external; + + function activate(address _nodeOwner) external; + + function remove(address _nodeOwner) external; + + function changeValidatorWeight(address _nodeOwner, uint32 _weight) external; + + function changeAttesterWeight(address _nodeOwner, uint32 _weight) external; + + function changeValidatorKey( + address _nodeOwner, + BLS12_381PublicKey calldata _pubKey, + BLS12_381Signature calldata _pop + ) external; + + function changeAttesterKey(address _nodeOwner, Secp256k1PublicKey calldata _pubKey) external; + + function commitAttesterCommittee() external; + + function commitValidatorCommittee() external; + + function getAttesterCommittee() external view returns (CommitteeAttester[] memory); + + function getValidatorCommittee() external view returns (CommitteeValidator[] memory); +} diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 474a5a25a..fdaa06327 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -42,7 +42,8 @@ "deploy-l2-weth": "ts-node src/deploy-l2-weth.ts", "upgrade-bridge-contracts": "ts-node src/upgrade-bridge-impl.ts", "update-l2-erc20-metadata": "ts-node src/update-l2-erc20-metadata.ts", - "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts" + "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts", + "deploy-consensus-registry": "ts-node src/deploy-consensus-registry.ts" }, "dependencies": { "dotenv": "^16.0.3" diff --git a/l2-contracts/src/deploy-consensus-registry.ts b/l2-contracts/src/deploy-consensus-registry.ts new file mode 100644 index 000000000..ffbf903f9 --- /dev/null +++ b/l2-contracts/src/deploy-consensus-registry.ts @@ -0,0 +1,90 @@ +import { Command } from "commander"; +import { ethers } from "ethers"; +import { computeL2Create2Address, create2DeployFromL2 } from "./utils"; +import { Interface } from "ethers/lib/utils"; +import { ethTestConfig } from "./deploy-utils"; + +import * as hre from "hardhat"; +import { Provider, Wallet } from "zksync-ethers"; + +const I_TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT = hre.artifacts.readArtifactSync("ITransparentUpgradeableProxy"); +const TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT = hre.artifacts.readArtifactSync("TransparentUpgradeableProxy"); +const CONSENSUS_REGISTRY_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); +const PROXY_ADMIN_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); + +const CONSENSUS_REGISTRY_INTERFACE = new Interface(CONSENSUS_REGISTRY_ARTIFACT.abi); +const I_TRANSPARENT_UPGRADEABLE_PROXY_INTERFACE = new Interface(I_TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.abi); + +// Script to deploy the consensus registry contract and output its address. +// Note, that this script expects that the L2 contracts have been compiled PRIOR +// to running this script. +async function main() { + const program = new Command(); + + program + .version("0.1.0") + .name("deploy-consensus-registry") + .description("Deploys the consensus registry contract to L2"); + + program.option("--private-key ").action(async (cmd) => { + const zksProvider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + const deployWallet = cmd.privateKey + ? new Wallet(cmd.privateKey, zksProvider) + : Wallet.fromMnemonic( + process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, + "m/44'/60'/0'/0/1" + ).connect(zksProvider); + console.log(`Using deployer wallet: ${deployWallet.address}`); + + // Deploy Consensus Registry contract + const consensusRegistryImplementation = await computeL2Create2Address( + deployWallet, + CONSENSUS_REGISTRY_ARTIFACT.bytecode, + "0x", + ethers.constants.HashZero + ); + await create2DeployFromL2(deployWallet, CONSENSUS_REGISTRY_ARTIFACT.bytecode, "0x", ethers.constants.HashZero); + + // Deploy Proxy Admin contract + const proxyAdminContract = await computeL2Create2Address( + deployWallet, + PROXY_ADMIN_ARTIFACT.bytecode, + "0x", + ethers.constants.HashZero + ); + await create2DeployFromL2(deployWallet, PROXY_ADMIN_ARTIFACT.bytecode, "0x", ethers.constants.HashZero); + + const proxyInitializationParams = CONSENSUS_REGISTRY_INTERFACE.encodeFunctionData("initialize", [ + deployWallet.address, + ]); + const proxyConstructor = I_TRANSPARENT_UPGRADEABLE_PROXY_INTERFACE.encodeDeploy([ + consensusRegistryImplementation, + proxyAdminContract, + proxyInitializationParams, + ]); + + await create2DeployFromL2( + deployWallet, + TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.bytecode, + proxyConstructor, + ethers.constants.HashZero + ); + + const address = computeL2Create2Address( + deployWallet, + TRANSPARENT_UPGRADEABLE_PROXY_ARTIFACT.bytecode, + proxyConstructor, + ethers.constants.HashZero + ); + console.log(`CONTRACTS_L2_CONSENSUS_REGISTRY_ADDR=${address}`); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); diff --git a/l2-contracts/src/utils.ts b/l2-contracts/src/utils.ts index c77817a0b..0a479a540 100644 --- a/l2-contracts/src/utils.ts +++ b/l2-contracts/src/utils.ts @@ -143,6 +143,27 @@ export async function create2DeployFromL1( ); } +export async function create2DeployFromL2( + wallet: ethers.Wallet, + bytecode: ethers.BytesLike, + constructor: ethers.BytesLike, + create2Salt: ethers.BytesLike, + extraFactoryDeps?: ethers.BytesLike[] +) { + const deployerSystemContracts = new Interface(artifacts.readArtifactSync("IContractDeployer").abi); + const bytecodeHash = hashL2Bytecode(bytecode); + const calldata = deployerSystemContracts.encodeFunctionData("create2", [create2Salt, bytecodeHash, constructor]); + + const factoryDeps = extraFactoryDeps ? [bytecode, ...extraFactoryDeps] : [bytecode]; + return await wallet.call({ + to: DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + data: calldata, + customData: { + factoryDeps, + }, + }); +} + export async function publishBytecodeFromL1( chainId: ethers.BigNumberish, wallet: ethers.Wallet, diff --git a/l2-contracts/test/consensusRegistry.test.ts b/l2-contracts/test/consensusRegistry.test.ts new file mode 100644 index 000000000..66c0309bd --- /dev/null +++ b/l2-contracts/test/consensusRegistry.test.ts @@ -0,0 +1,499 @@ +import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; +import * as hre from "hardhat"; +import { Provider, Wallet } from "zksync-ethers"; +import type { ConsensusRegistry } from "../typechain"; +import { ConsensusRegistryFactory } from "../typechain"; +import { expect } from "chai"; +import { ethers } from "ethers"; +import { Interface } from "ethers/lib/utils"; + +const richAccount = { + address: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + privateKey: "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110", +}; + +const gasLimit = 100_000_000; + +const CONSENSUS_REGISTRY_ARTIFACT = hre.artifacts.readArtifactSync("ConsensusRegistry"); +const CONSENSUS_REGISTRY_INTERFACE = new Interface(CONSENSUS_REGISTRY_ARTIFACT.abi); + +describe("ConsensusRegistry", function () { + const provider = new Provider(hre.config.networks.localhost.url); + const owner = new Wallet(richAccount.privateKey, provider); + const nonOwner = new Wallet(Wallet.createRandom().privateKey, provider); + const nodes = []; + const nodeEntries = []; + let registry: ConsensusRegistry; + + before("Initialize", async function () { + // Deploy. + const deployer = new Deployer(hre, owner); + const registryInstance = await deployer.deploy(await deployer.loadArtifact("ConsensusRegistry"), []); + const proxyAdmin = await deployer.deploy(await deployer.loadArtifact("ProxyAdmin"), []); + const proxyInitializationParams = CONSENSUS_REGISTRY_INTERFACE.encodeFunctionData("initialize", [owner.address]); + const proxyInstance = await deployer.deploy(await deployer.loadArtifact("TransparentUpgradeableProxy"), [ + registryInstance.address, + proxyAdmin.address, + proxyInitializationParams, + ]); + registry = ConsensusRegistryFactory.connect(proxyInstance.address, owner); + + // Fund nonOwner. + await ( + await owner.sendTransaction({ + to: nonOwner.address, + value: ethers.utils.parseEther("100"), + }) + ).wait(); + + // Prepare the node list. + const numNodes = 10; + for (let i = 0; i < numNodes; i++) { + const node = makeRandomNode(provider); + const nodeEntry = makeRandomNodeEntry(node, i); + nodes.push(node); + nodeEntries.push(nodeEntry); + } + + // Fund the first node owner. + await ( + await owner.sendTransaction({ + to: nodes[0].ownerKey.address, + value: ethers.utils.parseEther("100"), + }) + ).wait(); + }); + + it("Should set the owner as provided in constructor", async function () { + expect(await registry.owner()).to.equal(owner.address); + }); + + it("Should add nodes to both registries", async function () { + for (let i = 0; i < nodes.length; i++) { + await ( + await registry.add( + nodeEntries[i].ownerAddr, + nodeEntries[i].validatorWeight, + nodeEntries[i].validatorPubKey, + nodeEntries[i].validatorPoP, + nodeEntries[i].attesterWeight, + nodeEntries[i].attesterPubKey + ) + ).wait(); + } + + expect(await registry.numNodes()).to.equal(nodes.length); + + for (let i = 0; i < nodes.length; i++) { + const nodeOwner = await registry.nodeOwners(i); + expect(nodeOwner).to.equal(nodeEntries[i].ownerAddr); + const node = await registry.nodes(nodeOwner); + expect(node.attesterLastUpdateCommit).to.equal(0); + expect(node.validatorLastUpdateCommit).to.equal(0); + + // 'Latest' is expected to match the added node's attributes. + expect(node.attesterLatest.active).to.equal(true); + expect(node.attesterLatest.removed).to.equal(false); + expect(node.attesterLatest.weight).to.equal(nodeEntries[i].attesterWeight); + expect(node.attesterLatest.pubKey.tag).to.equal(nodeEntries[i].attesterPubKey.tag); + expect(node.attesterLatest.pubKey.x).to.equal(nodeEntries[i].attesterPubKey.x); + expect(node.validatorLastUpdateCommit).to.equal(0); + expect(node.validatorLatest.active).to.equal(true); + expect(node.validatorLatest.removed).to.equal(false); + expect(node.validatorLatest.weight).to.equal(nodeEntries[i].attesterWeight); + expect(node.validatorLatest.pubKey.a).to.equal(nodeEntries[i].validatorPubKey.a); + expect(node.validatorLatest.pubKey.b).to.equal(nodeEntries[i].validatorPubKey.b); + expect(node.validatorLatest.pubKey.c).to.equal(nodeEntries[i].validatorPubKey.c); + expect(node.validatorLatest.proofOfPossession.a).to.equal(nodeEntries[i].validatorPoP.a); + expect(node.validatorLatest.proofOfPossession.b).to.equal(nodeEntries[i].validatorPoP.b); + + // 'Snapshot' is expected to have zero values. + expect(node.attesterSnapshot.active).to.equal(false); + expect(node.attesterSnapshot.removed).to.equal(false); + expect(node.attesterSnapshot.weight).to.equal(0); + expect(ethers.utils.arrayify(node.attesterSnapshot.pubKey.tag)).to.deep.equal(new Uint8Array(1)); + expect(ethers.utils.arrayify(node.attesterSnapshot.pubKey.x)).to.deep.equal(new Uint8Array(32)); + expect(node.validatorSnapshot.active).to.equal(false); + expect(node.validatorSnapshot.removed).to.equal(false); + expect(node.validatorSnapshot.weight).to.equal(0); + expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.a)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.b)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.pubKey.c)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.proofOfPossession.a)).to.deep.equal(new Uint8Array(32)); + expect(ethers.utils.arrayify(node.validatorSnapshot.proofOfPossession.b)).to.deep.equal(new Uint8Array(16)); + } + }); + + it("Should not allow nonOwner to add", async function () { + await expect( + registry + .connect(nonOwner) + .add( + ethers.Wallet.createRandom().address, + 0, + { a: new Uint8Array(32), b: new Uint8Array(32), c: new Uint8Array(32) }, + { a: new Uint8Array(32), b: new Uint8Array(16) }, + 0, + { tag: new Uint8Array(1), x: new Uint8Array(32) }, + { gasLimit } + ) + ).to.be.reverted; + }); + + it("Should allow owner to deactivate", async function () { + const nodeOwner = nodeEntries[0].ownerAddr; + expect((await registry.nodes(nodeOwner)).validatorLatest.active).to.equal(true); + + await (await registry.connect(owner).deactivate(nodeOwner, { gasLimit })).wait(); + expect((await registry.nodes(nodeOwner)).validatorLatest.active).to.equal(false); + + // Restore state. + await (await registry.connect(owner).activate(nodeOwner, { gasLimit })).wait(); + }); + + it("Should not allow nonOwner, nonNodeOwner to deactivate", async function () { + const nodeOwner = nodeEntries[0].ownerAddr; + await expect(registry.connect(nonOwner).deactivate(nodeOwner, { gasLimit })).to.be.reverted; + }); + + it("Should change validator weight", async function () { + const entry = nodeEntries[0]; + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(entry.validatorWeight); + + const baseWeight = entry.validatorWeight; + const newWeight = getRandomNumber(100, 1000); + await (await registry.changeValidatorWeight(entry.ownerAddr, newWeight, { gasLimit })).wait(); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(newWeight); + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(entry.attesterWeight); + + // Restore state. + await (await registry.changeValidatorWeight(entry.ownerAddr, baseWeight, { gasLimit })).wait(); + }); + + it("Should not allow nodeOwner to change validator weight", async function () { + const node = nodes[0]; + await expect(registry.connect(node.ownerKey).changeValidatorWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should not allow nonOwner to change validator weight", async function () { + const node = nodes[0]; + await expect(registry.connect(nonOwner).changeValidatorWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should change attester weight", async function () { + const entry = nodeEntries[0]; + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(entry.attesterWeight); + + const baseWeight = entry.attesterWeight; + const newWeight = getRandomNumber(100, 1000); + await (await registry.changeAttesterWeight(entry.ownerAddr, newWeight, { gasLimit })).wait(); + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.weight).to.equal(newWeight); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.weight).to.equal(entry.validatorWeight); + + // Restore state. + await (await registry.changeAttesterWeight(entry.ownerAddr, baseWeight, { gasLimit })).wait(); + }); + + it("Should not allow nodeOwner to change attester weight", async function () { + const node = nodes[0]; + await expect(registry.connect(node.ownerKey).changeAttesterWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should not allow nonOwner to change attester weight", async function () { + const node = nodes[0]; + await expect(registry.connect(nonOwner).changeAttesterWeight(node.ownerKey.address, 0, { gasLimit })).to.be + .reverted; + }); + + it("Should not allow to add a node with a validator public key which already exist", async function () { + const newEntry = makeRandomNodeEntry(makeRandomNode(), 0); + await expect( + registry.add( + newEntry.ownerAddr, + newEntry.validatorWeight, + nodeEntries[0].validatorPubKey, + newEntry.validatorPoP, + newEntry.attesterWeight, + newEntry.attesterPubKey, + { gasLimit } + ) + ).to.be.reverted; + }); + + it("Should not allow to add a node with an attester public key which already exist", async function () { + const newEntry = makeRandomNodeEntry(makeRandomNode(), 0); + await expect( + registry.add( + newEntry.ownerAddr, + newEntry.validatorWeight, + newEntry.validatorPubKey, + newEntry.validatorPoP, + newEntry.attesterWeight, + nodeEntries[0].attesterPubKey, + { gasLimit } + ) + ).to.be.reverted; + }); + + it("Should return attester committee once committed to", async function () { + // Verify that committee was not committed to. + expect((await registry.getAttesterCommittee()).length).to.equal(0); + + // Commit. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + + // Read committee. + const attesterCommittee = await registry.getAttesterCommittee(); + expect(attesterCommittee.length).to.equal(nodes.length); + for (let i = 0; i < attesterCommittee.length; i++) { + const entry = nodeEntries[i]; + const attester = attesterCommittee[i]; + expect(attester.weight).to.equal(entry.attesterWeight); + expect(attester.pubKey.tag).to.equal(entry.attesterPubKey.tag); + expect(attester.pubKey.x).to.equal(entry.attesterPubKey.x); + } + }); + + it("Should return validator committee once committed to", async function () { + // Verify that committee was not committed to. + expect((await registry.getValidatorCommittee()).length).to.equal(0); + + // Commit. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + + // Read committee. + const validatorCommittee = await registry.getValidatorCommittee(); + expect(validatorCommittee.length).to.equal(nodes.length); + for (let i = 0; i < validatorCommittee.length; i++) { + const entry = nodeEntries[i]; + const validator = validatorCommittee[i]; + expect(validator.weight).to.equal(entry.validatorWeight); + expect(validator.pubKey.a).to.equal(entry.validatorPubKey.a); + expect(validator.pubKey.b).to.equal(entry.validatorPubKey.b); + expect(validator.pubKey.c).to.equal(entry.validatorPubKey.c); + expect(validator.proofOfPossession.a).to.equal(entry.validatorPoP.a); + expect(validator.proofOfPossession.b).to.equal(entry.validatorPoP.b); + } + }); + + it("Should not include inactive nodes in attester and validator committees when committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Deactivate attribute. + await (await registry.deactivate(entry.ownerAddr, { gasLimit })).wait(); + + // Verify no change. + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit attester committee and verify. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit validator committee and verify. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length - 1); + + // Restore state. + await (await registry.activate(entry.ownerAddr, { gasLimit })).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + it("Should not include removed nodes in attester and validator committees when committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Remove node. + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + + // Verify no change. + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit attester committee and verify. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length); + + // Commit validator committee and verify. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + expect((await registry.getAttesterCommittee()).length).to.equal(nodes.length - 1); + expect((await registry.getValidatorCommittee()).length).to.equal(nodes.length - 1); + + // Restore state. + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + await ( + await registry.add( + entry.ownerAddr, + entry.validatorWeight, + entry.validatorPubKey, + entry.validatorPoP, + entry.attesterWeight, + entry.attesterPubKey + ) + ).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + it("Should not include node attribute change in attester committee before committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Change attribute. + await (await registry.changeAttesterWeight(entry.ownerAddr, entry.attesterWeight + 1, { gasLimit })).wait(); + + // Verify no change. + const attester = (await registry.getAttesterCommittee())[idx]; + expect(attester.weight).to.equal(entry.attesterWeight); + + // Commit. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + + // Verify change. + const committedAttester = (await registry.getAttesterCommittee())[idx]; + expect(committedAttester.weight).to.equal(entry.attesterWeight + 1); + + // Restore state. + await (await registry.changeAttesterWeight(entry.ownerAddr, entry.attesterWeight, { gasLimit })).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + }); + + it("Should not include node attribute change in validator committee before committed to", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Change attribute. + await (await registry.changeValidatorWeight(entry.ownerAddr, entry.attesterWeight + 1, { gasLimit })).wait(); + + // Verify no change. + const validator = (await registry.getValidatorCommittee())[idx]; + expect(validator.weight).to.equal(entry.validatorWeight); + + // Commit. + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + + // Verify change. + const committedValidator = (await registry.getValidatorCommittee())[idx]; + expect(committedValidator.weight).to.equal(entry.validatorWeight + 1); + + // Restore state. + await (await registry.changeValidatorWeight(entry.ownerAddr, entry.validatorWeight, { gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + it("Should finalize node removal by fully deleting it from storage", async function () { + const idx = nodeEntries.length - 1; + const entry = nodeEntries[idx]; + + // Remove. + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.removed).to.equal(false); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.removed).to.equal(false); + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + expect((await registry.nodes(entry.ownerAddr)).attesterLatest.removed).to.equal(true); + expect((await registry.nodes(entry.ownerAddr)).validatorLatest.removed).to.equal(true); + + // Commit committees. + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + + // Verify node was not yet deleted. + expect(await registry.numNodes()).to.equal(nodes.length); + const attesterPubKeyHash = hashAttesterPubKey(entry.attesterPubKey); + expect(await registry.attesterPubKeyHashes(attesterPubKeyHash)).to.be.equal(true); + const validatorPubKeyHash = hashValidatorPubKey(entry.validatorPubKey); + expect(await registry.validatorPubKeyHashes(validatorPubKeyHash)).to.be.equal(true); + + // Trigger node deletion. + await (await registry.remove(entry.ownerAddr, { gasLimit })).wait(); + + // Verify the deletion. + expect(await registry.numNodes()).to.equal(nodes.length - 1); + expect(await registry.attesterPubKeyHashes(attesterPubKeyHash)).to.be.equal(false); + expect(await registry.validatorPubKeyHashes(attesterPubKeyHash)).to.be.equal(false); + const node = await registry.nodes(entry.ownerAddr, { gasLimit }); + expect(ethers.utils.arrayify(node.attesterLatest.pubKey.tag)).to.deep.equal(new Uint8Array(1)); + expect(ethers.utils.arrayify(node.attesterLatest.pubKey.x)).to.deep.equal(new Uint8Array(32)); + + // Restore state. + await ( + await registry.add( + entry.ownerAddr, + entry.validatorWeight, + entry.validatorPubKey, + entry.validatorPoP, + entry.attesterWeight, + entry.attesterPubKey + ) + ).wait(); + await (await registry.commitAttesterCommittee({ gasLimit })).wait(); + await (await registry.commitValidatorCommittee({ gasLimit })).wait(); + }); + + function makeRandomNode() { + return { + ownerKey: new Wallet(Wallet.createRandom().privateKey, provider), + validatorKey: Wallet.createRandom(), + attesterKey: Wallet.createRandom(), + }; + } + + function makeRandomNodeEntry(node, weight: number) { + return { + ownerAddr: node.ownerKey.address, + validatorWeight: weight, + validatorPubKey: getRandomValidatorPubKey(), + validatorPoP: getRandomValidatorPoP(), + attesterWeight: weight, + attesterPubKey: getRandomAttesterPubKey(), + }; + } +}); + +function getRandomNumber(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function getRandomValidatorPubKey() { + return { + a: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + b: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + c: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + }; +} + +function getRandomValidatorPoP() { + return { + a: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + b: ethers.utils.hexlify(ethers.utils.randomBytes(16)), + }; +} + +function getRandomAttesterPubKey() { + return { + tag: ethers.utils.hexlify(ethers.utils.randomBytes(1)), + x: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + }; +} + +function hashAttesterPubKey(attesterPubKey) { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode(["bytes1", "bytes32"], [attesterPubKey.tag, attesterPubKey.x]) + ); +} + +function hashValidatorPubKey(validatorPubKey) { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["bytes32", "bytes32", "bytes32"], + [validatorPubKey.a, validatorPubKey.b, validatorPubKey.c] + ) + ); +} diff --git a/system-contracts/package.json b/system-contracts/package.json index bce80474f..ef53db110 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -14,7 +14,8 @@ "ethers": "^5.7.0", "fast-glob": "^3.3.2", "hardhat": "=2.22.2", - "preprocess": "^3.2.0" + "preprocess": "^3.2.0", + "zksync-ethers": "^5.9.0" }, "devDependencies": { "@matterlabs/hardhat-zksync-chai-matchers": "^0.2.0", diff --git a/system-contracts/scripts/verify-on-explorer.ts b/system-contracts/scripts/verify-on-explorer.ts index 95fa65218..9aa37e3e6 100644 --- a/system-contracts/scripts/verify-on-explorer.ts +++ b/system-contracts/scripts/verify-on-explorer.ts @@ -6,7 +6,7 @@ import { SYSTEM_CONTRACTS } from "./constants"; import { query } from "./utils"; import { Command } from "commander"; import * as fs from "fs"; -import { sleep } from "zksync-ethers/build/src/utils"; +import { sleep } from "zksync-ethers/build/utils"; const VERIFICATION_URL = hre.network?.config?.verifyURL; diff --git a/yarn.lock b/yarn.lock index 2dfdc5f28..6ab96b427 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7926,8 +7926,8 @@ zksync-ethers@^5.0.0: ethers "~5.7.0" zksync-ethers@^5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.9.0.tgz#96dc29e4eaaf0aa70d927886fd6e1e4c545786e3" - integrity sha512-VnRUesrBcPBmiTYTAp+WreIazK2qCIJEHE7j8BiK+cDApHzjAfIXX+x8SXXJpG1npGJANxiJKnPwA5wjGZtCRg== + version "5.9.2" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.9.2.tgz#1c5f34cb25ac0b040fd1a6118f2ba1c2c3bda090" + integrity sha512-Y2Mx6ovvxO6UdC2dePLguVzvNToOY8iLWeq5ne+jgGSJxAi/f4He/NF6FNsf6x1aWX0o8dy4Df8RcOQXAkj5qw== dependencies: ethers "~5.7.0" From a7e892315793ec62dd240c510977064791fedad6 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Fri, 4 Oct 2024 08:33:20 -0400 Subject: [PATCH 40/42] Merge main back into protocol defense (#839) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Danil Co-authored-by: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Co-authored-by: Grzegorz Prusak Co-authored-by: Moshe Shababo <17073733+moshababo@users.noreply.github.com> Co-authored-by: Akosh Farkash Co-authored-by: Bruno França Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Co-authored-by: Roman Brodetski Co-authored-by: vladbochok Co-authored-by: Stanislav Bezkorovainyi Co-authored-by: Danil --- .../deploy-scripts/DeployL2Contracts.sol | 9 ++ l1-contracts/deploy-scripts/EIP712Utils.sol | 30 ++++ l1-contracts/deploy-scripts/Utils.sol | 133 ++++++++++++++++++ .../interfaces/IEmergencyUpgrageBoard.sol | 23 +++ .../deploy-scripts/interfaces/IMultisig.sol | 9 ++ .../interfaces/IProtocolUpgradeHandler.sol | 33 +++++ .../deploy-scripts/interfaces/ISafe.sol | 9 ++ yarn.lock | 7 + 8 files changed, 253 insertions(+) create mode 100644 l1-contracts/deploy-scripts/EIP712Utils.sol create mode 100644 l1-contracts/deploy-scripts/interfaces/IEmergencyUpgrageBoard.sol create mode 100644 l1-contracts/deploy-scripts/interfaces/IMultisig.sol create mode 100644 l1-contracts/deploy-scripts/interfaces/IProtocolUpgradeHandler.sol create mode 100644 l1-contracts/deploy-scripts/interfaces/ISafe.sol diff --git a/l1-contracts/deploy-scripts/DeployL2Contracts.sol b/l1-contracts/deploy-scripts/DeployL2Contracts.sol index 554ed940c..80b458f82 100644 --- a/l1-contracts/deploy-scripts/DeployL2Contracts.sol +++ b/l1-contracts/deploy-scripts/DeployL2Contracts.sol @@ -110,6 +110,15 @@ contract DeployL2Script is Script { saveOutput(); } + function runDeployMulticall3() public { + initializeConfig(); + loadContracts(false); + + deployMulticall3(); + + saveOutput(); + } + function loadContracts(bool legacyBridge) internal { //HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode( diff --git a/l1-contracts/deploy-scripts/EIP712Utils.sol b/l1-contracts/deploy-scripts/EIP712Utils.sol new file mode 100644 index 000000000..5f1aeb958 --- /dev/null +++ b/l1-contracts/deploy-scripts/EIP712Utils.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +library EIP712Utils { + bytes32 private constant TYPE_HASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + function buildDomainHash( + address _verifyingContract, + string memory _name, + string memory _version + ) internal view returns (bytes32) { + return + keccak256( + // solhint-disable-next-line func-named-parameters + abi.encode( + TYPE_HASH, + keccak256(bytes(_name)), + keccak256(bytes(_version)), + block.chainid, + _verifyingContract + ) + ); + } + + function buildDigest(bytes32 _domainHash, bytes32 _message) internal view returns (bytes32) { + return keccak256(abi.encodePacked("\x19\x01", _domainHash, _message)); + } +} diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index fa2bb194c..5f509b0db 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -13,6 +13,26 @@ import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; import {L2_DEPLOYER_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol"; import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; +import {EIP712Utils} from "./EIP712Utils.sol"; +import {IProtocolUpgradeHandler} from "./interfaces/IProtocolUpgradeHandler.sol"; +import {IEmergencyUpgrageBoard} from "./interfaces/IEmergencyUpgrageBoard.sol"; +import {IMultisig} from "./interfaces/IMultisig.sol"; +import {ISafe} from "./interfaces/ISafe.sol"; + +/// @dev EIP-712 TypeHash for the emergency protocol upgrade execution approved by the guardians. +bytes32 constant EXECUTE_EMERGENCY_UPGRADE_GUARDIANS_TYPEHASH = keccak256( + "ExecuteEmergencyUpgradeGuardians(bytes32 id)" +); + +/// @dev EIP-712 TypeHash for the emergency protocol upgrade execution approved by the Security Council. +bytes32 constant EXECUTE_EMERGENCY_UPGRADE_SECURITY_COUNCIL_TYPEHASH = keccak256( + "ExecuteEmergencyUpgradeSecurityCouncil(bytes32 id)" +); + +/// @dev EIP-712 TypeHash for the emergency protocol upgrade execution approved by the ZK Foundation. +bytes32 constant EXECUTE_EMERGENCY_UPGRADE_ZK_FOUNDATION_TYPEHASH = keccak256( + "ExecuteEmergencyUpgradeZKFoundation(bytes32 id)" +); library Utils { // Cheatcodes address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. @@ -342,4 +362,117 @@ library Utils { } vm.stopBroadcast(); } + + function executeEmergencyProtocolUpgrade( + IProtocolUpgradeHandler _protocolUpgradeHandler, + Vm.Wallet memory _governorWallet, + IProtocolUpgradeHandler.Call[] memory _calls, + bytes32 _salt + ) internal returns (bytes memory) { + bytes32 upgradeId; + bytes32 emergencyUpgradeBoardDigest; + { + address emergencyUpgradeBoard = _protocolUpgradeHandler.emergencyUpgradeBoard(); + IProtocolUpgradeHandler.UpgradeProposal memory upgradeProposal = IProtocolUpgradeHandler.UpgradeProposal({ + calls: _calls, + salt: _salt, + executor: emergencyUpgradeBoard + }); + upgradeId = keccak256(abi.encode(upgradeProposal)); + emergencyUpgradeBoardDigest = EIP712Utils.buildDomainHash( + emergencyUpgradeBoard, + "EmergencyUpgradeBoard", + "1" + ); + } + + bytes memory guardiansSignatures; + { + address[] memory guardiansMembers = new address[](8); + { + IMultisig guardians = IMultisig(_protocolUpgradeHandler.guardians()); + for (uint256 i = 0; i < 8; i++) { + guardiansMembers[i] = guardians.members(i); + } + } + bytes[] memory guardiansRawSignatures = new bytes[](8); + for (uint256 i = 0; i < 8; i++) { + bytes32 safeDigest; + { + bytes32 guardiansDigest = EIP712Utils.buildDigest( + emergencyUpgradeBoardDigest, + keccak256(abi.encode(EXECUTE_EMERGENCY_UPGRADE_GUARDIANS_TYPEHASH, upgradeId)) + ); + safeDigest = ISafe(guardiansMembers[i]).getMessageHash(abi.encode(guardiansDigest)); + } + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_governorWallet, safeDigest); + guardiansRawSignatures[i] = abi.encodePacked(r, s, v); + } + guardiansSignatures = abi.encode(guardiansMembers, guardiansRawSignatures); + } + + bytes memory securityCouncilSignatures; + { + address[] memory securityCouncilMembers = new address[](12); + { + IMultisig securityCouncil = IMultisig(_protocolUpgradeHandler.securityCouncil()); + for (uint256 i = 0; i < 12; i++) { + securityCouncilMembers[i] = securityCouncil.members(i); + } + } + bytes[] memory securityCouncilRawSignatures = new bytes[](12); + for (uint256 i = 0; i < securityCouncilMembers.length; i++) { + bytes32 safeDigest; + { + bytes32 securityCouncilDigest = EIP712Utils.buildDigest( + emergencyUpgradeBoardDigest, + keccak256(abi.encode(EXECUTE_EMERGENCY_UPGRADE_SECURITY_COUNCIL_TYPEHASH, upgradeId)) + ); + safeDigest = ISafe(securityCouncilMembers[i]).getMessageHash(abi.encode(securityCouncilDigest)); + } + { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_governorWallet, safeDigest); + securityCouncilRawSignatures[i] = abi.encodePacked(r, s, v); + } + } + securityCouncilSignatures = abi.encode(securityCouncilMembers, securityCouncilRawSignatures); + } + + bytes memory zkFoundationSignature; + { + ISafe zkFoundation; + { + IEmergencyUpgrageBoard emergencyUpgradeBoard = IEmergencyUpgrageBoard( + _protocolUpgradeHandler.emergencyUpgradeBoard() + ); + zkFoundation = ISafe(emergencyUpgradeBoard.ZK_FOUNDATION_SAFE()); + } + bytes32 zkFoundationDigest = EIP712Utils.buildDigest( + emergencyUpgradeBoardDigest, + keccak256(abi.encode(EXECUTE_EMERGENCY_UPGRADE_ZK_FOUNDATION_TYPEHASH, upgradeId)) + ); + bytes32 safeDigest = ISafe(zkFoundation).getMessageHash(abi.encode(zkFoundationDigest)); + { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_governorWallet, safeDigest); + zkFoundationSignature = abi.encodePacked(r, s, v); + } + } + + { + vm.startBroadcast(); + IEmergencyUpgrageBoard emergencyUpgradeBoard = IEmergencyUpgrageBoard( + _protocolUpgradeHandler.emergencyUpgradeBoard() + ); + // solhint-disable-next-line func-named-parameters + emergencyUpgradeBoard.executeEmergencyUpgrade( + _calls, + _salt, + guardiansSignatures, + securityCouncilSignatures, + zkFoundationSignature + ); + vm.stopBroadcast(); + } + } } diff --git a/l1-contracts/deploy-scripts/interfaces/IEmergencyUpgrageBoard.sol b/l1-contracts/deploy-scripts/interfaces/IEmergencyUpgrageBoard.sol new file mode 100644 index 000000000..1f3d0d3d6 --- /dev/null +++ b/l1-contracts/deploy-scripts/interfaces/IEmergencyUpgrageBoard.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {IProtocolUpgradeHandler} from "./IProtocolUpgradeHandler.sol"; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +interface IEmergencyUpgrageBoard { + function GUARDIANS() external view returns (address); + + function SECURITY_COUNCIL() external view returns (address); + + function ZK_FOUNDATION_SAFE() external view returns (address); + + function executeEmergencyUpgrade( + IProtocolUpgradeHandler.Call[] calldata _calls, + bytes32 _salt, + bytes calldata _guardiansSignatures, + bytes calldata _securityCouncilSignatures, + bytes calldata _zkFoundationSignatures + ) external; +} diff --git a/l1-contracts/deploy-scripts/interfaces/IMultisig.sol b/l1-contracts/deploy-scripts/interfaces/IMultisig.sol new file mode 100644 index 000000000..2a1dd955d --- /dev/null +++ b/l1-contracts/deploy-scripts/interfaces/IMultisig.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +interface IMultisig { + function members(uint256) external view returns (address); +} diff --git a/l1-contracts/deploy-scripts/interfaces/IProtocolUpgradeHandler.sol b/l1-contracts/deploy-scripts/interfaces/IProtocolUpgradeHandler.sol new file mode 100644 index 000000000..baa48f43f --- /dev/null +++ b/l1-contracts/deploy-scripts/interfaces/IProtocolUpgradeHandler.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +interface IProtocolUpgradeHandler { + /// @dev Represents a call to be made during an upgrade. + /// @param target The address to which the call will be made. + /// @param value The amount of Ether (in wei) to be sent along with the call. + /// @param data The calldata to be executed on the `target` address. + struct Call { + address target; + uint256 value; + bytes data; + } + + /// @dev Defines the structure of an upgrade that is executed by Protocol Upgrade Handler. + /// @param executor The L1 address that is authorized to perform the upgrade execution (if address(0) then anyone). + /// @param calls An array of `Call` structs, each representing a call to be made during the upgrade execution. + /// @param salt A bytes32 value used for creating unique upgrade proposal hashes. + struct UpgradeProposal { + Call[] calls; + address executor; + bytes32 salt; + } + + function emergencyUpgradeBoard() external view returns (address); + + function guardians() external view returns (address); + + function securityCouncil() external view returns (address); +} diff --git a/l1-contracts/deploy-scripts/interfaces/ISafe.sol b/l1-contracts/deploy-scripts/interfaces/ISafe.sol new file mode 100644 index 000000000..82877b3b3 --- /dev/null +++ b/l1-contracts/deploy-scripts/interfaces/ISafe.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +interface ISafe { + function getMessageHash(bytes memory _message) external view returns (bytes32); +} diff --git a/yarn.lock b/yarn.lock index 6ab96b427..66cd67b1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7931,3 +7931,10 @@ zksync-ethers@^5.9.0: integrity sha512-Y2Mx6ovvxO6UdC2dePLguVzvNToOY8iLWeq5ne+jgGSJxAi/f4He/NF6FNsf6x1aWX0o8dy4Df8RcOQXAkj5qw== dependencies: ethers "~5.7.0" + +zksync-web3@^0.15.4: + version "0.15.5" + resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.15.5.tgz#aabe379464963ab573e15948660a709f409b5316" + integrity sha512-97gB7OKJL4spegl8fGO54g6cvTd/75G6yFWZWEa2J09zhjTrfqabbwE/GwiUJkFQ5BbzoH4JaTlVz1hoYZI+DQ== + dependencies: + ethers "~5.7.0" From efa5d3b76d3cf7bb670ca13953787964cfa278a9 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Fri, 4 Oct 2024 10:25:56 -0400 Subject: [PATCH 41/42] remove whitespace from config --- l1-contracts/hardhat.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l1-contracts/hardhat.config.ts b/l1-contracts/hardhat.config.ts index 78208dd89..884dc43d3 100644 --- a/l1-contracts/hardhat.config.ts +++ b/l1-contracts/hardhat.config.ts @@ -5,7 +5,7 @@ import "hardhat-contract-sizer"; import "hardhat-gas-reporter"; import "hardhat-typechain"; import "solidity-coverage"; - + // If no network is specified, use the default config if (!process.env.CHAIN_ETH_NETWORK) { // eslint-disable-next-line @typescript-eslint/no-var-requires From 84d5e3716f645909e8144c7d50af9dd6dd9ded62 Mon Sep 17 00:00:00 2001 From: Danil Date: Fri, 4 Oct 2024 19:41:50 +0200 Subject: [PATCH 42/42] Update foundry bytecode (#764) Signed-off-by: Danil Co-authored-by: otani Co-authored-by: Zach Kolodny --- .github/workflows/build-release.yaml | 30 +- .github/workflows/l1-contracts-ci.yaml | 58 ++-- .github/workflows/l2-contracts-ci.yaml | 34 ++- .github/workflows/slither.yaml | 13 +- .github/workflows/system-contracts-ci.yaml | 66 ++--- l1-contracts/deploy-scripts/DeployErc20.s.sol | 2 +- .../deploy-scripts/DeployL2Contracts.sol | 40 ++- .../dev/SetupLegacyBridge.s.sol | 16 +- l1-contracts/script-config/.gitkeep | 0 .../script-config/artifacts/BeaconProxy.json | 81 ------ .../artifacts/L2SharedBridge.json | 262 ------------------ .../TransparentUpgradeableProxy.json | 86 ------ .../dev-contracts/DevL2SharedBridge.sol | 2 +- system-contracts/foundry.toml | 1 + system-contracts/scripts/calculate-hashes.ts | 8 +- .../scripts/preprocess-bootloader.ts | 34 ++- 16 files changed, 182 insertions(+), 551 deletions(-) create mode 100644 l1-contracts/script-config/.gitkeep delete mode 100644 l1-contracts/script-config/artifacts/BeaconProxy.json delete mode 100644 l1-contracts/script-config/artifacts/L2SharedBridge.json delete mode 100644 l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json diff --git a/.github/workflows/build-release.yaml b/.github/workflows/build-release.yaml index 2335b74fb..b4292e5e3 100644 --- a/.github/workflows/build-release.yaml +++ b/.github/workflows/build-release.yaml @@ -22,6 +22,15 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ inputs.commit }} + submodules: recursive + + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH - name: Use Node.js uses: actions/setup-node@v3 @@ -35,11 +44,24 @@ jobs: yarn echo "release_tag=${{ inputs.prefix }}-${{ inputs.commit }}" >> $GITHUB_OUTPUT - - name: Build contracts + - name: Build l1 contracts + working-directory: l1-contracts + run: | + forge build + + - name: Build l2 contracts + working-directory: l2-contracts + run: | + forge build --zksync --zk-enable-eravm-extensions + + - name: Build system-contracts + working-directory: system-contracts run: | - yarn l1 build - yarn l2 build - yarn sc build + yarn install + yarn preprocess:system-contracts + forge build --zksync --zk-enable-eravm-extensions + yarn preprocess:bootloader + forge build --zksync --zk-enable-eravm-extensions - name: Prepare artifacts run: | diff --git a/.github/workflows/l1-contracts-ci.yaml b/.github/workflows/l1-contracts-ci.yaml index fbf3cc770..5a27c65f8 100644 --- a/.github/workflows/l1-contracts-ci.yaml +++ b/.github/workflows/l1-contracts-ci.yaml @@ -15,6 +15,16 @@ jobs: steps: - name: Checkout the repository uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH - name: Use Node.js uses: actions/setup-node@v3 @@ -22,26 +32,25 @@ jobs: node-version: 18.18.0 cache: yarn - - name: Install dependencies - run: yarn - - - name: Build artifacts - run: yarn l1 build + - name: Build l1 contracts + working-directory: l1-contracts + run: | + forge build - - name: Build L2 artifacts - run: yarn l2 build + - name: Build l2 contracts + working-directory: l2-contracts + run: | + forge build --zksync --zk-enable-eravm-extensions - name: Create cache uses: actions/cache/save@v3 with: key: artifacts-l1-${{ github.sha }} path: | - l1-contracts/artifacts - l1-contracts/cache - l1-contracts/typechain - l2-contracts/artifacts-zk - l2-contracts/cache-zk - l2-contracts/typechain + l1-contracts/cache-forge + l1-contracts/out + l2-contracts/cache-forge + l2-contracts/zkout lint: runs-on: ubuntu-latest @@ -72,15 +81,19 @@ jobs: with: submodules: recursive - - name: Use Foundry - uses: foundry-rs/foundry-toolchain@v1 - - name: Use Node.js uses: actions/setup-node@v3 with: node-version: 18.18.0 cache: yarn + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH - name: Install dependencies run: yarn @@ -128,7 +141,7 @@ jobs: l2-contracts/typechain - name: Run tests - run: yarn l1 test --no-compile + run: yarn l1 test check-verifier-generator: runs-on: ubuntu-latest @@ -164,15 +177,20 @@ jobs: with: submodules: recursive - - name: Use Foundry - uses: foundry-rs/foundry-toolchain@v1 - - name: Use Node.js uses: actions/setup-node@v3 with: node-version: 18.18.0 cache: yarn + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH + - name: Install dependencies run: yarn diff --git a/.github/workflows/l2-contracts-ci.yaml b/.github/workflows/l2-contracts-ci.yaml index 20bb9583f..e19ac376b 100644 --- a/.github/workflows/l2-contracts-ci.yaml +++ b/.github/workflows/l2-contracts-ci.yaml @@ -10,6 +10,16 @@ jobs: steps: - name: Checkout the repository uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH - name: Use Node.js uses: actions/setup-node@v3 @@ -20,23 +30,25 @@ jobs: - name: Install dependencies run: yarn - - name: Build L1 artifacts - run: yarn l1 build + - name: Build l1 contracts + working-directory: l1-contracts + run: | + forge build - - name: Build L2 artifacts - run: yarn l2 build + - name: Build l2 contracts + working-directory: l2-contracts + run: | + forge build --zksync --zk-enable-eravm-extensions - name: Create cache uses: actions/cache/save@v3 with: - key: artifacts-l2-${{ github.sha }} + key: artifacts-l1-${{ github.sha }} path: | - l1-contracts/artifacts - l1-contracts/cache - l1-contracts/typechain - l2-contracts/artifacts-zk - l2-contracts/cache-zk - l2-contracts/typechain + l1-contracts/cache-forge + l1-contracts/out + l2-contracts/cache-forge + l2-contracts/zkout lint: runs-on: ubuntu-latest diff --git a/.github/workflows/slither.yaml b/.github/workflows/slither.yaml index fa253e159..50c9194dc 100644 --- a/.github/workflows/slither.yaml +++ b/.github/workflows/slither.yaml @@ -27,13 +27,18 @@ jobs: with: python-version: 3.8 + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH + - name: Install Slither run: | pip install slither-analyzer - - name: Use Foundry - uses: foundry-rs/foundry-toolchain@v1 - - name: Remove non-compiled files run: | rm -rf ./l1-contracts/contracts/state-transition/utils/ @@ -43,6 +48,6 @@ jobs: rm -rf ./l1-contracts/contracts/dev-contracts/test/VerifierRecursiveTest.sol - name: Run Slither + working-directory: l1-contracts run: | - cd l1-contracts slither --config ./slither.config.json . diff --git a/.github/workflows/system-contracts-ci.yaml b/.github/workflows/system-contracts-ci.yaml index f842214d6..d1338983e 100644 --- a/.github/workflows/system-contracts-ci.yaml +++ b/.github/workflows/system-contracts-ci.yaml @@ -10,6 +10,16 @@ jobs: steps: - name: Checkout the repository uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install foundry-zksync + run: | + mkdir ./foundry-zksync + curl -LO https://github.com/matter-labs/foundry-zksync/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz + tar zxf foundry_nightly_linux_amd64.tar.gz -C ./foundry-zksync + chmod +x ./foundry-zksync/forge ./foundry-zksync/cast + echo "$PWD/foundry-zksync" >> $GITHUB_PATH - name: Use Node.js uses: actions/setup-node@v3 @@ -17,22 +27,28 @@ jobs: node-version: 18.18.0 cache: yarn - - name: Install dependencies - run: yarn - - name: Build artifacts - run: yarn sc build + working-directory: system-contracts + run: | + yarn install + yarn preprocess:system-contracts + forge build --zksync --zk-enable-eravm-extensions + yarn preprocess:bootloader + forge build --zksync --zk-enable-eravm-extensions + yarn build - name: Create cache uses: actions/cache/save@v3 with: key: artifacts-system-${{ github.sha }} path: | + system-contracts/zkout + system-contracts/cache-forge + system-contracts/bootloader/build system-contracts/artifacts-zk system-contracts/cache-zk system-contracts/typechain system-contracts/contracts-preprocessed - system-contracts/bootloader/build lint: runs-on: ubuntu-latest @@ -72,11 +88,13 @@ jobs: fail-on-cache-miss: true key: artifacts-system-${{ github.sha }} path: | + system-contracts/zkout + system-contracts/cache-forge + system-contracts/bootloader/build system-contracts/artifacts-zk system-contracts/cache-zk system-contracts/typechain system-contracts/contracts-preprocessed - system-contracts/bootloader/build - name: Run bootloader tests run: | @@ -111,11 +129,13 @@ jobs: fail-on-cache-miss: true key: artifacts-system-${{ github.sha }} path: | + system-contracts/zkout + system-contracts/cache-forge + system-contracts/bootloader/build system-contracts/artifacts-zk system-contracts/cache-zk system-contracts/typechain system-contracts/contracts-preprocessed - system-contracts/bootloader/build - name: Run tests run: yarn sc test @@ -123,35 +143,3 @@ jobs: - name: Print output logs of era_test_node if: always() run: cat era_test_node.log - - check-hashes: - needs: [build] - runs-on: ubuntu-latest - - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - - - name: Install dependencies - run: yarn - - - name: Restore artifacts cache - uses: actions/cache/restore@v3 - with: - fail-on-cache-miss: true - key: artifacts-system-${{ github.sha }} - path: | - system-contracts/artifacts-zk - system-contracts/cache-zk - system-contracts/typechain - system-contracts/contracts-preprocessed - system-contracts/bootloader/build - - - name: Check hashes - run: yarn sc calculate-hashes:check diff --git a/l1-contracts/deploy-scripts/DeployErc20.s.sol b/l1-contracts/deploy-scripts/DeployErc20.s.sol index 60f34230a..9a7c9cfa9 100644 --- a/l1-contracts/deploy-scripts/DeployErc20.s.sol +++ b/l1-contracts/deploy-scripts/DeployErc20.s.sol @@ -83,7 +83,7 @@ contract DeployErc20Script is Script { function deployTokens() internal { uint256 tokensLength = config.tokens.length; for (uint256 i = 0; i < tokensLength; ++i) { - TokenDescription memory token = config.tokens[i]; + TokenDescription storage token = config.tokens[i]; console.log("Deploying token:", token.name); address tokenAddress = deployErc20({ name: token.name, diff --git a/l1-contracts/deploy-scripts/DeployL2Contracts.sol b/l1-contracts/deploy-scripts/DeployL2Contracts.sol index 80b458f82..4578f1717 100644 --- a/l1-contracts/deploy-scripts/DeployL2Contracts.sol +++ b/l1-contracts/deploy-scripts/DeployL2Contracts.sol @@ -121,43 +121,41 @@ contract DeployL2Script is Script { function loadContracts(bool legacyBridge) internal { //HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat - contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" + contracts.l2StandardErc20FactoryBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/UpgradeableBeacon.sol/UpgradeableBeacon.json" ); - contracts.beaconProxy = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/BeaconProxy.sol/BeaconProxy.json" - ); - contracts.l2StandardErc20Bytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" + contracts.beaconProxy = Utils.readFoundryBytecode("/../l2-contracts/zkout/BeaconProxy.sol/BeaconProxy.json"); + contracts.l2StandardErc20Bytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/L2StandardERC20.sol/L2StandardERC20.json" ); if (legacyBridge) { - contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/dev-contracts/DevL2SharedBridge.sol/DevL2SharedBridge.json" + contracts.l2SharedBridgeBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/DevL2SharedBridge.sol/DevL2SharedBridge.json" ); } else { - contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json" + contracts.l2SharedBridgeBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/L2SharedBridge.sol/L2SharedBridge.json" ); } - contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" + contracts.l2SharedBridgeProxyBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" ); - contracts.consensusRegistryBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/ConsensusRegistry.sol/ConsensusRegistry.json" + contracts.consensusRegistryBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/ConsensusRegistry.sol/ConsensusRegistry.json" ); - contracts.consensusRegistryProxyBytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" + contracts.consensusRegistryProxyBytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" ); - contracts.multicall3Bytecode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/dev-contracts/Multicall3.sol/Multicall3.json" + contracts.multicall3Bytecode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/Multicall3.sol/Multicall3.json" ); - contracts.forceDeployUpgrader = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" + contracts.forceDeployUpgrader = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/ForceDeployUpgrader.sol/ForceDeployUpgrader.json" ); } diff --git a/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol b/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol index e178824b1..518005915 100644 --- a/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol +++ b/l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol @@ -6,8 +6,8 @@ import {stdToml} from "forge-std/StdToml.sol"; import {Utils} from "./../Utils.sol"; import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {DummyL1ERC20Bridge} from "contracts/dev-contracts/DummyL1ERC20Bridge.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts-v4/proxy/transparent/ProxyAdmin.sol"; +import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; /// This scripts is only for developer @@ -112,8 +112,8 @@ contract SetupLegacyBridge is Script { internal returns (address tokenBeaconAddress, bytes32 tokenBeaconBytecodeHash) { - bytes memory l2StandardTokenCode = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" + bytes memory l2StandardTokenCode = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/L2StandardERC20.sol/L2StandardERC20.json" ); (address l2StandardToken, ) = calculateL2Create2Address( config.l2SharedBridgeAddress, @@ -122,13 +122,11 @@ contract SetupLegacyBridge is Script { "" ); - bytes memory beaconProxy = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json" - ); + bytes memory beaconProxy = Utils.readFoundryBytecode("/../l2-contracts/zkout/BeaconProxy.sol/BeaconProxy.json"); tokenBeaconBytecodeHash = L2ContractHelper.hashL2Bytecode(beaconProxy); - bytes memory upgradableBeacon = Utils.readHardhatBytecode( - "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" + bytes memory upgradableBeacon = Utils.readFoundryBytecode( + "/../l2-contracts/zkout/UpgradeableBeacon.sol/UpgradeableBeacon.json" ); (tokenBeaconAddress, ) = calculateL2Create2Address( diff --git a/l1-contracts/script-config/.gitkeep b/l1-contracts/script-config/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/l1-contracts/script-config/artifacts/BeaconProxy.json b/l1-contracts/script-config/artifacts/BeaconProxy.json deleted file mode 100644 index 258780377..000000000 --- a/l1-contracts/script-config/artifacts/BeaconProxy.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "_format": "hh-zksolc-artifact-1", - "contractName": "BeaconProxy", - "sourceName": "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "beacon", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000001020030019d0000010203300197000300000031035500020000000103550000008008000039000000400080043f00000001022001900000001c0000c13d000000000131034f0000010d02000041000000000202041a0000010b04000041000000800040043f00000106022001970000000004000414000000000303004b000000250000c13d000000040320008c000000ab0000c13d0000000103000031000000200230008c00000000040300190000002004008039000000d60000013d0000010302300041000001040220009c0000002c0000213d0000011d0100004100000000001004350000004101000039000000040010043f0000011e010000410000040400010430000000040320008c000001160000c13d0000000103000031000000200230008c00000000040300190000002004008039000001410000013d0000009f023000390000010502200197000000400020043f0000001f0230018f00000005043002720000003b0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000330000413d000000000502004b0000004a0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000003f0130008c0000014a0000a13d000000800a00043d0000010601a0009c0000014a0000213d000000a00200043d000001070120009c0000014a0000213d0000001f012000390000010804000041000000000531004b000000000500001900000000050480190000010801100197000000000601004b0000000004008019000001080110009c000000000405c019000000000104004b0000014a0000c13d00000080012000390000000001010433000001070410009c0000001f0000213d0000003f04100039000000200700008a000000000474016f000000400900043d0000000004490019000000000594004b00000000050000190000000105004039000001070640009c0000001f0000213d00000001055001900000001f0000c13d0000008003300039000000400040043f0000000006190436000000a0022000390000000004210019000000000334004b0000014a0000213d000600000009001d000500000007001d000400000008001d000000000301004b000000820000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b0000007b0000413d000300000006001d000000000116001900000000000104350000010901000041000000000010043900070000000a001d0000000400a0044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400a00043d000000000101043b000000000101004b000002200000c13d0000006401a000390000011b0200004100000000002104350000004401a000390000011c0200004100000000002104350000002401a0003900000025020000390000000000210435000001150100004100000000001a04350000000401a000390000002002000039000000000021043500000102010000410000010202a0009c000000000a0180190000004001a002100000011a011001c700000404000104300000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000000c30000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000000bb0000413d000000000705004b000000d20000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000014c0000613d0000009f02400039000000e00220018f000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000014a0000213d000000020500036700000000040000310000001f0740018f0000000506400272000000eb0000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000000e40000413d000000000807004b000000f90000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001c40000c13d0000001f0430018f0000000502300272000001070000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001000000413d000000000504004b000001ed0000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000001ed0000013d0000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000012e0000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000001260000413d000000000705004b0000013d0000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000001690000613d0000001f02400039000000600220018f00000080022001bf000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000018c0000a13d00000000010000190000040400010430000000400200043d0000001f0430018f0000000505300272000001590000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001510000413d000000000604004b000001680000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d000000400200043d0000001f0430018f0000000505300272000001760000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000016e0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000010201000041000001020420009c000000000201801900000040012002100000006002300210000000000121019f0000040400010430000000020500036700000000040000310000001f0740018f0000000506400272000001990000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000001920000413d000000000807004b000001a70000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001ee0000c13d0000001f0430018f0000000502300272000001b50000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001ae0000413d000000000504004b000002170000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000001dd0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001d60000413d000000000604004b000001eb0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021c0000613d000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000002070000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000002000000413d000000000604004b000002150000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021e0000613d0000010201000041000001020230009c00000000030180190000006001300210000004030001042e00000060013002100000040400010430000000600130021000000404000104300000010b0100004100000000001a0435000000000100041400000007020000290000010602200197000000040320008c000700000002001d0000022d0000c13d0000000103000031000000200130008c000000000403001900000020040080390000025e0000013d0000010204000041000001020310009c00000000010480190000010203a0009c00000000040a40190000004003400210000000c001100210000000000131019f0000010c011001c700020000000a001d040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000024b0000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002430000413d000000000705004b0000025a0000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000002950000613d0000001f01400039000000600210018f0000000001a20019000000000221004b00000000020000190000000102004039000001070410009c0000001f0000213d00000001022001900000001f0000c13d000000400010043f000000200130008c0000014a0000413d00000000010a0433000001060210009c0000014a0000213d00000109020000410000000000200439000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400200043d000200000002001d000000000101043b000000000101004b000002b20000c13d0000000203000029000000640130003900000118020000410000000000210435000000440130003900000119020000410000000000210435000000240130003900000030020000390000000000210435000001150100004100000000001304350000000401300039000000200200003900000000002104350000010201000041000001020230009c000000000301801900000040013002100000011a011001c70000040400010430000000400200043d0000001f0430018f0000000505300272000002a20000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000029a0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d0000010d01000041000000000201041a0000010e022001970000000705000029000000000252019f000000000021041b00000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010f011001c70000800d0200003900000002030000390000011004000041040203f30000040f000000010120019000000006010000290000014a0000613d0000000001010433000000000101004b000002cd0000c13d0000002001000039000001000010044300000120000004430000011701000041000004030001042e0000010b010000410000000202000029000000000012043500000000010004140000000702000029000000040220008c000002d90000c13d0000000103000031000000200130008c000000000403001900000020040080390000030b0000013d0000010202000041000001020310009c00000000010280190000000204000029000001020340009c00000000020440190000004002200210000000c001100210000000000121019f0000010c011001c70000000702000029040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000002f80000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002f00000413d000000000705004b000003070000613d0000000506600210000000000761034f00000002066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003380000613d0000001f01400039000000600110018f0000000202100029000000000112004b00000000010000190000000101004039000700000002001d000001070220009c00000006040000290000001f0000213d00000001011001900000001f0000c13d0000000701000029000000400010043f000000200130008c0000014a0000413d00000002010000290000000001010433000200000001001d000001060110009c0000014a0000213d0000000701000029000001110110009c0000001f0000213d00000007050000290000006001500039000000400010043f000000400150003900000112020000410000000000210435000000270100003900000000021504360000011301000041000100000002001d0000000000120435000000000204043300000000010004140000000204000029000000040440008c000003550000c13d0000000102000039000001070130009c00000005050000290000001f0000213d0000036d0000013d000000400200043d0000001f0430018f0000000505300272000003450000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000033d0000413d000000000604004b000003540000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d00000102030000410000000305000029000001020450009c00000000050380190000004004500210000001020520009c00000000020380190000006002200210000000000242019f000001020410009c0000000001038019000000c001100210000000000121019f0000000202000029040203fd0000040f0000006004000039000000010220018f00030000000103550000006001100270000101020010019d000001020310019800000004090000290000000505000029000003960000613d0000003f01300039000000000151016f000000400400043d0000000001140019000000000541004b00000000050000190000000105004039000001070610009c0000001f0000213d00000001055001900000001f0000c13d000000400010043f0000001f0130018f000000000934043600000003050003670000000503300272000003870000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b0000037f0000413d000000000601004b000003960000613d0000000503300210000000000535034f00000000033900190000000301100210000000000603043300000000061601cf000000000616022f000000000505043b0000010001100089000000000515022f00000000011501cf000000000161019f00000000001304350000000001040433000000000202004b000003b60000c13d000000000201004b000003dc0000c13d000000400400043d000600000004001d0000011501000041000000000014043500000004014000390000002002000039000000000021043500000007010000290000000003010433000700000003001d0000002401400039000000000031043500000044024000390000000101000029040203e50000040f00000007010000290000001f01100039000000050110017f00000044011000390000010202000041000001020310009c00000000010280190000000604000029000001020340009c00000000040280190000004002400210000003e20000013d000000000101004b000002c80000c13d000001090100004100000000001004390000000201000029000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000000101043b000000000101004b000002c80000c13d000000400100043d00000044021000390000011403000041000000000032043500000024021000390000001d030000390000000000320435000001150200004100000000002104350000000402100039000000200300003900000000003204350000010202000041000001020310009c0000000001028019000000400110021000000116011001c70000040400010430000000000001042f0000010202000041000001020310009c0000000001028019000001020390009c000000000902801900000040029002100000006001100210000000000121019f0000040400010430000000000403004b000003ef0000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000003e80000413d00000000012300190000000000010435000000000001042d000000000001042f000003f6002104210000000102000039000000000001042d0000000002000019000000000001042d000003fb002104230000000102000039000000000001042d0000000002000019000000000001042d00000400002104250000000102000039000000000001042d0000000002000019000000000001042d0000040200000432000004030001042e000004040001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8302000002000000000000000000000000000000240000000000000000000000005c60da1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50ffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000008c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000020000000000000000000000000000004000000100000000000000000073206e6f74206120636f6e747261637400000000000000000000000000000000455243313936373a20626561636f6e20696d706c656d656e746174696f6e206900000000000000000000000000000000000000840000000000000000000000007472616374000000000000000000000000000000000000000000000000000000455243313936373a206e657720626561636f6e206973206e6f74206120636f6e4e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000004000000800000000000000000d32177e88b033622e0bc848f24ab73d0795ed87730981120fcdf94fbc134fa5d", - "deployedBytecode": "0x0004000000000002000700000000000200000000030100190000006003300270000001020030019d0000010203300197000300000031035500020000000103550000008008000039000000400080043f00000001022001900000001c0000c13d000000000131034f0000010d02000041000000000202041a0000010b04000041000000800040043f00000106022001970000000004000414000000000303004b000000250000c13d000000040320008c000000ab0000c13d0000000103000031000000200230008c00000000040300190000002004008039000000d60000013d0000010302300041000001040220009c0000002c0000213d0000011d0100004100000000001004350000004101000039000000040010043f0000011e010000410000040400010430000000040320008c000001160000c13d0000000103000031000000200230008c00000000040300190000002004008039000001410000013d0000009f023000390000010502200197000000400020043f0000001f0230018f00000005043002720000003b0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000330000413d000000000502004b0000004a0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000003f0130008c0000014a0000a13d000000800a00043d0000010601a0009c0000014a0000213d000000a00200043d000001070120009c0000014a0000213d0000001f012000390000010804000041000000000531004b000000000500001900000000050480190000010801100197000000000601004b0000000004008019000001080110009c000000000405c019000000000104004b0000014a0000c13d00000080012000390000000001010433000001070410009c0000001f0000213d0000003f04100039000000200700008a000000000474016f000000400900043d0000000004490019000000000594004b00000000050000190000000105004039000001070640009c0000001f0000213d00000001055001900000001f0000c13d0000008003300039000000400040043f0000000006190436000000a0022000390000000004210019000000000334004b0000014a0000213d000600000009001d000500000007001d000400000008001d000000000301004b000000820000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b0000007b0000413d000300000006001d000000000116001900000000000104350000010901000041000000000010043900070000000a001d0000000400a0044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400a00043d000000000101043b000000000101004b000002200000c13d0000006401a000390000011b0200004100000000002104350000004401a000390000011c0200004100000000002104350000002401a0003900000025020000390000000000210435000001150100004100000000001a04350000000401a000390000002002000039000000000021043500000102010000410000010202a0009c000000000a0180190000004001a002100000011a011001c700000404000104300000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000000c30000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000000bb0000413d000000000705004b000000d20000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000014c0000613d0000009f02400039000000e00220018f000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000014a0000213d000000020500036700000000040000310000001f0740018f0000000506400272000000eb0000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000000e40000413d000000000807004b000000f90000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001c40000c13d0000001f0430018f0000000502300272000001070000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001000000413d000000000504004b000001ed0000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000001ed0000013d0000010201000041000001020340009c0000000004018019000000c0014002100000011f011001c7040203f80000040f000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000012e0000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000001260000413d000000000705004b0000013d0000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000001690000613d0000001f02400039000000600220018f00000080022001bf000000400020043f000000200230008c0000014a0000413d000000800200043d000001060420009c0000018c0000a13d00000000010000190000040400010430000000400200043d0000001f0430018f0000000505300272000001590000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001510000413d000000000604004b000001680000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d000000400200043d0000001f0430018f0000000505300272000001760000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000016e0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000010201000041000001020420009c000000000201801900000040012002100000006002300210000000000121019f0000040400010430000000020500036700000000040000310000001f0740018f0000000506400272000001990000613d00000000080000190000000509800210000000000a95034f000000000a0a043b0000000000a904350000000108800039000000000968004b000001920000413d000000000807004b000001a70000613d00000003077002100000000506600210000000000806043300000000087801cf000000000878022f000000000565034f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f00000000005604350000000005000414000000040620008c000001ee0000c13d0000001f0430018f0000000502300272000001b50000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001ae0000413d000000000504004b000002170000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000001dd0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001d60000413d000000000604004b000001eb0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021c0000613d000002170000013d0000010201000041000001020350009c0000000005018019000001020340009c00000000040180190000006001400210000000c003500210000000000113019f040203fd0000040f0003000000010355000000000301001900000060033002700000001f0430018f000101020030019d00000102033001970000000505300272000002070000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000002000000413d000000000604004b000002150000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f000000000015043500000001012001900000021e0000613d0000010201000041000001020230009c00000000030180190000006001300210000004030001042e00000060013002100000040400010430000000600130021000000404000104300000010b0100004100000000001a0435000000000100041400000007020000290000010602200197000000040320008c000700000002001d0000022d0000c13d0000000103000031000000200130008c000000000403001900000020040080390000025e0000013d0000010204000041000001020310009c00000000010480190000010203a0009c00000000040a40190000004003400210000000c001100210000000000131019f0000010c011001c700020000000a001d040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000024b0000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002430000413d000000000705004b0000025a0000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000002950000613d0000001f01400039000000600210018f0000000001a20019000000000221004b00000000020000190000000102004039000001070410009c0000001f0000213d00000001022001900000001f0000c13d000000400010043f000000200130008c0000014a0000413d00000000010a0433000001060210009c0000014a0000213d00000109020000410000000000200439000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000400200043d000200000002001d000000000101043b000000000101004b000002b20000c13d0000000203000029000000640130003900000118020000410000000000210435000000440130003900000119020000410000000000210435000000240130003900000030020000390000000000210435000001150100004100000000001304350000000401300039000000200200003900000000002104350000010201000041000001020230009c000000000301801900000040013002100000011a011001c70000040400010430000000400200043d0000001f0430018f0000000505300272000002a20000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000029a0000413d000000000604004b000001850000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d0000010d01000041000000000201041a0000010e022001970000000705000029000000000252019f000000000021041b00000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010f011001c70000800d0200003900000002030000390000011004000041040203f30000040f000000010120019000000006010000290000014a0000613d0000000001010433000000000101004b000002cd0000c13d0000002001000039000001000010044300000120000004430000011701000041000004030001042e0000010b010000410000000202000029000000000012043500000000010004140000000702000029000000040220008c000002d90000c13d0000000103000031000000200130008c000000000403001900000020040080390000030b0000013d0000010202000041000001020310009c00000000010280190000000204000029000001020340009c00000000020440190000004002200210000000c001100210000000000121019f0000010c011001c70000000702000029040203f80000040f000000020a000029000000000301001900000060033002700000010203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000002f80000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000002f00000413d000000000705004b000003070000613d0000000506600210000000000761034f00000002066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003380000613d0000001f01400039000000600110018f0000000202100029000000000112004b00000000010000190000000101004039000700000002001d000001070220009c00000006040000290000001f0000213d00000001011001900000001f0000c13d0000000701000029000000400010043f000000200130008c0000014a0000413d00000002010000290000000001010433000200000001001d000001060110009c0000014a0000213d0000000701000029000001110110009c0000001f0000213d00000007050000290000006001500039000000400010043f000000400150003900000112020000410000000000210435000000270100003900000000021504360000011301000041000100000002001d0000000000120435000000000204043300000000010004140000000204000029000000040440008c000003550000c13d0000000102000039000001070130009c00000005050000290000001f0000213d0000036d0000013d000000400200043d0000001f0430018f0000000505300272000003450000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000033d0000413d000000000604004b000003540000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001850000013d00000102030000410000000305000029000001020450009c00000000050380190000004004500210000001020520009c00000000020380190000006002200210000000000242019f000001020410009c0000000001038019000000c001100210000000000121019f0000000202000029040203fd0000040f0000006004000039000000010220018f00030000000103550000006001100270000101020010019d000001020310019800000004090000290000000505000029000003960000613d0000003f01300039000000000151016f000000400400043d0000000001140019000000000541004b00000000050000190000000105004039000001070610009c0000001f0000213d00000001055001900000001f0000c13d000000400010043f0000001f0130018f000000000934043600000003050003670000000503300272000003870000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b0000037f0000413d000000000601004b000003960000613d0000000503300210000000000535034f00000000033900190000000301100210000000000603043300000000061601cf000000000616022f000000000505043b0000010001100089000000000515022f00000000011501cf000000000161019f00000000001304350000000001040433000000000202004b000003b60000c13d000000000201004b000003dc0000c13d000000400400043d000600000004001d0000011501000041000000000014043500000004014000390000002002000039000000000021043500000007010000290000000003010433000700000003001d0000002401400039000000000031043500000044024000390000000101000029040203e50000040f00000007010000290000001f01100039000000050110017f00000044011000390000010202000041000001020310009c00000000010280190000000604000029000001020340009c00000000040280190000004002400210000003e20000013d000000000101004b000002c80000c13d000001090100004100000000001004390000000201000029000000040010044300000102010000410000000002000414000001020320009c0000000002018019000000c0012002100000010a011001c70000800202000039040203f80000040f0000000102200190000003db0000613d000000000101043b000000000101004b000002c80000c13d000000400100043d00000044021000390000011403000041000000000032043500000024021000390000001d030000390000000000320435000001150200004100000000002104350000000402100039000000200300003900000000003204350000010202000041000001020310009c0000000001028019000000400110021000000116011001c70000040400010430000000000001042f0000010202000041000001020310009c0000000001028019000001020390009c000000000902801900000040029002100000006001100210000000000121019f0000040400010430000000000403004b000003ef0000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000003e80000413d00000000012300190000000000010435000000000001042d000000000001042f000003f6002104210000000102000039000000000001042d0000000002000019000000000001042d000003fb002104230000000102000039000000000001042d0000000002000019000000000001042d00000400002104250000000102000039000000000001042d0000000002000019000000000001042d0000040200000432000004030001042e000004040001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8302000002000000000000000000000000000000240000000000000000000000005c60da1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50ffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000008c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000020000000000000000000000000000004000000100000000000000000073206e6f74206120636f6e747261637400000000000000000000000000000000455243313936373a20626561636f6e20696d706c656d656e746174696f6e206900000000000000000000000000000000000000840000000000000000000000007472616374000000000000000000000000000000000000000000000000000000455243313936373a206e657720626561636f6e206973206e6f74206120636f6e4e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000004000000800000000000000000d32177e88b033622e0bc848f24ab73d0795ed87730981120fcdf94fbc134fa5d", - "linkReferences": {}, - "deployedLinkReferences": {}, - "factoryDeps": {} -} diff --git a/l1-contracts/script-config/artifacts/L2SharedBridge.json b/l1-contracts/script-config/artifacts/L2SharedBridge.json deleted file mode 100644 index a74e5c9ad..000000000 --- a/l1-contracts/script-config/artifacts/L2SharedBridge.json +++ /dev/null @@ -1,262 +0,0 @@ -{ - "_format": "hh-zksolc-artifact-1", - "contractName": "L2SharedBridge", - "sourceName": "contracts/bridge/L2SharedBridge.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_eraChainId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Receiver", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "FinalizeDeposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l2Sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l1Receiver", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrawalInitiated", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Sender", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Receiver", - "type": "address" - }, - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "finalizeDeposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1SharedBridge", - "type": "address" - }, - { - "internalType": "address", - "name": "_l1Bridge", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_l2TokenProxyBytecodeHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_aliasedOwner", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l1Bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1SharedBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "l2TokenAddress", - "type": "address" - } - ], - "name": "l1TokenAddress", - "outputs": [ - { - "internalType": "address", - "name": "l1TokenAddress", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - } - ], - "name": "l2TokenAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2TokenBeacon", - "outputs": [ - { - "internalType": "contract UpgradeableBeacon", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Receiver", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x0004000000000002001000000000000200000000030100190000006004300270000001a20340019700030000003103550002000000010355000001a20040019d00000001022001900000001d0000c13d0000008002000039000000400020043f000000040230008c000000400000413d000000000201043b000000e002200270000001ab0420009c000000420000213d000001b10420009c0000008a0000213d000001b40120009c000000c10000613d000001b50120009c000000400000c13d0000000001000416000000000101004b000000400000c13d0000000401000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000bf02300039000001a302200197000000400020043f0000001f0230018f00000005043002720000002f0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000000270000413d000000000502004b0000003e0000613d0000000504400210000000000141034f0000000302200210000000a004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f0000000000140435000000200130008c000000640000813d00000000010000190000068300010430000001ac0420009c000000940000213d000001af0420009c000000c60000613d000001b00220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000600220008c000000400000413d0000000402100370000000000402043b000001b60240009c000000400000213d0000002402100370000000000302043b000001b60230009c000000400000213d0000004401100370000000000201043b000000000102004b000001de0000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000001501000039000000a40010043f000001c501000041000000c40010043f000001c6010000410000068300010430000000a00100043d000000800010043f000000000200041a0000ff0003200190000000ac0000c13d000000ff0320018f000000ff0330008c000000820000613d000000ff012001bf000000000010041b000000ff01000039000000400200043d0000000000120435000001a2010000410000000003000414000001a20430009c0000000003018019000001a20420009c00000000020180190000004001200210000000c002300210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d000000800100043d000001400000044300000160001004430000002001000039000001000010044300000001010000390000012000100443000001aa01000041000006820001042e000001b20420009c000001a50000613d000001b30120009c000000400000c13d0000000001000416000000000101004b000000400000c13d000000000100041a0000001001100270000001da0000013d000001ad0420009c000001c90000613d000001ae0220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d068106050000040f000001b601100197000000400200043d0000000000120435000001a201000041000001a20320009c00000000020180190000004001200210000001b7011001c7000006820001042e000000400100043d0000006402100039000001a40300004100000000003204350000004402100039000001a5030000410000000000320435000000240210003900000027030000390000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001a7011001c700000683000104300000000001000416000000000101004b000000400000c13d0000000101000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000a00220008c000000400000413d0000000402100370000000000802043b000001b60280009c000000400000213d0000002402100370000000000902043b000001b60290009c000000400000213d0000004402100370000000000a02043b000001b602a0009c000000400000213d0000008402100370000000000202043b000001bd0420009c000000400000213d0000002304200039000001c705000041000000000634004b00000000060000190000000006058019000001c704400197000000000704004b0000000005008019000001c70440009c000000000506c019000000000405004b000000400000c13d0000000404200039000000000441034f000000000504043b000001bd0450009c000000400000213d001000240020003d0000001002500029000000000232004b000000400000213d000b00000005001d000f0000000a001d000e00000009001d000c00000008001d0000006401100370000000000101043b000d00000001001d0000000001000411000001c801100041000001b6011001970000000402000039000000000202041a000001b602200197000000000221004b000001050000613d000000000200041a0000001002200270000001b602200197000000000121004b000002c10000c13d0000000101000039000800000001001d000000000101041a000001b601100197000000a00010043f0000004001000039000900000001001d000000c00010043f000000e00000043f0000006001000039000a00000001001d000000800010043f0000010001000039000000400010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ca011001c700008010020000390681067c0000040f00000001022001900000000f05000029000000400000613d0000000202000039000700000002001d000000000202041a000000000301043b000000400100043d000000a004100039000000000034043500000080031000390000000000230435000000600210003900000000005204350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000002170000213d000000c003100039000000400030043f000001a204000041000001a20320009c000000000204801900000040022002100000000001010433000001a20310009c00000000010480190000006001100210000000000121019f0000000002000414000001a20320009c0000000002048019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000500000001001d000001b601100197000600000001001d00000000001004350000000301000039000400000001001d000000200010043f0000000001000414000001a20210009c000001a201008041000000c001100210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000000000101041a000001b601100198000003ad0000c13d00000000010004140000000702000029000000000402041a0000000802000029000000000202041a000000400300043d000000400530003900000009060000290000000000650435000001b602200197000000200530003900000000002504350000000a02000029000000000023043500000060023000390000000000020435000001c00230009c000002170000213d0000008002300039000000400020043f000000a005300039000001cf060000410000000000650435000000e4053000390000000a060000290000000000650435000000c4053000390000000000450435000000a4043000390000000f0500002900000000005404350000010405300039000000000403043300000000004504350000012405300039000000000604004b0000018a0000613d000000000600001900000000075600190000002006600039000000000836001900000000080804330000000000870435000000000746004b000001830000413d000000000354001900000000000304350000001f03400039000a0020000000920000000a0330017f00000084043000390000000000420435000000c3033000390000000a0430017f0000000003240019000000000443004b00000000040000190000000104004039000001bd0530009c000002170000213d0000000104400190000002170000c13d000000400030043f0000000004020433000001d00540009c0000045f0000413d0000004401300039000001dc02000041000000000021043500000024013000390000000802000039000002b50000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000800220008c000000400000413d0000000402100370000000000202043b000001b60320009c000000400000213d0000002403100370000000000603043b000001b60360009c000000400000213d0000006403100370000000000503043b000001b60350009c000000400000213d000000000300041a0000fffe043001900000021d0000c13d000001e00330019700000102033001bf000000000030041b0000004401100370000000000401043b000000000102004b000002290000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f501000041000000610000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d00000000001004350000000301000039000000200010043f00000040020000390000000001000019068106610000040f000000000101041a000001b601100197000000800010043f000001b801000041000006820001042e000f00000002001d000e00000004001d000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000001004000029000000400000613d000000400500043d00000024015000390000000f020000290000000000210435000001bb0100004100000000001504350000000001000411000d00000001001d000001b601100197000000040250003900000000001204350000000001000414000000040240008c000002150000613d000001a202000041000001a20310009c0000000001028019000001a20350009c00000000020540190000004002200210000000c001100210000000000121019f000001bc011001c70000000002040019000c00000005001d068106770000040f0000000c05000029000000100400002900000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000002640000613d000001bd0150009c000002400000a13d000001f00100004100000000001004350000004101000039000000040010043f000001ef010000410000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000002e01000039000000a40010043f000001dd01000041000000c40010043f000001de01000041000000e40010043f000001df010000410000068300010430000000000104004b000002330000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f401000041000000610000013d001000000006001d000f00000004001d000e00000005001d000000000105004b000002870000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f301000041000000610000013d000000400050043f00000000004004350000000301000039000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000400200043d0000002403200039000000000101043b000000000101041a000001b601100198000002c90000c13d000001a6010000410000000000120435000000040120003900000020040000390000000000410435000000020100003900000000001304350000004401200039000001c3030000410000000000310435000001a201000041000001a20320009c00000000020180190000004001200210000001c4011001c70000068300010430000000400200043d0000001f0430018f0000000505300272000002710000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000002690000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20420009c000000000201801900000040012002100000006002300210000000000121019f0000068300010430000001e1013001970000001002200210000001e202200197000000000121019f000000000010041b000001e3010000410000000000100439000000000100041200000004001004430000002400000443000001a2030000410000000001000414000001a20210009c0000000001038019000000c001100210000001e4011001c700008005020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000d00000001001d000001e50100004100000000001004390000000001000414000001a20210009c000001a201008041000000c001100210000001e6011001c70000800b020000390681067c0000040f00000001022001900000059c0000613d000000400200043d000c00000002001d000000000101043b0000000d0110006c0000034d0000c13d000000100100006b0000038f0000c13d0000000c030000290000004401300039000001f2020000410000000000210435000000240130003900000003020000390000000000210435000001a6010000410000000000130435000000040130003900000020020000390000000000210435000001a201000041000001a20230009c00000000030180190000004001300210000001c4011001c70000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001c901000041000000610000013d0000002004200039000001bf0500004100000000005404350000000e04000029000000600440021000000000004304350000006001100210000000380320003900000000001304350000004c012000390000000f0300002900000000003104350000004c010000390000000000120435000001c00120009c000002170000213d0000008003200039000000400030043f000001c101000041000c00000003001d0000000000130435000000840120003900000020030000390000000000310435000000a40320003900000000010204330000000000130435000000c403200039000000000401004b000002ef0000613d000000000400001900000000053400190000002004400039000000000624001900000000060604330000000000650435000000000514004b000002e80000413d000000000231001900000000000204350000001f01100039000000200200008a000000000121016f000001a2020000410000000c04000029000001a20340009c0000000003020019000000000304401900000040033002100000004401100039000001a20410009c00000000010280190000006001100210000000000131019f0000000003000414000001a20430009c0000000003028019000000c002300210000000000112019f0000800802000039068106770000040f0000000c0a00002900000000030100190000006003300270000001a203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000003190000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000003110000413d000000000705004b000003280000613d0000000506600210000000000761034f0000000c066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003720000613d0000001f01400039000000600210018f0000000c01200029000000000221004b00000000020000190000000102004039000001bd0410009c00000010070000290000000e05000029000002170000213d0000000102200190000002170000c13d000000400010043f000000200230008c000000400000413d0000000f020000290000000000210435000001a2020000410000000003000414000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000112019f000001a8011001c7000001b6065001970000800d020000390000000403000039000001c2040000410000000d05000029000003a80000013d0000000c01000029000001e70110009c000002170000813d0000000c040000290000002401400039000001e8020000410000000000210435000000440140003900000000020004140000006003000039001000000003001d0000000000310435000001e90100004100000000001404350000006401400039000000000001043500000004014000390000000000010435000001a201000041000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000121019f000001ea011001c70000800602000039068106770000040f0000000102200190000003fc0000613d000000000201043b000000000102004b000004380000c13d00000003010003670000000102000031000004010000013d000000400200043d0000001f0430018f00000005053002720000037f0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000003770000413d000000000604004b0000038e0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d0000000401000039000000000201041a000001d90220019700000010022001af000000000021041b000001f101000041000000000200041a000000000112016f000000000010041b00000002010000390000000c040000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d0000000001000019000006820001042e0000000f0110006c000004260000c13d000001b901000041000000000010043900000006010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400400043d00000024014000390000000d030000290000000000310435000001da010000410000000000140435000001b602200197001000000004001d0000000401400039000f00000002001d000000000021043500000000010004140000000602000029000000040220008c000003e30000613d000001a202000041000001a20310009c00000000010280190000001004000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001bc011001c70000000602000029068106770000040f00000000030100190000006003300270000101a20030019d000001a203300197000300000001035500000001022001900000059d0000613d0000001001000029000001bd0110009c000002170000213d0000001004000029000000400040043f0000000d010000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000000c02000029000001b6052001970000800d020000390000000403000039000001db040000410000000f060000290000000607000029000003a80000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000040e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000004060000413d000000000604004b0000041d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20430009c0000000003018019000001a20420009c000000000201801900000060012002100000004002300210000000000112019f0000068300010430000000400100043d0000004402100039000001ce030000410000000000320435000000240210003900000007030000290000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001c4011001c70000068300010430000000400100043d000001eb0310009c000002170000213d000001b602200197000000840310003900000000002304350000002402100039000001ec0300004100000000003204350000006402100039000000000300041400000020040000390000000000420435000000440210003900000010040000290000000000420435000001e902000041000000000021043500000004021000390000000000020435000001a202000041000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000121019f000001ed011001c70000800602000039068106770000040f00000001022001900000053c0000613d000000000101043b000000000201004b0000055e0000c13d00000003010003670000000102000031000005410000013d000000c001100210000001d1011001970000004002200210000001d202200041000001d302200197000000000121019f0000006002400210000001d402200197000000000121019f000001d5011001c700008006020000390000000003000019000000000400001900000000050000190000000006000019068106770000040f000300000001035500000000030100190000006003300270000101a20030019d000001a2053001970000003f03500039000001a306300197000000400400043d0000000003460019000000000663004b00000000060000190000000106004039000001bd0730009c000002170000213d0000000106600190000002170000c13d000000400030043f00000000035404360000001f0650003900000005066002720000048f0000613d0000000007000031000000020770036700000000080000190000000509800210000000000a930019000000000997034f000000000909043b00000000009a04350000000108800039000000000968004b000004870000413d000000000600004b000004910000613d0000001f0650018f00000005055002720000049d0000613d000000000700001900000005087002100000000009830019000000000881034f000000000808043b00000000008904350000000107700039000000000857004b000004950000413d000000000706004b000004ac0000613d0000000505500210000000000151034f00000000055300190000000306600210000000000705043300000000076701cf000000000767022f000000000101043b0000010006600089000000000161022f00000000016101cf000000000171019f00000000001504350000000101200190000005ba0000613d0000000001040433000001c702000041000000200410008c00000000040000190000000004024019000001c701100197000000000501004b000000000200a019000001c70110009c000000000204c019000000000102004b000000400000c13d0000000001030433000800000001001d000001b60110009c000000400000213d000001b901000041000000000010043900000008010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000f020000290000000b04000029000000400000613d000000400300043d000001d701000041000000000013043500000024053000390000000901000029000300000005001d00000000001504350000000401300039000200000001001d00000000002104350000001f0240018f0000006401300039000900000003001d0000004403300039000100000003001d0000000000430435000000100300002900000002033003670000000504400272000004ee0000613d000000000500001900000005065002100000000007610019000000000663034f000000000606043b00000000006704350000000105500039000000000645004b000004e60000413d000000000502004b000004fd0000613d0000000504400210000000000343034f00000000044100190000000302200210000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f00000000002404350000000b01100029000000000001043500000000010004140000000802000029000000040220008c0000051e0000613d0000000b020000290000001f022000390000000a0220017f000001a2030000410000000905000029000001a20450009c0000000004030019000000000405401900000040044002100000006402200039000001a20520009c00000000020380190000006002200210000000000224019f000001a20410009c0000000001038019000000c001100210000000000121019f0000000802000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005db0000613d0000000901000029000001bd0110009c000002170000213d0000000901000029000000400010043f0000000802000029000000050120014f000001b601100198000005f80000c13d000000060100002900000000001004350000000401000029000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f00000001022001900000000f03000029000000400000613d000000000101043b000000000201041a000001d902200197000000000232019f000000000021041b000003af0000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000054e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005460000413d000000000604004b0000055d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000041d0000013d000001b6031001970000000101000039000000000201041a000001d902200197000000000232019f000000000021041b00000002010000390000000f02000029000000000021041b000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400300043d000001ee010000410000000000130435000c00000003001d0000000401300039000000000021043500000000010004140000001002000029000000040220008c000005960000613d000001a202000041000001a20310009c00000000010280190000000c04000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001ef011001c70000001002000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005be0000613d0000000c01000029000001bd0110009c000002170000213d0000000c01000029000000400010043f000003940000013d000000000001042f000000400200043d0000001f0430018f0000000505300272000005aa0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005a20000413d000000000604004b000005b90000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400100043d0000004402100039000001d603000041000004290000013d000000400200043d0000001f0430018f0000000505300272000005cb0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005c30000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400200043d0000001f0430018f0000000505300272000005e80000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005e00000413d000000000604004b000005f70000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000001a60100004100000009030000290000000000130435000000200100003900000002020000290000000000120435000000070100002900000003020000290000000000120435000001d80100004100000001020000290000000000120435000002bb0000013d0001000000000002000100000001001d0000000101000039000000000301041a000000400100043d00000040021000390000004004000039000000000042043500000060020000390000000002210436000001b603300197000000000032043500000060031000390000000000030435000001f60310009c000006580000813d0000008003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d0000000202000039000000000202041a000000000301043b000000400100043d000000a0041000390000000000340435000000800310003900000000002304350000000102000029000001b602200197000000600310003900000000002304350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000006580000213d000000c003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d000000000101043b000001b601100197000000000001042d000001f00100004100000000001004350000004101000039000000040010043f000001ef01000041000006830001043000000000010000190000068300010430000000000001042f000001a203000041000001a20410009c00000000010380190000004001100210000001a20420009c00000000020380190000006002200210000000000112019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000006750000613d000000000101043b000000000001042d000000000100001900000683000104300000067a002104210000000102000039000000000001042d0000000002000019000000000001042d0000067f002104230000000102000039000000000001042d0000000002000019000000000001042d0000068100000432000006820001042e0000068300010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe0616c697a696e6700000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320696e69746908c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000002000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000cfe7af7b00000000000000000000000000000000000000000000000000000000f54266a100000000000000000000000000000000000000000000000000000000f54266a200000000000000000000000000000000000000000000000000000000f5f1516800000000000000000000000000000000000000000000000000000000cfe7af7c00000000000000000000000000000000000000000000000000000000d9caed1200000000000000000000000000000000000000000000000000000000a31ee5af00000000000000000000000000000000000000000000000000000000a31ee5b000000000000000000000000000000000000000000000000000000000b852ad36000000000000000000000000000000000000000000000000000000006dde720900000000000000000000000000000000000000000000000000000000969b53da000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000008000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83020000020000000000000000000000000000002400000000000000000000000074f4f547000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff020000000000000000000000000000000000004000000000000000000000000011a2ccc100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f62f84b24000000000000000000000000000000000000000000000000000000002fc3848834aac8e883a2d2a17a7514dc4f2d3dd268089df9b9f5d918259ef3b079680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000416d6f756e742063616e6e6f74206265207a65726f000000000000000000000000000000000000000000000000000000000000640000008000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeffffffffffffffffffffffffffffffffeeef6d710000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000060000000a000000000000000002020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494000000000000000000000000000000000000000000000000ffffffffffffff3f020000000000000000000000000000000000000000000000000000000000000067670000000000000000000000000000000000000000000000000000000000003cda335100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffff00000000000000000000000001000000000000000000000000000000000000000000000000000000000000006d6b00000000000000000000000000000000000000000000000000000000000095f11a40000000000000000000000000000000000000000000000000000000006d74000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000008c2a993e00000000000000000000000000000000000000000000000000000000b84fba9af218da60d299dc177abd5805e7ac541d2673cbee7808c10017874f634f766572666c6f77000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65640000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000000000000000000000000000000000000000010200000000000000000000ffffffffffffffffffffffffffffffffffffffff0000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e02000002000000000000000000000000000000440000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7c010004751688ab9322961547058fd0f36d3edf69880b64cbb2857041d33f4a133cda33511d41a8a5431b1770c5bc0ddd62e1cd30555d16659b89c0d60f4f9f570200000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7b010000691fa4f751f8312bc555242f18ed78cdc9aabc0ea77d7d5a675ee8ac6f02000000000000000000000000000000000000a4000000000000000000000000f2fde38b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6266320000000000000000000000000000000000000000000000000000000000736600000000000000000000000000000000000000000000000000000000000064660000000000000000000000000000000000000000000000000000000000006266000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff800000000000000000000000000000000000000000000000000000000000000000f5cf0be6820df44d868e986d4d5cafabd5702ac45d181a5ac4eb5ed59a001b03", - "deployedBytecode": "0x0004000000000002001000000000000200000000030100190000006004300270000001a20340019700030000003103550002000000010355000001a20040019d00000001022001900000001d0000c13d0000008002000039000000400020043f000000040230008c000000400000413d000000000201043b000000e002200270000001ab0420009c000000420000213d000001b10420009c0000008a0000213d000001b40120009c000000c10000613d000001b50120009c000000400000c13d0000000001000416000000000101004b000000400000c13d0000000401000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000bf02300039000001a302200197000000400020043f0000001f0230018f00000005043002720000002f0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000000270000413d000000000502004b0000003e0000613d0000000504400210000000000141034f0000000302200210000000a004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f0000000000140435000000200130008c000000640000813d00000000010000190000068300010430000001ac0420009c000000940000213d000001af0420009c000000c60000613d000001b00220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000600220008c000000400000413d0000000402100370000000000402043b000001b60240009c000000400000213d0000002402100370000000000302043b000001b60230009c000000400000213d0000004401100370000000000201043b000000000102004b000001de0000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000001501000039000000a40010043f000001c501000041000000c40010043f000001c6010000410000068300010430000000a00100043d000000800010043f000000000200041a0000ff0003200190000000ac0000c13d000000ff0320018f000000ff0330008c000000820000613d000000ff012001bf000000000010041b000000ff01000039000000400200043d0000000000120435000001a2010000410000000003000414000001a20430009c0000000003018019000001a20420009c00000000020180190000004001200210000000c002300210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d000000800100043d000001400000044300000160001004430000002001000039000001000010044300000001010000390000012000100443000001aa01000041000006820001042e000001b20420009c000001a50000613d000001b30120009c000000400000c13d0000000001000416000000000101004b000000400000c13d000000000100041a0000001001100270000001da0000013d000001ad0420009c000001c90000613d000001ae0220009c000000400000c13d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d068106050000040f000001b601100197000000400200043d0000000000120435000001a201000041000001a20320009c00000000020180190000004001200210000001b7011001c7000006820001042e000000400100043d0000006402100039000001a40300004100000000003204350000004402100039000001a5030000410000000000320435000000240210003900000027030000390000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001a7011001c700000683000104300000000001000416000000000101004b000000400000c13d0000000101000039000001d90000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000a00220008c000000400000413d0000000402100370000000000802043b000001b60280009c000000400000213d0000002402100370000000000902043b000001b60290009c000000400000213d0000004402100370000000000a02043b000001b602a0009c000000400000213d0000008402100370000000000202043b000001bd0420009c000000400000213d0000002304200039000001c705000041000000000634004b00000000060000190000000006058019000001c704400197000000000704004b0000000005008019000001c70440009c000000000506c019000000000405004b000000400000c13d0000000404200039000000000441034f000000000504043b000001bd0450009c000000400000213d001000240020003d0000001002500029000000000232004b000000400000213d000b00000005001d000f0000000a001d000e00000009001d000c00000008001d0000006401100370000000000101043b000d00000001001d0000000001000411000001c801100041000001b6011001970000000402000039000000000202041a000001b602200197000000000221004b000001050000613d000000000200041a0000001002200270000001b602200197000000000121004b000002c10000c13d0000000101000039000800000001001d000000000101041a000001b601100197000000a00010043f0000004001000039000900000001001d000000c00010043f000000e00000043f0000006001000039000a00000001001d000000800010043f0000010001000039000000400010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ca011001c700008010020000390681067c0000040f00000001022001900000000f05000029000000400000613d0000000202000039000700000002001d000000000202041a000000000301043b000000400100043d000000a004100039000000000034043500000080031000390000000000230435000000600210003900000000005204350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000002170000213d000000c003100039000000400030043f000001a204000041000001a20320009c000000000204801900000040022002100000000001010433000001a20310009c00000000010480190000006001100210000000000121019f0000000002000414000001a20320009c0000000002048019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000500000001001d000001b601100197000600000001001d00000000001004350000000301000039000400000001001d000000200010043f0000000001000414000001a20210009c000001a201008041000000c001100210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000000101043b000000000101041a000001b601100198000003ad0000c13d00000000010004140000000702000029000000000402041a0000000802000029000000000202041a000000400300043d000000400530003900000009060000290000000000650435000001b602200197000000200530003900000000002504350000000a02000029000000000023043500000060023000390000000000020435000001c00230009c000002170000213d0000008002300039000000400020043f000000a005300039000001cf060000410000000000650435000000e4053000390000000a060000290000000000650435000000c4053000390000000000450435000000a4043000390000000f0500002900000000005404350000010405300039000000000403043300000000004504350000012405300039000000000604004b0000018a0000613d000000000600001900000000075600190000002006600039000000000836001900000000080804330000000000870435000000000746004b000001830000413d000000000354001900000000000304350000001f03400039000a0020000000920000000a0330017f00000084043000390000000000420435000000c3033000390000000a0430017f0000000003240019000000000443004b00000000040000190000000104004039000001bd0530009c000002170000213d0000000104400190000002170000c13d000000400030043f0000000004020433000001d00540009c0000045f0000413d0000004401300039000001dc02000041000000000021043500000024013000390000000802000039000002b50000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000800220008c000000400000413d0000000402100370000000000202043b000001b60320009c000000400000213d0000002403100370000000000603043b000001b60360009c000000400000213d0000006403100370000000000503043b000001b60350009c000000400000213d000000000300041a0000fffe043001900000021d0000c13d000001e00330019700000102033001bf000000000030041b0000004401100370000000000401043b000000000102004b000002290000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f501000041000000610000013d0000000002000416000000000202004b000000400000c13d000000040230008a000000200220008c000000400000413d0000000401100370000000000101043b000001b60210009c000000400000213d00000000001004350000000301000039000000200010043f00000040020000390000000001000019068106610000040f000000000101041a000001b601100197000000800010043f000001b801000041000006820001042e000f00000002001d000e00000004001d000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000001004000029000000400000613d000000400500043d00000024015000390000000f020000290000000000210435000001bb0100004100000000001504350000000001000411000d00000001001d000001b601100197000000040250003900000000001204350000000001000414000000040240008c000002150000613d000001a202000041000001a20310009c0000000001028019000001a20350009c00000000020540190000004002200210000000c001100210000000000121019f000001bc011001c70000000002040019000c00000005001d068106770000040f0000000c05000029000000100400002900000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000002640000613d000001bd0150009c000002400000a13d000001f00100004100000000001004350000004101000039000000040010043f000001ef010000410000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000002e01000039000000a40010043f000001dd01000041000000c40010043f000001de01000041000000e40010043f000001df010000410000068300010430000000000104004b000002330000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f401000041000000610000013d001000000006001d000f00000004001d000e00000005001d000000000105004b000002870000c13d000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001f301000041000000610000013d000000400050043f00000000004004350000000301000039000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f0000000102200190000000400000613d000000400200043d0000002403200039000000000101043b000000000101041a000001b601100198000002c90000c13d000001a6010000410000000000120435000000040120003900000020040000390000000000410435000000020100003900000000001304350000004401200039000001c3030000410000000000310435000001a201000041000001a20320009c00000000020180190000004001200210000001c4011001c70000068300010430000000400200043d0000001f0430018f0000000505300272000002710000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000002690000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20420009c000000000201801900000040012002100000006002300210000000000121019f0000068300010430000001e1013001970000001002200210000001e202200197000000000121019f000000000010041b000001e3010000410000000000100439000000000100041200000004001004430000002400000443000001a2030000410000000001000414000001a20210009c0000000001038019000000c001100210000001e4011001c700008005020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000d00000001001d000001e50100004100000000001004390000000001000414000001a20210009c000001a201008041000000c001100210000001e6011001c70000800b020000390681067c0000040f00000001022001900000059c0000613d000000400200043d000c00000002001d000000000101043b0000000d0110006c0000034d0000c13d000000100100006b0000038f0000c13d0000000c030000290000004401300039000001f2020000410000000000210435000000240130003900000003020000390000000000210435000001a6010000410000000000130435000000040130003900000020020000390000000000210435000001a201000041000001a20230009c00000000030180190000004001300210000001c4011001c70000068300010430000001a601000041000000800010043f0000002001000039000000840010043f0000000201000039000000a40010043f000001c901000041000000610000013d0000002004200039000001bf0500004100000000005404350000000e04000029000000600440021000000000004304350000006001100210000000380320003900000000001304350000004c012000390000000f0300002900000000003104350000004c010000390000000000120435000001c00120009c000002170000213d0000008003200039000000400030043f000001c101000041000c00000003001d0000000000130435000000840120003900000020030000390000000000310435000000a40320003900000000010204330000000000130435000000c403200039000000000401004b000002ef0000613d000000000400001900000000053400190000002004400039000000000624001900000000060604330000000000650435000000000514004b000002e80000413d000000000231001900000000000204350000001f01100039000000200200008a000000000121016f000001a2020000410000000c04000029000001a20340009c0000000003020019000000000304401900000040033002100000004401100039000001a20410009c00000000010280190000006001100210000000000131019f0000000003000414000001a20430009c0000000003028019000000c002300210000000000112019f0000800802000039068106770000040f0000000c0a00002900000000030100190000006003300270000001a203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000003190000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000003110000413d000000000705004b000003280000613d0000000506600210000000000761034f0000000c066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000102200190000003720000613d0000001f01400039000000600210018f0000000c01200029000000000221004b00000000020000190000000102004039000001bd0410009c00000010070000290000000e05000029000002170000213d0000000102200190000002170000c13d000000400010043f000000200230008c000000400000413d0000000f020000290000000000210435000001a2020000410000000003000414000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000112019f000001a8011001c7000001b6065001970000800d020000390000000403000039000001c2040000410000000d05000029000003a80000013d0000000c01000029000001e70110009c000002170000813d0000000c040000290000002401400039000001e8020000410000000000210435000000440140003900000000020004140000006003000039001000000003001d0000000000310435000001e90100004100000000001404350000006401400039000000000001043500000004014000390000000000010435000001a201000041000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000121019f000001ea011001c70000800602000039068106770000040f0000000102200190000003fc0000613d000000000201043b000000000102004b000004380000c13d00000003010003670000000102000031000004010000013d000000400200043d0000001f0430018f00000005053002720000037f0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000003770000413d000000000604004b0000038e0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d0000000401000039000000000201041a000001d90220019700000010022001af000000000021041b000001f101000041000000000200041a000000000112016f000000000010041b00000002010000390000000c040000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000800d020000390000000103000039000001a904000041068106770000040f0000000101200190000000400000613d0000000001000019000006820001042e0000000f0110006c000004260000c13d000001b901000041000000000010043900000006010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400400043d00000024014000390000000d030000290000000000310435000001da010000410000000000140435000001b602200197001000000004001d0000000401400039000f00000002001d000000000021043500000000010004140000000602000029000000040220008c000003e30000613d000001a202000041000001a20310009c00000000010280190000001004000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001bc011001c70000000602000029068106770000040f00000000030100190000006003300270000101a20030019d000001a203300197000300000001035500000001022001900000059d0000613d0000001001000029000001bd0110009c000002170000213d0000001004000029000000400040043f0000000d010000290000000000140435000001a2010000410000000002000414000001a20320009c0000000002018019000001a20340009c00000000040180190000004001400210000000c002200210000000000112019f000001a8011001c70000000c02000029000001b6052001970000800d020000390000000403000039000001db040000410000000f060000290000000607000029000003a80000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000040e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000004060000413d000000000604004b0000041d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000001a201000041000001a20430009c0000000003018019000001a20420009c000000000201801900000060012002100000004002300210000000000112019f0000068300010430000000400100043d0000004402100039000001ce030000410000000000320435000000240210003900000007030000290000000000320435000001a6020000410000000000210435000000040210003900000020030000390000000000320435000001a202000041000001a20310009c00000000010280190000004001100210000001c4011001c70000068300010430000000400100043d000001eb0310009c000002170000213d000001b602200197000000840310003900000000002304350000002402100039000001ec0300004100000000003204350000006402100039000000000300041400000020040000390000000000420435000000440210003900000010040000290000000000420435000001e902000041000000000021043500000004021000390000000000020435000001a202000041000001a20430009c0000000003028019000001a20410009c00000000010280190000004001100210000000c002300210000000000121019f000001ed011001c70000800602000039068106770000040f00000001022001900000053c0000613d000000000101043b000000000201004b0000055e0000c13d00000003010003670000000102000031000005410000013d000000c001100210000001d1011001970000004002200210000001d202200041000001d302200197000000000121019f0000006002400210000001d402200197000000000121019f000001d5011001c700008006020000390000000003000019000000000400001900000000050000190000000006000019068106770000040f000300000001035500000000030100190000006003300270000101a20030019d000001a2053001970000003f03500039000001a306300197000000400400043d0000000003460019000000000663004b00000000060000190000000106004039000001bd0730009c000002170000213d0000000106600190000002170000c13d000000400030043f00000000035404360000001f0650003900000005066002720000048f0000613d0000000007000031000000020770036700000000080000190000000509800210000000000a930019000000000997034f000000000909043b00000000009a04350000000108800039000000000968004b000004870000413d000000000600004b000004910000613d0000001f0650018f00000005055002720000049d0000613d000000000700001900000005087002100000000009830019000000000881034f000000000808043b00000000008904350000000107700039000000000857004b000004950000413d000000000706004b000004ac0000613d0000000505500210000000000151034f00000000055300190000000306600210000000000705043300000000076701cf000000000767022f000000000101043b0000010006600089000000000161022f00000000016101cf000000000171019f00000000001504350000000101200190000005ba0000613d0000000001040433000001c702000041000000200410008c00000000040000190000000004024019000001c701100197000000000501004b000000000200a019000001c70110009c000000000204c019000000000102004b000000400000c13d0000000001030433000800000001001d000001b60110009c000000400000213d000001b901000041000000000010043900000008010000290000000400100443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000f020000290000000b04000029000000400000613d000000400300043d000001d701000041000000000013043500000024053000390000000901000029000300000005001d00000000001504350000000401300039000200000001001d00000000002104350000001f0240018f0000006401300039000900000003001d0000004403300039000100000003001d0000000000430435000000100300002900000002033003670000000504400272000004ee0000613d000000000500001900000005065002100000000007610019000000000663034f000000000606043b00000000006704350000000105500039000000000645004b000004e60000413d000000000502004b000004fd0000613d0000000504400210000000000343034f00000000044100190000000302200210000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f00000000002404350000000b01100029000000000001043500000000010004140000000802000029000000040220008c0000051e0000613d0000000b020000290000001f022000390000000a0220017f000001a2030000410000000905000029000001a20450009c0000000004030019000000000405401900000040044002100000006402200039000001a20520009c00000000020380190000006002200210000000000224019f000001a20410009c0000000001038019000000c001100210000000000121019f0000000802000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005db0000613d0000000901000029000001bd0110009c000002170000213d0000000901000029000000400010043f0000000802000029000000050120014f000001b601100198000005f80000c13d000000060100002900000000001004350000000401000029000000200010043f000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001be011001c700008010020000390681067c0000040f00000001022001900000000f03000029000000400000613d000000000101043b000000000201041a000001d902200197000000000232019f000000000021041b000003af0000013d000300000001035500000000020100190000006002200270000101a20020019d000001a202200197000000400300043d0000001f0420018f00000005052002720000054e0000613d000000000600001900000005076002100000000008730019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005460000413d000000000604004b0000055d0000613d0000000505500210000000000151034f00000000055300190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000041d0000013d000001b6031001970000000101000039000000000201041a000001d902200197000000000232019f000000000021041b00000002010000390000000f02000029000000000021041b000001b9010000410000000000100439001000000003001d0000000400300443000001a2010000410000000002000414000001a20320009c0000000002018019000000c001200210000001ba011001c700008002020000390681067c0000040f00000001022001900000059c0000613d000000000101043b000000000101004b0000000e02000029000000400000613d000000400300043d000001ee010000410000000000130435000c00000003001d0000000401300039000000000021043500000000010004140000001002000029000000040220008c000005960000613d000001a202000041000001a20310009c00000000010280190000000c04000029000001a20340009c00000000020440190000004002200210000000c001100210000000000121019f000001ef011001c70000001002000029068106770000040f00000000030100190000006003300270000101a20030019d000001a20330019700030000000103550000000102200190000005be0000613d0000000c01000029000001bd0110009c000002170000213d0000000c01000029000000400010043f000003940000013d000000000001042f000000400200043d0000001f0430018f0000000505300272000005aa0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005a20000413d000000000604004b000005b90000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400100043d0000004402100039000001d603000041000004290000013d000000400200043d0000001f0430018f0000000505300272000005cb0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005c30000413d000000000604004b000002800000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000000400200043d0000001f0430018f0000000505300272000005e80000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000005e00000413d000000000604004b000005f70000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000002800000013d000001a60100004100000009030000290000000000130435000000200100003900000002020000290000000000120435000000070100002900000003020000290000000000120435000001d80100004100000001020000290000000000120435000002bb0000013d0001000000000002000100000001001d0000000101000039000000000301041a000000400100043d00000040021000390000004004000039000000000042043500000060020000390000000002210436000001b603300197000000000032043500000060031000390000000000030435000001f60310009c000006580000813d0000008003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d0000000202000039000000000202041a000000000301043b000000400100043d000000a0041000390000000000340435000000800310003900000000002304350000000102000029000001b602200197000000600310003900000000002304350000004002100039000000000300041000000000003204350000002002100039000001cb030000410000000000320435000000a0030000390000000000310435000001cc0310009c000006580000213d000000c003100039000000400030043f000001a203000041000001a20420009c000000000203801900000040022002100000000001010433000001a20410009c00000000010380190000006001100210000000000121019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f00000001022001900000065e0000613d000000000101043b000001b601100197000000000001042d000001f00100004100000000001004350000004101000039000000040010043f000001ef01000041000006830001043000000000010000190000068300010430000000000001042f000001a203000041000001a20410009c00000000010380190000004001100210000001a20420009c00000000020380190000006002200210000000000112019f0000000002000414000001a20420009c0000000002038019000000c002200210000000000112019f000001cd011001c700008010020000390681067c0000040f0000000102200190000006750000613d000000000101043b000000000001042d000000000100001900000683000104300000067a002104210000000102000039000000000001042d0000000002000019000000000001042d0000067f002104230000000102000039000000000001042d0000000002000019000000000001042d0000068100000432000006820001042e0000068300010430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe0616c697a696e6700000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320696e69746908c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000002000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000cfe7af7b00000000000000000000000000000000000000000000000000000000f54266a100000000000000000000000000000000000000000000000000000000f54266a200000000000000000000000000000000000000000000000000000000f5f1516800000000000000000000000000000000000000000000000000000000cfe7af7c00000000000000000000000000000000000000000000000000000000d9caed1200000000000000000000000000000000000000000000000000000000a31ee5af00000000000000000000000000000000000000000000000000000000a31ee5b000000000000000000000000000000000000000000000000000000000b852ad36000000000000000000000000000000000000000000000000000000006dde720900000000000000000000000000000000000000000000000000000000969b53da000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000008000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83020000020000000000000000000000000000002400000000000000000000000074f4f547000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff020000000000000000000000000000000000004000000000000000000000000011a2ccc100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f62f84b24000000000000000000000000000000000000000000000000000000002fc3848834aac8e883a2d2a17a7514dc4f2d3dd268089df9b9f5d918259ef3b079680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000416d6f756e742063616e6e6f74206265207a65726f000000000000000000000000000000000000000000000000000000000000640000008000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeffffffffffffffffffffffffffffffffeeef6d710000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000060000000a000000000000000002020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494000000000000000000000000000000000000000000000000ffffffffffffff3f020000000000000000000000000000000000000000000000000000000000000067670000000000000000000000000000000000000000000000000000000000003cda335100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffff00000000000000000000000001000000000000000000000000000000000000000000000000000000000000006d6b00000000000000000000000000000000000000000000000000000000000095f11a40000000000000000000000000000000000000000000000000000000006d74000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000008c2a993e00000000000000000000000000000000000000000000000000000000b84fba9af218da60d299dc177abd5805e7ac541d2673cbee7808c10017874f634f766572666c6f77000000000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65640000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000000000000000000000000000000000000000010200000000000000000000ffffffffffffffffffffffffffffffffffffffff0000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e02000002000000000000000000000000000000440000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7c010004751688ab9322961547058fd0f36d3edf69880b64cbb2857041d33f4a133cda33511d41a8a5431b1770c5bc0ddd62e1cd30555d16659b89c0d60f4f9f570200000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7b010000691fa4f751f8312bc555242f18ed78cdc9aabc0ea77d7d5a675ee8ac6f02000000000000000000000000000000000000a4000000000000000000000000f2fde38b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6266320000000000000000000000000000000000000000000000000000000000736600000000000000000000000000000000000000000000000000000000000064660000000000000000000000000000000000000000000000000000000000006266000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff800000000000000000000000000000000000000000000000000000000000000000f5cf0be6820df44d868e986d4d5cafabd5702ac45d181a5ac4eb5ed59a001b03", - "linkReferences": {}, - "deployedLinkReferences": {}, - "factoryDeps": { - "0x010000691fa4f751f8312bc555242f18ed78cdc9aabc0ea77d7d5a675ee8ac6f": "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol:UpgradeableBeacon", - "0x010004751688ab9322961547058fd0f36d3edf69880b64cbb2857041d33f4a13": "contracts/bridge/L2StandardERC20.sol:L2StandardERC20" - } -} diff --git a/l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json b/l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json deleted file mode 100644 index c8880c120..000000000 --- a/l1-contracts/script-config/artifacts/TransparentUpgradeableProxy.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "_format": "hh-zksolc-artifact-1", - "contractName": "TransparentUpgradeableProxy", - "sourceName": "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x00020000000000020008000000000002000000000301001900000060033002700000012c0330019700010000003103550000008008000039000000400080043f00000001022001900000001e0000c13d000000000431034f00000000050004110000013d02000041000000000702041a0000013002700197000000000603004b000000270000c13d000000000325004b0000010c0000c13d000000000101043b0000014101100197000001420310009c0000001b0000613d000001430310009c000002c20000613d000001440310009c000002680000c13d00000000010004160000000001000019000004ac000104300000012d023000410000012e0220009c0000005f0000213d000001520100004100000000001004350000004101000039000000040010043f0000015301000041000004ac00010430000000000525004b0000012d0000c13d000000000401043b0000014104400197000001420540009c000001670000c13d0000000002000416000000000202004b000002c20000c13d000000240230008c000002c20000413d0000000401100370000000000201043b000001300120009c000002c20000213d000000a001000039000000400010043f000000800000043f00000133010000410000000000100439000800000002001d00000004002004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002a80000c13d000000400100043d00000064021000390000015403000041000000000032043500000044021000390000015503000041000000000032043500000024021000390000002d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014c011001c7000004ac000104300000009f023000390000012f02200197000000400020043f0000001f0230018f00000005043002720000006e0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000660000413d000000000502004b0000007d0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000005f0130008c000002c20000a13d000000800900043d000001300190009c000002c20000213d000000a00700043d000001300170009c000002c20000213d000000c00200043d000001310120009c000002c20000213d0000001f012000390000013204000041000000000531004b000000000500001900000000050480190000013201100197000000000601004b0000000004008019000001320110009c000000000405c019000000000104004b000002c20000c13d00000080012000390000000001010433000001310410009c000000210000213d0000003f04100039000000200a00008a0000000004a4016f000000400b00043d00000000044b00190000000005b4004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d0000008003300039000000400040043f00000000061b0436000000a0022000390000000004210019000000000334004b000002c20000213d00060000000b001d00050000000a001d000700000007001d000300000008001d000000000301004b000000b90000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b000000b20000413d000400000006001d0000000001160019000000000001043500000133010000410000000000100439000800000009001d00000004009004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d000000080100002900000130051001970000013501000041000000000201041a0000013602200197000000000252019f000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f0000000803000029000000010120019000000007020000290000000605000029000002c20000613d0000000001050433000000000101004b000003770000c13d0000013d01000041000000000301041a0000013004200197000000400100043d0000002002100039000800000004001d0000000000420435000700000003001d000001300230019700000000002104350000012c0200004100000000030004140000012c0430009c00000000030280190000012c0410009c00000000010280190000004001100210000000c002300210000000000112019f0000013e011001c70000800d0200003900000001030000390000013f0400004104aa049b0000040f0000000101200190000002c20000613d000000080100006b0000025a0000613d0000000701000029000001360110019700000008011001af0000013d02000041000000000012041b0000002001000039000001000010044300000120000004430000014001000041000004ab0001042e0000013501000041000000000201041a00000000010004140000013002200197000000040320008c000001e90000c13d00000000030000310000001f0230018f00000005013002720000011e0000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001170000413d000000000502004b0000020e0000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f00000000002104350000020e0000013d0000001f0530018f0000013502000041000000000202041a000001300220019700000005063002720000013b0000613d00000000070000190000000508700210000000000981034f000000000909043b00000000009804350000000107700039000000000867004b000001340000413d000000000705004b000001490000613d00000003055002100000000506600210000000000706043300000000075701cf000000000757022f000000000161034f000000000101043b0000010005500089000000000151022f00000000015101cf000000000171019f00000000001604350000000001000414000000040520008c0000020f0000c13d00000000030000310000001f0230018f0000000501300272000001580000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001510000413d000000000502004b000002360000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f0000000000210435000002360000013d000001430540009c0000023b0000c13d000000440230008c000002c20000413d0000000402100370000000000802043b000001300280009c000002c20000213d0000002402100370000000000402043b000001310240009c000002c20000213d00000023024000390000013205000041000000000632004b000000000600001900000000060580190000013202200197000000000702004b0000000005008019000001320220009c000000000506c019000000000205004b000002c20000c13d0000000405400039000000000251034f000000000202043b000001310620009c000000210000213d000000bf06200039000000200900008a000000000696016f000001310760009c000000210000213d000000400060043f000000800020043f00000000042400190000002404400039000000000334004b000002c20000213d0000002003500039000000000131034f0000001f0320018f00000005042002720000019d0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000001950000413d000700000009001d000000000503004b000001ad0000613d0000000504400210000000000141034f0000000303300210000000a004400039000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000140435000000a001200039000000000001043500000133010000410000000000100439000800000008001d00000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d0000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008030000290000000101200190000002c20000613d000000400100043d000600000001001d000001390110009c000000210000213d00000006040000290000006001400039000000400010043f00000040014000390000013a02000041000000000021043500000020014000390000013b02000041000000000021043500000027010000390000000000140435000000800200043d0000000001000414000000040330008c0000040d0000c13d000000010200003900000000040000310000041d0000013d0000012c030000410000012c0410009c0000000001038019000000c00110021004aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000001fe0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001f70000413d000000000604004b0000020c0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002640000613d000002360000013d0000012c040000410000012c0510009c0000000001048019000000c0011002100000006003300210000000000131019f04aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000002260000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b0000021f0000413d000000000604004b000002340000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002660000613d0000012c010000410000012c0230009c00000000030180190000006001300210000004ab0001042e000001440540009c0000026e0000c13d0000000004000416000000000404004b000002c20000c13d000000240330008c000002c20000413d0000000401100370000000000401043b000001300140009c000002c20000213d000000800020043f000000a00040043f0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000148011001c70000800d020000390000000103000039000700000004001d0000013f04000041000800000007001d04aa049b0000040f000000070400002900000008030000290000000101200190000002c20000613d000000000104004b000002c40000c13d000000400100043d00000064021000390000014a03000041000000000032043500000044021000390000014b03000041000000000032043500000024021000390000002603000039000000530000013d0000006001300210000004ac000104300000006001300210000004ac00010430000001450310009c000002750000c13d0000000001000416000000000101004b000002c20000c13d0000027d0000013d000001450140009c000002840000c13d0000000001000416000000000101004b000002c20000c13d000000a00020043f0000028d0000013d000001460110009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013002100197000000a00020043f0000002001000039000000800010043f000000c001000039000000400010043f0000015a01000041000004ab0001042e000001460140009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013001100197000000a00010043f0000002001000039000000800010043f000000c001000039000000400010043f000000800100003900000147020000410000015003000041000001500410009c000000000103801900000040011002100000015101100041000000000121019f000004ab0001042e0000013c01000041000000800010043f0000002001000039000000840010043f0000004201000039000000a40010043f0000015601000041000000c40010043f0000015701000041000000e40010043f0000015801000041000001040010043f0000015901000041000004ac000104300000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008080000290000000101200190000002c20000613d000000800100043d000000000101004b000002d00000c13d000000400100043d000001490210009c000000210000213d000002cb0000013d0000000001000019000004ac000104300000013601300197000000000114019f0000013d02000041000000000012041b000000400100043d000001490210009c000000210000213d0000002002100039000000400020043f00000000000104350000000002000019000002930000013d000000400900043d000001390190009c000000210000213d0000006001900039000000400010043f00000040019000390000013a02000041000000000021043500000020019000390000013b02000041000000000021043500000027010000390000000000190435000000800200043d0000000001000414000000040380008c000002e40000c13d00000001020000390000000004000031000002f70000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c70000000002080019000700000009001d04aa04a50000040f00000007090000290000000808000029000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b000003230000c13d0000000003030433000000000202004b000003530000c13d000000000203004b0000038c0000c13d000000400100043d0000013c0200004100000000002104350000000402100039000000200300003900000000003204350000000002090433000000240310003900000000002304350000004403100039000000000402004b000003140000613d000000000400001900000000053400190000002004400039000000000694001900000000060604330000000000650435000000000524004b0000030d0000413d0000001f04200039000000200500008a000000000454016f0000000002320019000000000002043500000044024000390000012c030000410000012c0420009c00000000020380190000012c0410009c000000000103801900000040011002100000006002200210000000000112019f000004ac00010430000001310140009c000000210000213d0000003f01400039000000200300008a000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000000a090019000000400010043f0000001f0540018f000000000143043600000001060003670000000504400272000003410000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000003390000413d000000000705004b000000080800002900000000090a0019000002fb0000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000002fb0000013d000000000103004b000002be0000c13d0000013301000041000000000010043900000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002be0000c13d000000400100043d00000044021000390000014e03000041000000000032043500000024021000390000001d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014f011001c7000004ac00010430000000400400043d000001390140009c000000210000213d0000006001400039000000400010043f00000040014000390000013a0200004100000000002104350000002701000039000200000004001d00000000021404360000013b01000041000100000002001d000000000012043500000000020504330000000001000414000000040330008c000003950000c13d00000001020000390000000003000031000003a90000013d0000012c020000410000012c0430009c00000000030280190000012c0410009c000000000102801900000040011002100000006002300210000000000112019f000004ac000104300000012c0300004100000004050000290000012c0450009c000000000503801900000040045002100000012c0520009c00000000020380190000006002200210000000000242019f0000012c0410009c0000000001038019000000c001100210000000000112019f000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c031001970000006001000039000000000403004b000003c90000c13d0000000001010433000000000202004b000003f70000c13d000000000201004b000004830000c13d000000400400043d000800000004001d0000013c01000041000000000014043500000004014000390000002002000039000000000021043500000002010000290000000003010433000700000003001d000000240140003900000000003104350000004402400039000000010100002904aa048d0000040f00000007010000290000001f01100039000000050110017f00000044011000390000012c020000410000012c0310009c00000000010280190000000804000029000004870000013d000001310130009c0000000504000029000000210000213d0000003f01300039000000000441016f000000400100043d0000000004410019000000000514004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d000000400040043f0000001f0430018f000000000931043600000001050003670000000503300272000003e60000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b000003de0000413d000300000009001d000000000604004b000003ac0000613d0000000503300210000000000535034f00000003033000290000000304400210000000000603043300000000064601cf000000000646022f000000000505043b0000010004400089000000000545022f00000000044501cf000000000464019f0000000000430435000003ac0000013d000000000101004b00000007020000290000000803000029000000e60000c13d0000013301000041000000000010043900000004003004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000000702000029000000e60000c13d000003650000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c7000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b0000043e0000c13d0000000003030433000000000202004b0000046b0000c13d000000000203004b0000038c0000c13d000000400100043d0000013c02000041000000000021043500000004021000390000002003000039000000000032043500000006070000290000000002070433000000240310003900000000002304350000004403100039000000000402004b0000043b0000613d000000000400001900000000053400190000002004400039000000000674001900000000060604330000000000650435000000000524004b000004340000413d0000001f042000390000000705000029000003160000013d000001310140009c0000000703000029000000210000213d0000003f01400039000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000400010043f0000001f0540018f0000000001430436000000010600036700000005044002720000045b0000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000004530000413d000000000705004b000004210000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000004210000013d000000000103004b0000047e0000c13d00000133010000410000000000100439000000080100002900000004001004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000003650000613d000000400100043d000001490210009c000000210000213d000002cb0000013d000000000001042f0000012c020000410000012c0310009c000000000102801900000003040000290000012c0340009c000000000402801900000040024002100000006001100210000000000121019f000004ac00010430000000000403004b000004970000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000004900000413d00000000012300190000000000010435000000000001042d000000000001042f0000049e002104210000000102000039000000000001042d0000000002000019000000000001042d000004a3002104230000000102000039000000000001042d0000000002000019000000000001042d000004a8002104250000000102000039000000000001042d0000000002000019000000000001042d000004aa00000432000004ab0001042e000004ac0001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcffffffffffffffffffffffff00000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c08c379a000000000000000000000000000000000000000000000000000000000b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610302000000000000000000000000000000000000400000000000000000000000007e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f0000000200000000000000000000000000000040000001000000000000000000ffffffff000000000000000000000000000000000000000000000000000000003659cfe6000000000000000000000000000000000000000000000000000000004f1ef286000000000000000000000000000000000000000000000000000000008f28397000000000000000000000000000000000000000000000000000000000f851a440000000000000000000000000000000000000000000000000000000005c60da1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000200000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf6464726573730000000000000000000000000000000000000000000000000000455243313936373a206e65772061646d696e20697320746865207a65726f206100000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffdf00000000000000000000000000000000000000000000002000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000006f74206120636f6e747261637400000000000000000000000000000000000000455243313936373a206e657720696d706c656d656e746174696f6e206973206e5472616e73706172656e745570677261646561626c6550726f78793a2061646d696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40000008000000000000000000000000000000000000000000000000000000020000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000007444ff0b02dc9864c7dbf97ccd7719c286d6972190eeb0285ea9e04a713977c0", - "deployedBytecode": "0x00020000000000020008000000000002000000000301001900000060033002700000012c0330019700010000003103550000008008000039000000400080043f00000001022001900000001e0000c13d000000000431034f00000000050004110000013d02000041000000000702041a0000013002700197000000000603004b000000270000c13d000000000325004b0000010c0000c13d000000000101043b0000014101100197000001420310009c0000001b0000613d000001430310009c000002c20000613d000001440310009c000002680000c13d00000000010004160000000001000019000004ac000104300000012d023000410000012e0220009c0000005f0000213d000001520100004100000000001004350000004101000039000000040010043f0000015301000041000004ac00010430000000000525004b0000012d0000c13d000000000401043b0000014104400197000001420540009c000001670000c13d0000000002000416000000000202004b000002c20000c13d000000240230008c000002c20000413d0000000401100370000000000201043b000001300120009c000002c20000213d000000a001000039000000400010043f000000800000043f00000133010000410000000000100439000800000002001d00000004002004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002a80000c13d000000400100043d00000064021000390000015403000041000000000032043500000044021000390000015503000041000000000032043500000024021000390000002d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014c011001c7000004ac000104300000009f023000390000012f02200197000000400020043f0000001f0230018f00000005043002720000006e0000613d00000000050000190000000506500210000000000761034f000000000707043b000000800660003900000000007604350000000105500039000000000645004b000000660000413d000000000502004b0000007d0000613d0000000504400210000000000141034f00000003022002100000008004400039000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000005f0130008c000002c20000a13d000000800900043d000001300190009c000002c20000213d000000a00700043d000001300170009c000002c20000213d000000c00200043d000001310120009c000002c20000213d0000001f012000390000013204000041000000000531004b000000000500001900000000050480190000013201100197000000000601004b0000000004008019000001320110009c000000000405c019000000000104004b000002c20000c13d00000080012000390000000001010433000001310410009c000000210000213d0000003f04100039000000200a00008a0000000004a4016f000000400b00043d00000000044b00190000000005b4004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d0000008003300039000000400040043f00000000061b0436000000a0022000390000000004210019000000000334004b000002c20000213d00060000000b001d00050000000a001d000700000007001d000300000008001d000000000301004b000000b90000613d000000000300001900000000046300190000000005230019000000000505043300000000005404350000002003300039000000000413004b000000b20000413d000400000006001d0000000001160019000000000001043500000133010000410000000000100439000800000009001d00000004009004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d000000080100002900000130051001970000013501000041000000000201041a0000013602200197000000000252019f000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f0000000803000029000000010120019000000007020000290000000605000029000002c20000613d0000000001050433000000000101004b000003770000c13d0000013d01000041000000000301041a0000013004200197000000400100043d0000002002100039000800000004001d0000000000420435000700000003001d000001300230019700000000002104350000012c0200004100000000030004140000012c0430009c00000000030280190000012c0410009c00000000010280190000004001100210000000c002300210000000000112019f0000013e011001c70000800d0200003900000001030000390000013f0400004104aa049b0000040f0000000101200190000002c20000613d000000080100006b0000025a0000613d0000000701000029000001360110019700000008011001af0000013d02000041000000000012041b0000002001000039000001000010044300000120000004430000014001000041000004ab0001042e0000013501000041000000000201041a00000000010004140000013002200197000000040320008c000001e90000c13d00000000030000310000001f0230018f00000005013002720000011e0000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001170000413d000000000502004b0000020e0000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f00000000002104350000020e0000013d0000001f0530018f0000013502000041000000000202041a000001300220019700000005063002720000013b0000613d00000000070000190000000508700210000000000981034f000000000909043b00000000009804350000000107700039000000000867004b000001340000413d000000000705004b000001490000613d00000003055002100000000506600210000000000706043300000000075701cf000000000757022f000000000161034f000000000101043b0000010005500089000000000151022f00000000015101cf000000000171019f00000000001604350000000001000414000000040520008c0000020f0000c13d00000000030000310000001f0230018f0000000501300272000001580000613d00000000050000190000000506500210000000000764034f000000000707043b00000000007604350000000105500039000000000615004b000001510000413d000000000502004b000002360000613d00000003022002100000000501100210000000000501043300000000052501cf000000000525022f000000000414034f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f0000000000210435000002360000013d000001430540009c0000023b0000c13d000000440230008c000002c20000413d0000000402100370000000000802043b000001300280009c000002c20000213d0000002402100370000000000402043b000001310240009c000002c20000213d00000023024000390000013205000041000000000632004b000000000600001900000000060580190000013202200197000000000702004b0000000005008019000001320220009c000000000506c019000000000205004b000002c20000c13d0000000405400039000000000251034f000000000202043b000001310620009c000000210000213d000000bf06200039000000200900008a000000000696016f000001310760009c000000210000213d000000400060043f000000800020043f00000000042400190000002404400039000000000334004b000002c20000213d0000002003500039000000000131034f0000001f0320018f00000005042002720000019d0000613d00000000050000190000000506500210000000000761034f000000000707043b000000a00660003900000000007604350000000105500039000000000645004b000001950000413d000700000009001d000000000503004b000001ad0000613d0000000504400210000000000141034f0000000303300210000000a004400039000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000140435000000a001200039000000000001043500000133010000410000000000100439000800000008001d00000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000004a0000613d0000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008030000290000000101200190000002c20000613d000000400100043d000600000001001d000001390110009c000000210000213d00000006040000290000006001400039000000400010043f00000040014000390000013a02000041000000000021043500000020014000390000013b02000041000000000021043500000027010000390000000000140435000000800200043d0000000001000414000000040330008c0000040d0000c13d000000010200003900000000040000310000041d0000013d0000012c030000410000012c0410009c0000000001038019000000c00110021004aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000001fe0000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b000001f70000413d000000000604004b0000020c0000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002640000613d000002360000013d0000012c040000410000012c0510009c0000000001048019000000c0011002100000006003300210000000000131019f04aa04a50000040f0001000000010355000000000301001900000060033002700000001f0430018f0000012c0030019d0000012c033001970000000505300272000002260000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000756004b0000021f0000413d000000000604004b000002340000613d00000003044002100000000505500210000000000605043300000000064601cf000000000646022f000000000151034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000000101200190000002660000613d0000012c010000410000012c0230009c00000000030180190000006001300210000004ab0001042e000001440540009c0000026e0000c13d0000000004000416000000000404004b000002c20000c13d000000240330008c000002c20000413d0000000401100370000000000401043b000001300140009c000002c20000213d000000800020043f000000a00040043f0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000148011001c70000800d020000390000000103000039000700000004001d0000013f04000041000800000007001d04aa049b0000040f000000070400002900000008030000290000000101200190000002c20000613d000000000104004b000002c40000c13d000000400100043d00000064021000390000014a03000041000000000032043500000044021000390000014b03000041000000000032043500000024021000390000002603000039000000530000013d0000006001300210000004ac000104300000006001300210000004ac00010430000001450310009c000002750000c13d0000000001000416000000000101004b000002c20000c13d0000027d0000013d000001450140009c000002840000c13d0000000001000416000000000101004b000002c20000c13d000000a00020043f0000028d0000013d000001460110009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013002100197000000a00020043f0000002001000039000000800010043f000000c001000039000000400010043f0000015a01000041000004ab0001042e000001460140009c0000029a0000c13d0000000001000416000000000101004b000002c20000c13d0000013501000041000000000101041a0000013001100197000000a00010043f0000002001000039000000800010043f000000c001000039000000400010043f000000800100003900000147020000410000015003000041000001500410009c000000000103801900000040011002100000015101100041000000000121019f000004ab0001042e0000013c01000041000000800010043f0000002001000039000000840010043f0000004201000039000000a40010043f0000015601000041000000c40010043f0000015701000041000000e40010043f0000015801000041000001040010043f0000015901000041000004ac000104300000013501000041000000000201041a000001360220019700000008022001af0000000805000029000000000021041b0000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000137011001c70000800d020000390000000203000039000001380400004104aa049b0000040f00000008080000290000000101200190000002c20000613d000000800100043d000000000101004b000002d00000c13d000000400100043d000001490210009c000000210000213d000002cb0000013d0000000001000019000004ac000104300000013601300197000000000114019f0000013d02000041000000000012041b000000400100043d000001490210009c000000210000213d0000002002100039000000400020043f00000000000104350000000002000019000002930000013d000000400900043d000001390190009c000000210000213d0000006001900039000000400010043f00000040019000390000013a02000041000000000021043500000020019000390000013b02000041000000000021043500000027010000390000000000190435000000800200043d0000000001000414000000040380008c000002e40000c13d00000001020000390000000004000031000002f70000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c70000000002080019000700000009001d04aa04a50000040f00000007090000290000000808000029000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b000003230000c13d0000000003030433000000000202004b000003530000c13d000000000203004b0000038c0000c13d000000400100043d0000013c0200004100000000002104350000000402100039000000200300003900000000003204350000000002090433000000240310003900000000002304350000004403100039000000000402004b000003140000613d000000000400001900000000053400190000002004400039000000000694001900000000060604330000000000650435000000000524004b0000030d0000413d0000001f04200039000000200500008a000000000454016f0000000002320019000000000002043500000044024000390000012c030000410000012c0420009c00000000020380190000012c0410009c000000000103801900000040011002100000006002200210000000000112019f000004ac00010430000001310140009c000000210000213d0000003f01400039000000200300008a000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000000a090019000000400010043f0000001f0540018f000000000143043600000001060003670000000504400272000003410000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000003390000413d000000000705004b000000080800002900000000090a0019000002fb0000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000002fb0000013d000000000103004b000002be0000c13d0000013301000041000000000010043900000004008004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000002be0000c13d000000400100043d00000044021000390000014e03000041000000000032043500000024021000390000001d0300003900000000003204350000013c0200004100000000002104350000000402100039000000200300003900000000003204350000012c020000410000012c0310009c000000000102801900000040011002100000014f011001c7000004ac00010430000000400400043d000001390140009c000000210000213d0000006001400039000000400010043f00000040014000390000013a0200004100000000002104350000002701000039000200000004001d00000000021404360000013b01000041000100000002001d000000000012043500000000020504330000000001000414000000040330008c000003950000c13d00000001020000390000000003000031000003a90000013d0000012c020000410000012c0430009c00000000030280190000012c0410009c000000000102801900000040011002100000006002300210000000000112019f000004ac000104300000012c0300004100000004050000290000012c0450009c000000000503801900000040045002100000012c0520009c00000000020380190000006002200210000000000242019f0000012c0410009c0000000001038019000000c001100210000000000112019f000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c031001970000006001000039000000000403004b000003c90000c13d0000000001010433000000000202004b000003f70000c13d000000000201004b000004830000c13d000000400400043d000800000004001d0000013c01000041000000000014043500000004014000390000002002000039000000000021043500000002010000290000000003010433000700000003001d000000240140003900000000003104350000004402400039000000010100002904aa048d0000040f00000007010000290000001f01100039000000050110017f00000044011000390000012c020000410000012c0310009c00000000010280190000000804000029000004870000013d000001310130009c0000000504000029000000210000213d0000003f01300039000000000441016f000000400100043d0000000004410019000000000514004b00000000050000190000000105004039000001310640009c000000210000213d0000000105500190000000210000c13d000000400040043f0000001f0430018f000000000931043600000001050003670000000503300272000003e60000613d000000000600001900000005076002100000000008790019000000000775034f000000000707043b00000000007804350000000106600039000000000736004b000003de0000413d000300000009001d000000000604004b000003ac0000613d0000000503300210000000000535034f00000003033000290000000304400210000000000603043300000000064601cf000000000646022f000000000505043b0000010004400089000000000545022f00000000044501cf000000000464019f0000000000430435000003ac0000013d000000000101004b00000007020000290000000803000029000000e60000c13d0000013301000041000000000010043900000004003004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b0000000702000029000000e60000c13d000003650000013d0000012c030000410000012c0410009c00000000010380190000012c0420009c00000000020380190000006002200210000000c001100210000000000121019f0000014d011001c7000000080200002904aa04a50000040f000000010220018f000100000001035500000060011002700000012c0010019d0000012c0410019700000060030000390000008001000039000000000504004b0000043e0000c13d0000000003030433000000000202004b0000046b0000c13d000000000203004b0000038c0000c13d000000400100043d0000013c02000041000000000021043500000004021000390000002003000039000000000032043500000006070000290000000002070433000000240310003900000000002304350000004403100039000000000402004b0000043b0000613d000000000400001900000000053400190000002004400039000000000674001900000000060604330000000000650435000000000524004b000004340000413d0000001f042000390000000705000029000003160000013d000001310140009c0000000703000029000000210000213d0000003f01400039000000000131016f000000400300043d0000000001130019000000000531004b00000000050000190000000105004039000001310610009c000000210000213d0000000105500190000000210000c13d000000400010043f0000001f0540018f0000000001430436000000010600036700000005044002720000045b0000613d000000000700001900000005087002100000000009810019000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000004530000413d000000000705004b000004210000613d0000000504400210000000000646034f00000000044100190000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000004210000013d000000000103004b0000047e0000c13d00000133010000410000000000100439000000080100002900000004001004430000012c0100004100000000020004140000012c0320009c0000000002018019000000c00120021000000134011001c7000080020200003904aa04a00000040f0000000102200190000004820000613d000000000101043b000000000101004b000003650000613d000000400100043d000001490210009c000000210000213d000002cb0000013d000000000001042f0000012c020000410000012c0310009c000000000102801900000003040000290000012c0340009c000000000402801900000040024002100000006001100210000000000121019f000004ac00010430000000000403004b000004970000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000534004b000004900000413d00000000012300190000000000010435000000000001042d000000000001042f0000049e002104210000000102000039000000000001042d0000000002000019000000000001042d000004a3002104230000000102000039000000000001042d0000000002000019000000000001042d000004a8002104250000000102000039000000000001042d0000000002000019000000000001042d000004aa00000432000004ab0001042e000004ac0001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009fffffffffffffffffffffffffffffffffffffffffffffffff000000000000007f00000000000000000000000000000000000000000000000000000001ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcffffffffffffffffffffffff00000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c08c379a000000000000000000000000000000000000000000000000000000000b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610302000000000000000000000000000000000000400000000000000000000000007e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f0000000200000000000000000000000000000040000001000000000000000000ffffffff000000000000000000000000000000000000000000000000000000003659cfe6000000000000000000000000000000000000000000000000000000004f1ef286000000000000000000000000000000000000000000000000000000008f28397000000000000000000000000000000000000000000000000000000000f851a440000000000000000000000000000000000000000000000000000000005c60da1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000200000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf6464726573730000000000000000000000000000000000000000000000000000455243313936373a206e65772061646d696e20697320746865207a65726f206100000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffdf00000000000000000000000000000000000000000000002000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000006f74206120636f6e747261637400000000000000000000000000000000000000455243313936373a206e657720696d706c656d656e746174696f6e206973206e5472616e73706172656e745570677261646561626c6550726f78793a2061646d696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40000008000000000000000000000000000000000000000000000000000000020000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000007444ff0b02dc9864c7dbf97ccd7719c286d6972190eeb0285ea9e04a713977c0", - "linkReferences": {}, - "deployedLinkReferences": {}, - "factoryDeps": {} -} diff --git a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol index e93d5c987..fda1c5932 100644 --- a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol +++ b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.24; +pragma solidity ^0.8.20; import {L2SharedBridge} from "../bridge/L2SharedBridge.sol"; import {L2StandardERC20} from "../bridge/L2StandardERC20.sol"; diff --git a/system-contracts/foundry.toml b/system-contracts/foundry.toml index ee3885489..06485883a 100644 --- a/system-contracts/foundry.toml +++ b/system-contracts/foundry.toml @@ -11,3 +11,4 @@ remappings = [ [profile.default.zksync] zksolc = "1.5.0" +enable_eravm_extensions = true diff --git a/system-contracts/scripts/calculate-hashes.ts b/system-contracts/scripts/calculate-hashes.ts index a8fc8036f..1b9f355a5 100644 --- a/system-contracts/scripts/calculate-hashes.ts +++ b/system-contracts/scripts/calculate-hashes.ts @@ -42,10 +42,10 @@ const findFilesEndingWith = (path: string, endingWith: string): string[] => { } }; -const SOLIDITY_ARTIFACTS_DIR = "artifacts-zk"; +const SOLIDITY_ARTIFACTS_DIR = "zkout"; const getSolidityContractDetails = (dir: string, contractName: string): ContractDetails => { - const bytecodePath = join(SOLIDITY_ARTIFACTS_DIR, dir, contractName + ".sol", contractName + ".json"); + const bytecodePath = join(SOLIDITY_ARTIFACTS_DIR, contractName + ".sol", contractName + ".json"); const sourceCodePath = join(dir, contractName + ".sol"); return { contractName, @@ -55,7 +55,7 @@ const getSolidityContractDetails = (dir: string, contractName: string): Contract }; const getSolidityContractsDetails = (dir: string): ContractDetails[] => { - const bytecodesDir = join(SOLIDITY_ARTIFACTS_DIR, dir); + const bytecodesDir = SOLIDITY_ARTIFACTS_DIR; const dirsEndingWithSol = findDirsEndingWith(bytecodesDir, ".sol"); const contractNames = dirsEndingWithSol.map((d) => d.replace(".sol", "")); const solidityContractsDetails = contractNames.map((c) => getSolidityContractDetails(dir, c)); @@ -100,7 +100,7 @@ const readBytecode = (details: ContractDetails): string => { try { if (details.bytecodePath.endsWith(".json")) { const jsonFile = fs.readFileSync(absolutePath, "utf8"); - return ethers.utils.hexlify(JSON.parse(jsonFile).bytecode); + return ethers.utils.hexlify("0x" + JSON.parse(jsonFile).bytecode.object); } else { return ethers.utils.hexlify(fs.readFileSync(absolutePath)); } diff --git a/system-contracts/scripts/preprocess-bootloader.ts b/system-contracts/scripts/preprocess-bootloader.ts index 952181455..e3dc18aaf 100644 --- a/system-contracts/scripts/preprocess-bootloader.ts +++ b/system-contracts/scripts/preprocess-bootloader.ts @@ -13,7 +13,8 @@ const preprocess = require("preprocess"); const SYSTEM_PARAMS = require("../../SystemConfig.json"); /* eslint-enable@typescript-eslint/no-var-requires */ -const OUTPUT_DIR = "bootloader/build"; +const OUTPUT_DIR_1 = "contracts-preprocessed/bootloader"; +const OUTPUT_DIR_2 = "bootloader/build"; const PREPROCCESING_MODES = ["proved_batch", "playground_batch"]; @@ -224,15 +225,32 @@ async function main() { }); const provedBootloaderWithTests = preprocess.preprocess(bootloaderWithTests, { BOOTLOADER_TYPE: "proved_batch" }); - if (!existsSync(OUTPUT_DIR)) { - mkdirSync(OUTPUT_DIR); + if (!existsSync(OUTPUT_DIR_1)) { + mkdirSync(OUTPUT_DIR_1); } - writeFileSync(`${OUTPUT_DIR}/bootloader_test.yul`, provedBootloaderWithTests); - writeFileSync(`${OUTPUT_DIR}/proved_batch.yul`, provedBatchBootloader); - writeFileSync(`${OUTPUT_DIR}/playground_batch.yul`, playgroundBatchBootloader); - writeFileSync(`${OUTPUT_DIR}/gas_test.yul`, gasTestBootloader); - writeFileSync(`${OUTPUT_DIR}/fee_estimate.yul`, feeEstimationBootloader); + if (!existsSync(OUTPUT_DIR_2)) { + mkdirSync(OUTPUT_DIR_2); + } + + const transferTest = readFileSync("bootloader/tests/transfer_test.yul").toString(); + const dummy = readFileSync("bootloader/tests/dummy.yul").toString(); + + writeFileSync(`${OUTPUT_DIR_1}/bootloader_test.yul`, provedBootloaderWithTests); + writeFileSync(`${OUTPUT_DIR_1}/proved_batch.yul`, provedBatchBootloader); + writeFileSync(`${OUTPUT_DIR_1}/playground_batch.yul`, playgroundBatchBootloader); + writeFileSync(`${OUTPUT_DIR_1}/gas_test.yul`, gasTestBootloader); + writeFileSync(`${OUTPUT_DIR_1}/fee_estimate.yul`, feeEstimationBootloader); + writeFileSync(`${OUTPUT_DIR_1}/dummy.yul`, dummy); + writeFileSync(`${OUTPUT_DIR_1}/transfer_test.yul`, transferTest); + + writeFileSync(`${OUTPUT_DIR_2}/bootloader_test.yul`, provedBootloaderWithTests); + writeFileSync(`${OUTPUT_DIR_2}/proved_batch.yul`, provedBatchBootloader); + writeFileSync(`${OUTPUT_DIR_2}/playground_batch.yul`, playgroundBatchBootloader); + writeFileSync(`${OUTPUT_DIR_2}/gas_test.yul`, gasTestBootloader); + writeFileSync(`${OUTPUT_DIR_2}/fee_estimate.yul`, feeEstimationBootloader); + writeFileSync(`${OUTPUT_DIR_2}/dummy.yul`, dummy); + writeFileSync(`${OUTPUT_DIR_2}/transfer_test.yul`, transferTest); console.log("Bootloader preprocessing done!"); }