From 8e0d098f39ad4b19c82eef42b417c3c44bc5e0c1 Mon Sep 17 00:00:00 2001 From: invocamanman Date: Tue, 28 Nov 2023 16:50:39 +0100 Subject: [PATCH] update deployment scripts --- contracts/v2/PolygonRollupManager.sol | 26 ++++- deployment/v2/3_deployContracts.ts | 2 +- deployment/v2/4_createRollup.ts | 94 +++++++++++++++---- deployment/v2/README.md | 58 ++++++------ deployment/v2/deploy_parameters.json.example | 4 +- .../scripts/v2/deploy_parameters_docker.json | 1 + hardhat.config.ts | 10 ++ 7 files changed, 144 insertions(+), 51 deletions(-) diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index f87a22c9f..9f6458742 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -956,7 +956,7 @@ contract PolygonRollupManager is /** * @notice Verify and reward batches internal function - * @param rollup Rollup Data struct that will be used to the verification + * @param rollup Rollup Data storage pointer that will be used to the verification * @param pendingStateNum Init pending state, 0 if consolidated state is used * @param initNumBatch Batch which the aggregator starts the verification * @param finalNewBatch Last batch aggregator intends to verify @@ -1085,6 +1085,7 @@ contract PolygonRollupManager is /** * @notice Allows to consolidate any pending state that has already exceed the pendingStateTimeout * Can be called by the trusted aggregator, which can consolidate any state without the timeout restrictions + * @param rollupID Rollup identifier * @param pendingStateNum Pending state to consolidate */ function consolidatePendingState( @@ -1108,6 +1109,7 @@ contract PolygonRollupManager is /** * @notice Internal function to consolidate any pending state that has already exceed the pendingStateTimeout + * @param rollup Rollup data storage pointer * @param pendingStateNum Pending state to consolidate */ function _consolidatePendingState( @@ -1689,6 +1691,8 @@ contract PolygonRollupManager is /** * @notice Returns a boolean that indicates if the pendingStateNum is or not consolidable + * @param rollupID Rollup id + * @param pendingStateNum Pending state number to check * Note that his function does not check if the pending state currently exists, or if it's consolidated already */ function isPendingStateConsolidable( @@ -1704,6 +1708,8 @@ contract PolygonRollupManager is /** * @notice Returns a boolean that indicates if the pendingStateNum is or not consolidable + * @param rollup Rollup data storage pointer + * @param pendingStateNum Pending state number to check * Note that his function does not check if the pending state currently exists, or if it's consolidated already */ function _isPendingStateConsolidable( @@ -1747,6 +1753,7 @@ contract PolygonRollupManager is /** * @notice Function to calculate the input snark bytes + * @param rollupID Rollup id used to calculate the input snark bytes * @param initNumBatch Batch which the aggregator starts the verification * @param finalNewBatch Last batch aggregator intends to verify * @param newLocalExitRoot New local exit root once the batch is processed @@ -1774,6 +1781,7 @@ contract PolygonRollupManager is /** * @notice Function to calculate the input snark bytes + * @param rollup Rollup data storage pointer * @param initNumBatch Batch which the aggregator starts the verification * @param finalNewBatch Last batch aggregator intends to verify * @param newLocalExitRoot New local exit root once the batch is processed @@ -1826,6 +1834,10 @@ contract PolygonRollupManager is ); } + /** + * @notice Function to check if the state root is inside of the prime field + * @param newStateRoot New State root once the batch is processed + */ function _checkStateRootInsidePrime( uint256 newStateRoot ) internal pure returns (bool) { @@ -1843,7 +1855,9 @@ contract PolygonRollupManager is } /** - * @notice Get the last verified batch + * @notice Get rollup state root given a batch number + * @param rollupID Rollup identifier + * @param batchNum Batch number */ function getRollupBatchNumToStateRoot( uint32 rollupID, @@ -1853,7 +1867,9 @@ contract PolygonRollupManager is } /** - * @notice Get the last verified batch + * @notice Get rollup sequence batches struct given a batch number + * @param rollupID Rollup identifier + * @param batchNum Batch number */ function getRollupSequencedBatches( uint32 rollupID, @@ -1863,7 +1879,9 @@ contract PolygonRollupManager is } /** - * @notice Get the last verified batch + * @notice Get rollup sequence pending state struct given a batch number + * @param rollupID Rollup identifier + * @param batchNum Batch number */ function getRollupPendingStateTransitions( uint32 rollupID, diff --git a/deployment/v2/3_deployContracts.ts b/deployment/v2/3_deployContracts.ts index 320871119..4d7e50a7d 100644 --- a/deployment/v2/3_deployContracts.ts +++ b/deployment/v2/3_deployContracts.ts @@ -390,7 +390,7 @@ async function main() { expect(precalculateRollupManager).to.be.equal(await polygonZkEVMGlobalExitRoot.rollupManager()); } - // deploy Rollup Managdr + // deploy Rollup Manager console.log("\n#######################"); console.log("##### Deployment Polygon ZK-EVM #####"); console.log("#######################"); diff --git a/deployment/v2/4_createRollup.ts b/deployment/v2/4_createRollup.ts index 782803eb3..b604be52b 100644 --- a/deployment/v2/4_createRollup.ts +++ b/deployment/v2/4_createRollup.ts @@ -19,7 +19,7 @@ const genesis = require("./genesis.json"); const deployOutput = require("./deploy_output.json"); import "../helpers/utils"; -import {PolygonRollupManager, PolygonZkEVMV2} from "../../typechain-types"; +import {PolygonRollupManager, PolygonZkEVMV2, PolygonZkEVMBridgeV2} from "../../typechain-types"; async function main() { /* @@ -35,6 +35,7 @@ async function main() { "chainID", "adminZkEVM", "forkID", + "consensusContract", ]; for (const parameterName of mandatoryDeploymentParameters) { @@ -43,8 +44,28 @@ async function main() { } } - const {realVerifier, trustedSequencerURL, networkName, description, trustedSequencer, chainID, adminZkEVM, forkID} = - deployParameters; + const { + realVerifier, + trustedSequencerURL, + networkName, + description, + trustedSequencer, + chainID, + adminZkEVM, + forkID, + consensusContract, + } = deployParameters; + + const supportedConensus = [ + "PolygonZkEVMEtrog", + "PolygonZkEVMV2", + "PolygonDataComittee", + "PolygonDataComitteeEtrog", + ]; + + if (!supportedConensus.includes(consensusContract)) { + throw new Error(`Consensus contract not supported, supported contracts are: ${supportedConensus}`); + } // Load provider let currentProvider = ethers.provider; @@ -115,24 +136,28 @@ async function main() { const ADD_ROLLUP_TYPE_ROLE = ethers.id("ADD_ROLLUP_TYPE_ROLE"); const CREATE_ROLLUP_ROLE = ethers.id("CREATE_ROLLUP_ROLE"); - await rollupManagerContract.grantRole(ADD_ROLLUP_TYPE_ROLE, deployer.address); - await rollupManagerContract.grantRole(CREATE_ROLLUP_ROLE, deployer.address); + // Check role: + if ((await rollupManagerContract.hasRole(ADD_ROLLUP_TYPE_ROLE, deployer.address)) == false) + await rollupManagerContract.grantRole(ADD_ROLLUP_TYPE_ROLE, deployer.address); + + if ((await rollupManagerContract.hasRole(CREATE_ROLLUP_ROLE, deployer.address)) == false) + await rollupManagerContract.grantRole(CREATE_ROLLUP_ROLE, deployer.address); - // Create zkEVM implementation - const PolygonZKEVMV2Factory = await ethers.getContractFactory("PolygonZkEVMEtrog"); - const PolygonZKEVMV2Contract = await PolygonZKEVMV2Factory.deploy( + // Create consensus implementation + const PolygonconsensusFactory = (await ethers.getContractFactory(consensusContract)) as any; + const PolygonconsensusContract = await PolygonconsensusFactory.deploy( deployOutput.polygonZkEVMGlobalExitRootAddress, deployOutput.polTokenAddress, deployOutput.polygonZkEVMBridgeAddress, deployOutput.polygonRollupManager ); - await PolygonZKEVMV2Contract.waitForDeployment(); + await PolygonconsensusContract.waitForDeployment(); // Add a new rollup type with timelock const rollupCompatibilityID = 0; await ( await rollupManagerContract.addNewRollupType( - PolygonZKEVMV2Contract.target, + PolygonconsensusContract.target, verifierContract.target, forkID, rollupCompatibilityID, @@ -147,9 +172,30 @@ async function main() { let gasTokenAddress, gasTokenNetwork, gasTokenMetadata; - if (deployParameters.gasTokenAddress && deployParameters.gasTokenAddress != "") { - gasTokenAddress = deployParameters.gasTokenAddress; - gasTokenNetwork = deployParameters.gasTokenNetwork; + if ( + deployParameters.gasTokenAddress && + deployParameters.gasTokenAddress != "" && + deployParameters.gasTokenAddress != ethers.ZeroAddress + ) { + // Get bridge instance + const bridgeFactory = await ethers.getContractFactory("PolygonZkEVMBridgeV2", deployer); + const polygonZkEVMBridgeContract = bridgeFactory.attach( + deployOutput.polygonZkEVMBridgeAddress + ) as PolygonZkEVMBridgeV2; + + // Get token metadata + gasTokenMetadata = await polygonZkEVMBridgeContract.getTokenMetadata(deployParameters.gasTokenAddress); + + const wrappedData = await polygonZkEVMBridgeContract.wrappedTokenToTokenInfo(deployParameters.gasTokenAddress); + if (wrappedData.originNetwork != 0n) { + // Wrapped token + gasTokenAddress = wrappedData.originTokenAddress; + gasTokenNetwork = wrappedData.originNetwork; + } else { + // Mainnet token + gasTokenAddress = deployParameters.gasTokenAddress; + gasTokenNetwork = 0n; + } } else { gasTokenAddress = ethers.ZeroAddress; gasTokenNetwork = 0; @@ -172,22 +218,36 @@ async function main() { networkName ); - const receipt = await txDeployRollup.wait(); + const receipt = (await txDeployRollup.wait()) as any; const timestampReceipt = (await receipt?.getBlock())?.timestamp; const rollupID = await rollupManagerContract.chainIDToRollupID(chainID); + console.log("#######################\n"); console.log("Created new Rollup:", newZKEVMAddress); // Assert admin address expect(await upgrades.erc1967.getAdminAddress(newZKEVMAddress)).to.be.equal(rollupManagerContract.target); - expect(await upgrades.erc1967.getImplementationAddress(newZKEVMAddress)).to.be.equal(PolygonZKEVMV2Contract.target); + expect(await upgrades.erc1967.getImplementationAddress(newZKEVMAddress)).to.be.equal( + PolygonconsensusContract.target + ); + + // Search added global exit root on the logs + let globalExitRoot; + for (const log of receipt?.logs) { + if (log.address == newZKEVMAddress) { + const parsedLog = PolygonconsensusFactory.interface.parseLog(log); + if (parsedLog != null && parsedLog.name == "InitialSequenceBatches") { + globalExitRoot = parsedLog.args.lastGlobalExitRoot; + } + } + } deployOutput.genesis = genesis.root; deployOutput.newZKEVMAddress = newZKEVMAddress; deployOutput.verifierAddress = verifierContract.target; // Add the first batch of the created rollup - const newZKEVMContract = (await PolygonZKEVMV2Factory.attach(newZKEVMAddress)) as PolygonZkEVMV2; + const newZKEVMContract = (await PolygonconsensusFactory.attach(newZKEVMAddress)) as PolygonZkEVMV2; const batchData = { transactions: await newZKEVMContract.generateInitializeTransaction( rollupID, @@ -195,7 +255,7 @@ async function main() { gasTokenNetwork, gasTokenMetadata as any ), - globalExitRoot: ethers.ZeroHash, + globalExitRoot: globalExitRoot, timestamp: timestampReceipt, sequencer: trustedSequencer, }; diff --git a/deployment/v2/README.md b/deployment/v2/README.md index 19bf1191a..f23ca21c3 100644 --- a/deployment/v2/README.md +++ b/deployment/v2/README.md @@ -1,7 +1,7 @@ ## Requirements -- node version: 14.x -- npm version: 7.x +- node version: 14.x +- npm version: 7.x ## Deployment @@ -55,34 +55,38 @@ A new folder will be created witth the following name `deployments/${network}_$( ## deploy-parameters.json -- `realVerifier`: bool, Indicates whether deploy a real verifier or not -- `trustedSequencerURL`: string, trustedSequencer URL -- `networkName`: string, networkName -- `version`:string, will just be emitted at initialization of the contract, usefull just for synchronizer -- `trustedSequencer`: address, trusted sequencer addresss -- `chainID`: uint64, chainID of the zkEVM -- `trustedAggregator`:address, Trusted aggregator address -- `trustedAggregatorTimeout`: uint64, If a sequence is not verified in this timeout everyone can verify it -- `pendingStateTimeout`: uint64, Once a pending state exceeds this timeout it can be consolidated -- `forkID`: uint64, Fork ID of the zkEVM, indicates the prover (zkROM/executor) version -- `admin`:address, Admin address, can adjust PolygonZkEVM parameters or stop the emergency state -- `zkEVMOwner`: address, Able to put the PolygonZkEVM into emergency state (kill switch) -- `timelockAddress`: address, Timelock owner address, able to send start an upgradability process via timelock -- `minDelayTimelock`: number, Minimum timelock delay, -- `salt`: bytes32, Salt used in `PolygonZkEVMDeployer` to deploy deterministic contracts, such as the PolygonZkEVMBridge -- `initialZkEVMDeployerOwner`: address, Initial owner of the `PolygonZkEVMDeployer` -- `maticTokenAddress`: address, Matic token address, only if deploy on testnet can be left blank and will fullfilled by the scripts. -- `zkEVMDeployerAddress`: address, Address of the `PolygonZkEVMDeployer`. Can be left blank, will be fullfilled automatically with the `deploy:deployer:ZkEVM:goerli` script. +- `timelockAdminAddress`: address, Timelock owner address, able to send start an upgradability process via timelock +- `minDelayTimelock`: number, Minimum timelock delay, +- `salt`: bytes32, Salt used in `PolygonZkEVMDeployer` to deploy deterministic contracts, such as the PolygonZkEVMBridge +- `initialZkEVMDeployerOwner`: address, Initial owner of the `PolygonZkEVMDeployer` +- `admin`:address, Admin address, can adjust RollupManager parameters or stop the emergency state +- `trustedAggregator`:address, Trusted aggregator address +- `trustedAggregatorTimeout`: uint64, If a sequence is not verified in this timeout everyone can verify it +- `pendingStateTimeout`: uint64, Once a pending state exceeds this timeout it can be consolidated +- `emergencyCouncilAddress`:address, Emergency council addres + +- `realVerifier`: bool, Indicates whether deploy a real verifier or not for the new created +- `trustedSequencerURL`: string, trustedSequencer URL +- `networkName`: string, networkName +- `description`:string, Description of the new rollup type +- `trustedSequencer`: address, trusted sequencer addresss +- `chainID`: uint64, chainID of the new rollup +- `admin`:address, Admin address, can adjust Rollup parameters +- `forkID`: uint64, Fork ID of the new rollup, indicates the prover (zkROM/executor) version +- `consensusContract`: string, Consensus contract name of the new rollup deployed, current options are: "PolygonZkEVMEtrog","PolygonZkEVMV2","PolygonDataComittee", "PolygonDataComitteeEtrog", +- `gasTokenAddress`:address, Gas token address, empty or address(0) for ether +- `polTokenAddress`: address, Matic token address, only if deploy on testnet can be left blank and will fullfilled by the scripts. +- `zkEVMDeployerAddress`: address, Address of the `PolygonZkEVMDeployer`. Can be left blank, will be fullfilled automatically with the `deploy:deployer:ZkEVM:goerli` script. ### Optional Parameters -- `deployerPvtKey`: string, pvtKey of the deployer, overrides the address in `MNEMONIC` of `.env` if exist -- `maxFeePerGas`:string, Set `maxFeePerGas`, must define aswell `maxPriorityFeePerGas` to use it -- `maxPriorityFeePerGas`:string, Set `maxPriorityFeePerGas`, must define aswell `maxFeePerGas` to use it -- `multiplierGas`: number, Gas multiplier with 3 decimals. If `maxFeePerGas` and `maxPriorityFeePerGas` are set, this will not take effect +- `deployerPvtKey`: string, pvtKey of the deployer, overrides the address in `MNEMONIC` of `.env` if exist +- `maxFeePerGas`:string, Set `maxFeePerGas`, must define aswell `maxPriorityFeePerGas` to use it +- `maxPriorityFeePerGas`:string, Set `maxPriorityFeePerGas`, must define aswell `maxFeePerGas` to use it +- `multiplierGas`: number, Gas multiplier with 3 decimals. If `maxFeePerGas` and `maxPriorityFeePerGas` are set, this will not take effect ## Notes -- Since there are deterministic address you cannot deploy twice on the same network using the same `salt` and `initialZkEVMDeployerOwner`. Changing one of them is enough to make a new deployment. -- It's mandatory to delete the `.openzeppelin` upgradebility information in order to make a new deployment -- `genesis.json` has been generated using the tool: `1_createGenesis`, this script depends on the `deploy_parameters` aswell. +- Since there are deterministic address you cannot deploy twice on the same network using the same `salt` and `initialZkEVMDeployerOwner`. Changing one of them is enough to make a new deployment. +- It's mandatory to delete the `.openzeppelin` upgradebility information in order to make a new deployment +- `genesis.json` has been generated using the tool: `1_createGenesis`, this script depends on the `deploy_parameters` aswell. diff --git a/deployment/v2/deploy_parameters.json.example b/deployment/v2/deploy_parameters.json.example index 522ff3b2e..b2f242a80 100644 --- a/deployment/v2/deploy_parameters.json.example +++ b/deployment/v2/deploy_parameters.json.example @@ -16,10 +16,10 @@ "chainID": 1001, "adminZkEVM":"0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D", "forkID": 1, + "consensusContract": "PolygonZkEVMEtrog", + "gasTokenAddress":"", "polTokenAddress":"0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D", "zkEVMDeployerAddress":"", - "gasTokenAddress":"", - "gasTokenNetwork":0, "deployerPvtKey": "", "maxFeePerGas":"", "maxPriorityFeePerGas":"", diff --git a/docker/scripts/v2/deploy_parameters_docker.json b/docker/scripts/v2/deploy_parameters_docker.json index 0eff58791..3ec40a7c6 100644 --- a/docker/scripts/v2/deploy_parameters_docker.json +++ b/docker/scripts/v2/deploy_parameters_docker.json @@ -16,6 +16,7 @@ "chainID": 1001, "adminZkEVM": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "forkID": 5, + "consensusContract": "PolygonZkEVMEtrog", "polTokenAddress": "", "zkEVMDeployerAddress": "", "gasTokenAddress": "", diff --git a/hardhat.config.ts b/hardhat.config.ts index 01386d93c..acf6360a0 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -105,6 +105,16 @@ const config: HardhatUserConfig = { evmVersion: "shanghai", }, }, + "contracts/v2/mocks/PolygonRollupManagerMockInternalTest.sol": { + version: "0.8.20", + settings: { + optimizer: { + enabled: true, + runs: 99, + }, + evmVersion: "shanghai", + }, // try yul optimizer + }, "contracts/v2/mocks/PolygonRollupManagerMock.sol": { version: "0.8.20", settings: {