From a26c598d6b96c02c154b45db7235e6e62699e885 Mon Sep 17 00:00:00 2001 From: Cherkaso8 <136514171+Cherkaso8@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:05:23 +0300 Subject: [PATCH 1/3] Upgrade hardhat.config.ts Common parameters for networks are entered in the createNetworkConfig function, which automatically builds the configuration for each network. This eliminates duplication. All compilers use the same optimizer setting (for most contracts). This is submitted to the COMPILER_SETTINGS constant. Account configuration is now stored in one ACCOUNTS_CONFIG object, which is used for all networks. Flexibility is applied through the use of the INFURA_URL variable, which makes it easy to change the URL for providers without having to copy the same code --- hardhat.config.ts | 247 ++++++++++++---------------------------------- 1 file changed, 62 insertions(+), 185 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 17f2358f1..facbbf009 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -3,18 +3,37 @@ import "@nomicfoundation/hardhat-toolbox"; import "@openzeppelin/hardhat-upgrades"; import "hardhat-dependency-compiler"; -import {HardhatUserConfig} from "hardhat/config"; +import { HardhatUserConfig } from "hardhat/config"; const DEFAULT_MNEMONIC = "test test test test test test test test test test test junk"; +const INFURA_URL = `https://{network}.infura.io/v3/${process.env.INFURA_PROJECT_ID}`; +const MNEMONIC = process.env.MNEMONIC || DEFAULT_MNEMONIC; +const ACCOUNTS_CONFIG = { + mnemonic: MNEMONIC, + path: "m/44'/60'/0'/0", + initialIndex: 0, + count: 20, +}; + +const COMPILER_SETTINGS = { + optimizer: { + enabled: true, + runs: 999999, + }, +}; -/* - * You need to export an object to set up your config - * Go to https://hardhat.org/config/ to learn more - */ +const COMPILER_VERSIONS = [ + "0.8.17", + "0.8.20", + "0.6.11", + "0.5.12", + "0.5.16" +]; -/** - * @type import('hardhat/config').HardhatUserConfig - */ +const createNetworkConfig = (network: string, providerUrl?: string) => ({ + url: process.env[`${network.toUpperCase()}_PROVIDER`] || providerUrl.replace("{network}", network), + accounts: ACCOUNTS_CONFIG, +}); const config: HardhatUserConfig = { dependencyCompiler: { @@ -22,225 +41,83 @@ const config: HardhatUserConfig = { "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol", "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol", "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol", - ], // , - // keep: true + ], }, solidity: { - compilers: [ - { - version: "0.8.17", - settings: { - optimizer: { - enabled: true, - runs: 999999, - }, - }, - }, - { - version: "0.8.20", - settings: { - optimizer: { - enabled: true, - runs: 999999, - }, - evmVersion: "shanghai", - }, - }, - { - version: "0.6.11", - settings: { - optimizer: { - enabled: true, - runs: 999999, - }, - }, - }, - { - version: "0.5.12", - settings: { - optimizer: { - enabled: true, - runs: 999999, - }, - }, - }, - { - version: "0.5.16", - settings: { - optimizer: { - enabled: true, - runs: 999999, - }, - }, - }, - ], + compilers: COMPILER_VERSIONS.map(version => ({ + version, + settings: COMPILER_SETTINGS, + })), overrides: { "contracts/v2/PolygonRollupManager.sol": { version: "0.8.20", settings: { - optimizer: { - enabled: true, - runs: 500, - }, + ...COMPILER_SETTINGS, + runs: 500, evmVersion: "shanghai", - }, // try yul optimizer + }, }, "contracts/v2/PolygonZkEVMBridgeV2.sol": { version: "0.8.20", settings: { - optimizer: { - enabled: true, - runs: 999, - }, + ...COMPILER_SETTINGS, + runs: 999, evmVersion: "shanghai", }, }, "contracts/v2/newDeployments/PolygonRollupManagerNotUpgraded.sol": { version: "0.8.20", settings: { - optimizer: { - enabled: true, - runs: 500, - }, + ...COMPILER_SETTINGS, + runs: 500, evmVersion: "shanghai", - }, // try yul optimizer + }, }, "contracts/v2/mocks/PolygonRollupManagerMock.sol": { version: "0.8.20", settings: { - optimizer: { - enabled: true, - runs: 10, - }, + optimizer: { enabled: true, runs: 10 }, evmVersion: "shanghai", - }, // try yul optimizer + }, }, - // Should have the same optimizations than the RollupManager to verify "contracts/v2/lib/PolygonTransparentProxy.sol": { version: "0.8.20", settings: { - optimizer: { - enabled: true, - runs: 500, - }, + ...COMPILER_SETTINGS, + runs: 500, evmVersion: "shanghai", - }, // try yul optimizer + }, }, "contracts/v2/utils/ClaimCompressor.sol": { version: "0.8.20", settings: { - optimizer: { - enabled: true, - runs: 999999, - }, + ...COMPILER_SETTINGS, evmVersion: "shanghai", - //viaIR: true, }, }, }, }, networks: { - mainnet: { - url: process.env.MAINNET_PROVIDER - ? process.env.MAINNET_PROVIDER - : `https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - ropsten: { - url: process.env.ROPSTEN_PROVIDER - ? process.env.ROPSTEN_PROVIDER - : `https://ropsten.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - goerli: { - url: process.env.GOERLI_PROVIDER - ? process.env.GOERLI_PROVIDER - : `https://goerli.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - rinkeby: { - url: process.env.RINKEBY_PROVIDER - ? process.env.RINKEBY_PROVIDER - : `https://rinkeby.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - sepolia: { - url: process.env.SEPOLIA_PROVIDER - ? process.env.SEPOLIA_PROVIDER - : `https://sepolia.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, + mainnet: createNetworkConfig('mainnet', INFURA_URL), + ropsten: createNetworkConfig('ropsten', INFURA_URL), + goerli: createNetworkConfig('goerli', INFURA_URL), + rinkeby: createNetworkConfig('rinkeby', INFURA_URL), + sepolia: createNetworkConfig('sepolia', INFURA_URL), localhost: { url: "http://127.0.0.1:8545", - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, + accounts: ACCOUNTS_CONFIG, }, hardhat: { initialDate: "0", allowUnlimitedContractSize: true, initialBaseFeePerGas: 0, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - polygonZKEVMTestnet: { - url: "https://rpc.cardona.zkevm-rpc.com", - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - polygonZKEVMMainnet: { - url: "https://zkevm-rpc.com", - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, + accounts: ACCOUNTS_CONFIG, }, + polygonZKEVMTestnet: createNetworkConfig('polygonZKEVMTestnet', "https://rpc.cardona.zkevm-rpc.com"), + polygonZKEVMMainnet: createNetworkConfig('polygonZKEVMMainnet', "https://zkevm-rpc.com"), zkevmDevnet: { url: "http://123:123:123:123:123", - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, + accounts: ACCOUNTS_CONFIG, }, }, gasReporter: { @@ -250,12 +127,12 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: { - polygonZKEVMTestnet: `${process.env.ETHERSCAN_ZKEVM_API_KEY}`, - polygonZKEVMMainnet: `${process.env.ETHERSCAN_ZKEVM_API_KEY}`, - goerli: `${process.env.ETHERSCAN_API_KEY}`, - sepolia: `${process.env.ETHERSCAN_API_KEY}`, - mainnet: `${process.env.ETHERSCAN_API_KEY}`, - zkevmDevnet: `${process.env.ETHERSCAN_API_KEY}`, + polygonZKEVMTestnet: process.env.ETHERSCAN_ZKEVM_API_KEY, + polygonZKEVMMainnet: process.env.ETHERSCAN_ZKEVM_API_KEY, + goerli: process.env.ETHERSCAN_API_KEY, + sepolia: process.env.ETHERSCAN_API_KEY, + mainnet: process.env.ETHERSCAN_API_KEY, + zkevmDevnet: process.env.ETHERSCAN_API_KEY, }, customChains: [ { From 6d15d52d053fd56682ef1d8d72aca21d1eb4610f Mon Sep 17 00:00:00 2001 From: Cherkaso8 <136514171+Cherkaso8@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:24:24 +0300 Subject: [PATCH 2/3] Upgrade verifyMainnetDeployment.js Instead of prescribing the path to artifacts for each contract every time, I created an artifactsPath object that stores the path to all the necessary files. This makes it easy to control and change paths in one place. To improve readability and reduce repeating code, I have taken repeated actions into separate functions Renamed some variables to improve code readability Excess or non-informative comments have also been removed, for example, indications of the location of files that are now processed automatically. --------------------------------------------------- there were typos in the original contract if you decide to leave it: conracts - contracts, btyecode - bytecode "deployMainnet.polygonZkEVMBridgeAddress" and other proxy addresses are checked several times. It is better to check each address specifically in the context of his contract to avoid confusion. Printout:"polygonZkEVMGlobalImpl" must be "polygonZkEVMGlobalExitRootImpl" so that the variable name matches the content. and few more --- .../verifyMainnetDeployment.js | 324 ++++++++---------- 1 file changed, 144 insertions(+), 180 deletions(-) diff --git a/verifyMainnetDeployment/verifyMainnetDeployment.js b/verifyMainnetDeployment/verifyMainnetDeployment.js index 0b7dc7b28..a7ce17fbd 100644 --- a/verifyMainnetDeployment/verifyMainnetDeployment.js +++ b/verifyMainnetDeployment/verifyMainnetDeployment.js @@ -7,189 +7,153 @@ const { expect } = require('chai'); const deployMainnet = require("./mainnetDeployment.json"); const mainnetDeployParameters = require("./mainnetDeployParameters.json"); -const pathFflonkVerifier = '../artifacts/contracts/verifiers/FflonkVerifier.sol/FflonkVerifier.json'; -const pathPolygonZkEVMDeployer = '../artifacts/contracts/deployment/PolygonZkEVMDeployer.sol/PolygonZkEVMDeployer.json'; -const pathPolygonZkEVMBridge = '../artifacts/contracts/PolygonZkEVMBridge.sol/PolygonZkEVMBridge.json'; -const pathTransparentProxyOZUpgradeDep = '../node_modules/@openzeppelin/upgrades-core/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json'; -const pathProxyAdmin = '../artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json'; -const pathTransparentProxy = '../artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json'; -const pathPolygonZkEVMTimelock = '../artifacts/contracts/PolygonZkEVMTimelock.sol/PolygonZkEVMTimelock.json'; -const pathPolygonZkEVM = '../artifacts/contracts/PolygonZkEVM.sol/PolygonZkEVM.json'; -const pathPolygonZkEVMGlobalExitRoot = '../artifacts/contracts/PolygonZkEVMGlobalExitRoot.sol/PolygonZkEVMGlobalExitRoot.json'; - -const FflonkVerifier = require(pathFflonkVerifier); -const PolygonZkEVMDeployer = require(pathPolygonZkEVMDeployer); -const PolygonZkEVMBridge = require(pathPolygonZkEVMBridge); -const TransparentProxyOZUpgradeDep = require(pathTransparentProxyOZUpgradeDep); -const ProxyAdmin = require(pathProxyAdmin); -const TransparentProxy = require(pathTransparentProxy); - - -const etherscanURL = "https://etherscan.io/address/" +const artifactsPath = { + fflonkVerifier: '../artifacts/contracts/verifiers/FflonkVerifier.sol/FflonkVerifier.json', + polygonZkEVMDeployer: '../artifacts/contracts/deployment/PolygonZkEVMDeployer.sol/PolygonZkEVMDeployer.json', + polygonZkEVMBridge: '../artifacts/contracts/PolygonZkEVMBridge.sol/PolygonZkEVMBridge.json', + transparentProxyOZUpgradeDep: '../node_modules/@openzeppelin/upgrades-core/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json', + proxyAdmin: '../artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json', + transparentProxy: '../artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json', + polygonZkEVMTimelock: '../artifacts/contracts/PolygonZkEVMTimelock.sol/PolygonZkEVMTimelock.json', + polygonZkEVM: '../artifacts/contracts/PolygonZkEVM.sol/PolygonZkEVM.json', + polygonZkEVMGlobalExitRoot: '../artifacts/contracts/PolygonZkEVMGlobalExitRoot.sol/PolygonZkEVMGlobalExitRoot.json' +}; + +// Load contract artifacts +const FflonkVerifier = require(artifactsPath.fflonkVerifier); +const PolygonZkEVMDeployer = require(artifactsPath.polygonZkEVMDeployer); +const PolygonZkEVMBridge = require(artifactsPath.polygonZkEVMBridge); +const TransparentProxyOZUpgradeDep = require(artifactsPath.transparentProxyOZUpgradeDep); +const ProxyAdmin = require(artifactsPath.proxyAdmin); +const TransparentProxy = require(artifactsPath.transparentProxy); + +const etherscanURL = "https://etherscan.io/address/"; + async function main() { - // First verify not immutable conracts - const mainnetProvider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}`); - - // FflonkVerifier - expect(await mainnetProvider.getCode(deployMainnet.fflonkVerifierAddress)) - .to.be.equal(FflonkVerifier.deployedBytecode); - console.log("FflonkVerifier was correctly verified") - console.log("Etherscan URL: ", etherscanURL + deployMainnet.fflonkVerifierAddress) - console.log("Path file: ", path.join(__dirname, pathFflonkVerifier)); - console.log(); - - // PolygonZkEVMDeployer - expect(await mainnetProvider.getCode(deployMainnet.polygonZkEVMDeployerAddress)) - .to.be.equal(PolygonZkEVMDeployer.deployedBytecode); - console.log("PolygonZkEVMDeployer was correctly verified") - console.log("Etherscan URL: ", etherscanURL + deployMainnet.polygonZkEVMDeployerAddress) - console.log("Path file: ", path.join(__dirname, pathPolygonZkEVMDeployer)); - console.log(); - - // Bridge - // Since this contract is a proxy, we will need to verify the implementation - const polygonZkEVMBridgeImpl = await getImplementationAddress(deployMainnet.polygonZkEVMBridgeAddress, mainnetProvider) - - expect(await mainnetProvider.getCode(polygonZkEVMBridgeImpl)) - .to.be.equal(PolygonZkEVMBridge.deployedBytecode); - console.log("PolygonZkEVMBridgeAddress implementation was correctly verified") - console.log("Etherscan URL: ", etherscanURL + polygonZkEVMBridgeImpl) - console.log("Path file: ", path.join(__dirname, pathPolygonZkEVMBridge)); - console.log(); - - // Check transparent Proxys - expect(await mainnetProvider.getCode(deployMainnet.polygonZkEVMBridgeAddress)) - .to.be.equal(TransparentProxy.deployedBytecode); - console.log("PolygonZkEVMBridgeAddress proxy was correctly verified") - console.log("Etherscan URL: ", etherscanURL + deployMainnet.polygonZkEVMBridgeAddress); - console.log("Path file: ", path.join(__dirname, pathTransparentProxy)); - console.log(); - - // The other 3 contracts are immutables, therefore we will deploy them locally and check the btyecode against the deployed one - - // PolygonZkEVMTimelock - const PolygonZkEVMTimelockFactory = await ethers.getContractFactory('PolygonZkEVMTimelock'); - const timelockAddress = mainnetDeployParameters.timelockAddress; //not relevant to deployed bytecode - const minDelayTimelock = mainnetDeployParameters.minDelayTimelock; //not relevant to deployed bytecode - - const PolygonZkEVMTimelock = await PolygonZkEVMTimelockFactory.deploy( - minDelayTimelock, - [timelockAddress], - [timelockAddress], - timelockAddress, - deployMainnet.polygonZkEVMAddress, - ); - PolygonZkEVMTimelock.deployed() - - const deployedBytecodePolygonZkEVMTimelock = await ethers.provider.getCode(PolygonZkEVMTimelock.address); - expect(await mainnetProvider.getCode(deployMainnet.polygonZkEVMTimelockAddress)) - .to.be.equal(deployedBytecodePolygonZkEVMTimelock); - console.log("Timelock was correctly verified") - console.log("Etherscan URL: ", etherscanURL + deployMainnet.polygonZkEVMTimelockAddress); - console.log("Path file: ", path.join(__dirname, pathPolygonZkEVMTimelock)); - console.log(); - - // polygonZkEVMGlobalExitRoot - const PolygonZkEVMGlobalExitRootFactory = await ethers.getContractFactory('PolygonZkEVMGlobalExitRoot'); - const polygonZkEVMGlobalExitRoot = await PolygonZkEVMGlobalExitRootFactory.deploy( - deployMainnet.polygonZkEVMAddress, - deployMainnet.polygonZkEVMBridgeAddress - ); - polygonZkEVMGlobalExitRoot.deployed() - - const deployedBytecodeGlobalExitRoot = await ethers.provider.getCode(polygonZkEVMGlobalExitRoot.address); - const polygonZkEVMGlobalImpl = await getImplementationAddress(deployMainnet.polygonZkEVMGlobalExitRootAddress, mainnetProvider) - - expect(await mainnetProvider.getCode(polygonZkEVMGlobalImpl)) - .to.be.equal(deployedBytecodeGlobalExitRoot); - console.log("PolygonZkEVMGlobalExitRoot implementation was correctly verified") - console.log("Etherscan URL: ", etherscanURL + polygonZkEVMGlobalImpl); - console.log("Path file: ", path.join(__dirname, pathPolygonZkEVMGlobalExitRoot)); - console.log(); - - // Check transparent Proxys - expect(await mainnetProvider.getCode(deployMainnet.polygonZkEVMGlobalExitRootAddress)) - .to.be.equal(TransparentProxyOZUpgradeDep.deployedBytecode); - console.log("PolygonZkEVMGlobalExitRoot proxy was correctly verified") - console.log("Etherscan URL: ", etherscanURL + deployMainnet.polygonZkEVMGlobalExitRootAddress); - console.log("Path file: ", path.join(__dirname, pathTransparentProxyOZUpgradeDep)); - console.log(); - - // PolygonZkEVM - const mainnetChainID = mainnetDeployParameters.chainID; - const mainnetForkID = mainnetDeployParameters.forkID; - const maticAddress = mainnetDeployParameters.maticTokenAddress; - - const PolygonZkEVMFactory = await ethers.getContractFactory('PolygonZkEVM'); - const polygonZkEVMContract = await PolygonZkEVMFactory.deploy( - deployMainnet.polygonZkEVMGlobalExitRootAddress, - maticAddress, - deployMainnet.fflonkVerifierAddress, - deployMainnet.polygonZkEVMBridgeAddress, - mainnetChainID, - mainnetForkID, - ); - polygonZkEVMContract.deployed() - - const deployedBytecodePolygonZkEVM = await ethers.provider.getCode(polygonZkEVMContract.address); - const polygonZkEVMImpl = await getImplementationAddress(deployMainnet.polygonZkEVMAddress, mainnetProvider) - - expect(await mainnetProvider.getCode(polygonZkEVMImpl)) - .to.be.equal(deployedBytecodePolygonZkEVM); - console.log("PolygonZkEVMAddress implementation was correctly verified") - console.log("Etherscan URL: ", etherscanURL + polygonZkEVMImpl); - console.log("Path file: ", path.join(__dirname, pathPolygonZkEVM)); - console.log(); - - // Check transparent Proxys - expect(await mainnetProvider.getCode(deployMainnet.polygonZkEVMAddress)) - .to.be.equal(TransparentProxyOZUpgradeDep.deployedBytecode); - console.log("PolygonZkEVMAddress proxy was correctly verified") - console.log("Etherscan URL: ", etherscanURL + deployMainnet.polygonZkEVMAddress); - console.log("Path file: ", path.join(__dirname, pathTransparentProxyOZUpgradeDep)); - console.log(); - - // Check proxy Admin - const polygonZkEVMBridgeAdmin = await getProxyAdminAddress(deployMainnet.polygonZkEVMBridgeAddress, mainnetProvider); - const polygonZkEVMAdmin = await getProxyAdminAddress(deployMainnet.polygonZkEVMAddress, mainnetProvider); - const polygonZkEVMGlobalExitRootAdmin = await getProxyAdminAddress(deployMainnet.polygonZkEVMGlobalExitRootAddress, mainnetProvider); - - expect(polygonZkEVMBridgeAdmin).to.be.equal(polygonZkEVMAdmin); - expect(polygonZkEVMAdmin).to.be.equal(polygonZkEVMGlobalExitRootAdmin); - expect(await mainnetProvider.getCode(polygonZkEVMAdmin)) - .to.be.equal(ProxyAdmin.deployedBytecode); - console.log("ProxyAdmin proxy was correctly verified") - console.log("Etherscan URL: ", etherscanURL + polygonZkEVMAdmin); - console.log("Path file: ", path.join(__dirname, pathProxyAdmin)); - console.log(); - - // Assert genesis is the same as the provided in the document - let mainnetPolygonZkVEM = (await ethers.getContractFactory('PolygonZkEVM', mainnetProvider)).attach(deployMainnet.polygonZkEVMAddress); - mainnetPolygonZkVEM = mainnetPolygonZkVEM.connect(mainnetProvider); - expect(await mainnetPolygonZkVEM.batchNumToStateRoot(0)).to.be.equal(deployMainnet.genesisRoot); - console.log("Genesis root was correctly verified:",deployMainnet.genesisRoot) + const mainnetProvider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}`); + + // Verify contracts + await verifyContract(mainnetProvider, deployMainnet.fflonkVerifierAddress, FflonkVerifier, 'FflonkVerifier'); + await verifyContract(mainnetProvider, deployMainnet.polygonZkEVMDeployerAddress, PolygonZkEVMDeployer, 'PolygonZkEVMDeployer'); + + // Verify Bridge implementation + const polygonZkEVMBridgeImpl = await getImplementationAddress(deployMainnet.polygonZkEVMBridgeAddress, mainnetProvider); + await verifyImplementation(mainnetProvider, polygonZkEVMBridgeImpl, PolygonZkEVMBridge, 'PolygonZkEVMBridge', deployMainnet.polygonZkEVMBridgeAddress); + + // Verify Transparent Proxies + await verifyProxy(mainnetProvider, deployMainnet.polygonZkEVMBridgeAddress, TransparentProxy, 'PolygonZkEVMBridgeAddress proxy'); + + // Verify Timelock contract + await verifyTimelockContract(mainnetProvider); + + // Verify Global Exit Root contract + await verifyGlobalExitRootContract(mainnetProvider); + // Verify PolygonZkEVM contract + await verifyPolygonZkEVMContract(mainnetProvider); + + // Verify Proxy Admin contract + await verifyProxyAdmin(mainnetProvider); + + // Verify Genesis root + await verifyGenesisRoot(mainnetProvider); + + console.log("Verification complete!"); } -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); - -// bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; -// bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; -const adminSlot = "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"; -const implSlot = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - -async function getImplementationAddress(proxyAddress, provider) { - const implementationAddress = await provider.getStorageAt(proxyAddress, implSlot); - return `0x${implementationAddress.slice(2 + (32 * 2 - 40))}` + +async function verifyContract(provider, contractAddress, contractArtifact, name) { + expect(await provider.getCode(contractAddress)).to.be.equal(contractArtifact.deployedBytecode); + console.log(`${name} was correctly verified`); + console.log(`Etherscan URL: ${etherscanURL}${contractAddress}`); + console.log(`Path file: ${path.join(__dirname, artifactsPath[name.toLowerCase()])}`); + console.log(); } -async function getProxyAdminAddress(proxyAddress, provider) { - const adminAddress = await provider.getStorageAt(proxyAddress, adminSlot); - return `0x${adminAddress.slice(2 + (32 * 2 - 40))}` +async function verifyImplementation(provider, implAddress, contractArtifact, name, contractAddress) { + expect(await provider.getCode(implAddress)).to.be.equal(contractArtifact.deployedBytecode); + console.log(`${name} implementation was correctly verified`); + console.log(`Etherscan URL: ${etherscanURL}${implAddress}`); + console.log(`Path file: ${path.join(__dirname, artifactsPath[name.toLowerCase()])}`); + console.log(); } + +async function verifyProxy(provider, proxyAddress, proxyArtifact, name) { + expect(await provider.getCode(proxyAddress)).to.be.equal(proxyArtifact.deployedBytecode); + console.log(`${name} was correctly verified`); + console.log(`Etherscan URL: ${etherscanURL}${proxyAddress}`); + console.log(`Path file: ${path.join(__dirname, artifactsPath.transparentProxy)}`); + console.log(); +} + +async function verifyTimelockContract(provider) { + const PolygonZkEVMTimelockFactory = await ethers.getContractFactory('PolygonZkEVMTimelock'); + const timelockAddress = mainnetDeployParameters.timelockAddress; + const minDelayTimelock = mainnetDeployParameters.minDelayTimelock; + + const timelockContract = await PolygonZkEVMTimelockFactory.deploy( + minDelayTimelock, + [timelockAddress], + [timelockAddress], + timelockAddress, + deployMainnet.polygonZkEVMAddress, + ); + await timelockContract.deployed(); + + const deployedBytecodeTimelock = await ethers.provider.getCode(timelockContract.address); + expect(await provider.getCode(deployMainnet.polygonZkEVMTimelockAddress)).to.be.equal(deployedBytecodeTimelock); + console.log("Timelock contract was correctly verified"); + console.log(`Etherscan URL: ${etherscanURL}${deployMainnet.polygonZkEVMTimelockAddress}`); + console.log(`Path file: ${path.join(__dirname, artifactsPath.polygonZkEVMTimelock)}`); + console.log(); +} + +async function verifyGlobalExitRootContract(provider) { + const PolygonZkEVMGlobalExitRootFactory = await ethers.getContractFactory('PolygonZkEVMGlobalExitRoot'); + const globalExitRootContract = await PolygonZkEVMGlobalExitRootFactory.deploy( + deployMainnet.polygonZkEVMAddress, + deployMainnet.polygonZkEVMBridgeAddress + ); + await globalExitRootContract.deployed(); + + const deployedBytecodeGlobalExitRoot = await ethers.provider.getCode(globalExitRootContract.address); + const globalExitRootImpl = await getImplementationAddress(deployMainnet.polygonZkEVMGlobalExitRootAddress, provider); + + expect(await provider.getCode(globalExitRootImpl)).to.be.equal(deployedBytecodeGlobalExitRoot); + console.log("Global Exit Root contract implementation was correctly verified"); + console.log(`Etherscan URL: ${etherscanURL}${globalExitRootImpl}`); + console.log(`Path file: ${path.join(__dirname, artifactsPath.polygonZkEVMGlobalExitRoot)}`); + console.log(); +} + +async function verifyPolygonZkEVMContract(provider) { + const PolygonZkEVMFactory = await ethers.getContractFactory('PolygonZkEVM'); + const polygonZkEVMContract = await PolygonZkEVMFactory.deploy( + deployMainnet.polygonZkEVMGlobalExitRootAddress, + mainnetDeployParameters.maticTokenAddress, + deployMainnet.fflonkVerifierAddress, + deployMainnet.polygonZkEVMBridgeAddress, + mainnetDeployParameters.chainID, + mainnetDeployParameters.forkID, + ); + await polygonZkEVMContract.deployed(); + + const deployedBytecodePolygonZkEVM = await ethers.provider.getCode(polygonZkEVMContract.address); + const polygonZkEVMImpl = await getImplementationAddress(deployMainnet.polygonZkEVMAddress, provider); + + expect(await provider.getCode(polygonZkEVMImpl)).to.be.equal(deployedBytecodePolygonZkEVM); + console.log("PolygonZkEVM contract implementation was correctly verified"); + console.log(`Etherscan URL: ${etherscanURL}${polygonZkEVMImpl}`); + console.log(`Path file: ${path.join(__dirname, artifactsPath.polygonZkEVM)}`); + console.log(); +} + +async function verifyProxyAdmin(provider) { + const proxyAdminAddress = await getProxyAdminAddress(deployMainnet.polygonZkEVMBridgeAddress, provider); + const polygonZkEVMAdmin = await getProxyAdminAddress(deployMainnet.polygonZkEVMAddress, provider); + const globalExitRootAdmin = await getProxyAdminAddress(deployMainnet.polygonZkEVMGlobalExitRootAddress, provider); + + expect(proxyAdminAddress).to.be.equal(polygonZkEVMAdmin); + expect(polygonZkEVMAdmin).to.be.equal(globalExitRootAdmin); + expect(await provider.getCode(polygonZkEVMAdmin)).to.be.equal(ProxyAdmin.deployedBytecode); + + console.log(" From 64b3d355fc4c9d28196dcb9f5c7c239f7b1b9d38 Mon Sep 17 00:00:00 2001 From: Cherkaso8 <136514171+Cherkaso8@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:33:49 +0300 Subject: [PATCH 3/3] Typos verifyTestnetProofVerifier.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed typos lets - let’s
Tweeking - Tweaking exactlly - exactly transacction - transaction bycode - bytecode --- verifyMainnetDeployment/verifyTestnetProofVerifier.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/verifyMainnetDeployment/verifyTestnetProofVerifier.md b/verifyMainnetDeployment/verifyTestnetProofVerifier.md index bf402ca25..10c909908 100644 --- a/verifyMainnetDeployment/verifyTestnetProofVerifier.md +++ b/verifyMainnetDeployment/verifyTestnetProofVerifier.md @@ -4,7 +4,7 @@ In order to verify the smart contract, you will need a machine with at least 256 In this tutorial we will give instructions for a r6a.8xlarge aws instance. This instance has 16 cores 32 threads, 512GB of SSD. The instance will use Ubuntu 22.04 LTS and the cost of the instance is about 1.82 $/h. This process is quite long, it takes approximately 5-6 hours. -So lets start by launching and instance. +So let's start by launching and instance. ## Basic OS preparation @@ -13,7 +13,7 @@ sudo apt update sudo apt install -y tmux git curl jq ``` -## Tweeking the OS to accept high amount of memory. +## Tweaking the OS to accept high amount of memory. ```bash echo "vm.max_map_count=655300" | sudo tee -a /etc/sysctl.conf @@ -104,7 +104,7 @@ npm install hardhat mkdir -p contracts/verifiers ``` -To generate the same bycode it's important recover exactlly same options used during compilation, we found this information with contract information on etherscan (Settings). +To generate the same bytecode it's important recover exactly same options used during compilation, we found this information with contract information on etherscan (Settings). Copy this information inside the file ~/contract/settings.json, as follows: ```bash @@ -212,7 +212,7 @@ To download bytecode of deployed smartcontract, need the address of smart contra Go to Etherscan or Beaconcha to get transaction bytecode. -Associated with address _0x8d0aAd785905c5c9f942CB18a3AC1e50c4F52786_ found the transacction _0xed0f103dc5e5f5bb8aa5df90a2bfb1949ad41dec8b04e5acc0747dbc1c26e837_. +Associated with address _0x8d0aAd785905c5c9f942CB18a3AC1e50c4F52786_ found the transaction _0xed0f103dc5e5f5bb8aa5df90a2bfb1949ad41dec8b04e5acc0747dbc1c26e837_. - ### Etherscan (https://sepolia.etherscan.io)