From 0ff922dadd0d8686c9487471a6f70fd2837bb659 Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:15:37 +0200 Subject: [PATCH] chore(upgrade-tool): Extend upgrade tool to work with new governance (#507) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Extends upgrade tool to be able to work with new governance. Tool was tested locally. ## Why ❔ New governance mechanism is being introduced. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zk fmt` and `zk lint`. --- infrastructure/protocol-upgrade/README.md | 6 +- .../protocol-upgrade/src/transaction.ts | 207 +++++++++++++----- 2 files changed, 163 insertions(+), 50 deletions(-) diff --git a/infrastructure/protocol-upgrade/README.md b/infrastructure/protocol-upgrade/README.md index 595bea8a84f6..6636dff8b0ff 100644 --- a/infrastructure/protocol-upgrade/README.md +++ b/infrastructure/protocol-upgrade/README.md @@ -213,7 +213,8 @@ $ zk f yarn start transactions build-default \ --l2-upgrader-address \ --diamond-upgrade-proposal-id \ --l1rpc \ ---zksync-address +--zksync-address \ +--use-new-governance ``` To execute the `proposeTransparentUpgrade` transaction on L1, use the following command: @@ -225,6 +226,7 @@ $ zk f yarn start transactions propose-upgrade \ --gas-price \ --nonce \ --zksync-address \ +--new-governance \ --environment ``` @@ -237,6 +239,7 @@ $ zk f yarn start transactions execute-upgrade \ --gas-price \ --nonce \ --zksync-address \ +--new-governance \ --environment ``` @@ -249,5 +252,6 @@ $ zk f yarn start transactions cancel-upgrade \ --zksync-address \ --gas-price \ --nonce \ +--new-governance \ --environment ``` diff --git a/infrastructure/protocol-upgrade/src/transaction.ts b/infrastructure/protocol-upgrade/src/transaction.ts index 3d92127a8b47..9162da1c46f8 100644 --- a/infrastructure/protocol-upgrade/src/transaction.ts +++ b/infrastructure/protocol-upgrade/src/transaction.ts @@ -1,7 +1,11 @@ import { BigNumberish } from '@ethersproject/bignumber'; import { BytesLike, ethers } from 'ethers'; import { ForceDeployUpgraderFactory as ForceDeployUpgraderFactoryL2 } from 'l2-zksync-contracts/typechain'; -import { DefaultUpgradeFactory as DefaultUpgradeFactoryL1 } from 'l1-zksync-contracts/typechain'; +import { + DefaultUpgradeFactory as DefaultUpgradeFactoryL1, + AdminFacetFactory, + GovernanceFactory +} from 'l1-zksync-contracts/typechain'; import { FacetCut } from 'l1-zksync-contracts/src.ts/diamondCut'; import { IZkSyncFactory } from '../pre-boojum/IZkSyncFactory'; import { ComplexUpgrader__factory } from '../../../etc/system-contracts/typechain-types'; @@ -163,7 +167,7 @@ export function prepareDefaultCalldataForL2upgrade(forcedDeployments: ForceDeplo return complexUpgraderCalldata; } -export function prepareproposeTransparentUpgradeCalldata( +export function prepareProposeTransparentUpgradeCalldata( initCalldata, upgradeAddress: string, facetCuts: FacetCut[], @@ -185,7 +189,56 @@ export function prepareproposeTransparentUpgradeCalldata( transparentUpgrade, ethers.constants.HashZero ]); - return [proposeTransparentUpgradeCalldata, executeUpgradeCalldata, transparentUpgrade]; + return { + transparentUpgrade, + proposeTransparentUpgradeCalldata, + executeUpgradeCalldata + }; +} + +export function prepareTransparentUpgradeCalldataForNewGovernance( + initCalldata, + upgradeAddress: string, + facetCuts: FacetCut[], + zksyncAddress: string +) { + let transparentUpgrade: TransparentUpgrade = { + facetCuts, + initAddress: upgradeAddress, + initCalldata + }; + + // Prepare calldata for upgrading diamond proxy + let adminFacet = new AdminFacetFactory(); + const diamondProxyUpgradeCalldata = adminFacet.interface.encodeFunctionData('executeUpgrade', [transparentUpgrade]); + + const call = { + target: zksyncAddress, + value: 0, + data: diamondProxyUpgradeCalldata + }; + const governanceOperation = { + calls: [call], + predecessor: ethers.constants.HashZero, + salt: ethers.constants.HashZero + }; + + const governance = new GovernanceFactory(); + // Get transaction data of the `scheduleTransparent` + const scheduleTransparentOperation = governance.interface.encodeFunctionData('scheduleTransparent', [ + governanceOperation, + 0 // delay + ]); + + // Get transaction data of the `execute` + const executeOperation = governance.interface.encodeFunctionData('execute', [governanceOperation]); + + return { + scheduleTransparentOperation, + executeOperation, + governanceOperation, + transparentUpgrade + }; } export function buildDefaultUpgradeTx( @@ -194,7 +247,9 @@ export function buildDefaultUpgradeTx( upgradeAddress, l2UpgraderAddress, upgradeTimestamp, - newAllowList + newAllowList, + zksyncAddress, + useNewGovernance ) { const commonData = JSON.parse(fs.readFileSync(getCommonDataFileName(), { encoding: 'utf-8' })); const protocolVersion = commonData.protocolVersion; @@ -261,13 +316,22 @@ export function buildDefaultUpgradeTx( let l1upgradeCalldata = prepareDefaultCalldataForL1upgrade(proposeUpgradeTx); - let [proposeTransparentUpgradeCalldata, executeUpgradeCalldata, transparentUpgrade] = - prepareproposeTransparentUpgradeCalldata( + let upgradeData; + if (useNewGovernance) { + upgradeData = prepareTransparentUpgradeCalldataForNewGovernance( + l1upgradeCalldata, + upgradeAddress, + facetCuts, + zksyncAddress + ); + } else { + upgradeData = prepareProposeTransparentUpgradeCalldata( l1upgradeCalldata, upgradeAddress, facetCuts, diamondUpgradeProposalId ); + } const transactions = { proposeUpgradeTx, l1upgradeCalldata, @@ -275,9 +339,7 @@ export function buildDefaultUpgradeTx( protocolVersion, diamondUpgradeProposalId, upgradeTimestamp, - proposeTransparentUpgradeCalldata, - transparentUpgrade, - executeUpgradeCalldata + ...upgradeData }; fs.writeFileSync(getL2TransactionsFileName(environment), JSON.stringify(transactions, null, 2)); @@ -288,17 +350,16 @@ async function sendTransaction( calldata: BytesLike, privateKey: string, l1rpc: string, - zksyncAddress: string, + to: string, environment: string, gasPrice: ethers.BigNumber, nonce: number ) { const wallet = getWallet(l1rpc, privateKey); - zksyncAddress = zksyncAddress ?? process.env.CONTRACTS_DIAMOND_PROXY_ADDR; gasPrice = gasPrice ?? (await wallet.provider.getGasPrice()); nonce = nonce ?? (await wallet.getTransactionCount()); const tx = await wallet.sendTransaction({ - to: zksyncAddress, + to, data: calldata, value: 0, gasLimit: 10_000_000, @@ -330,20 +391,21 @@ async function proposeUpgrade( zksyncAddress: string, environment: string, gasPrice: ethers.BigNumber, - nonce: number + nonce: number, + newGovernanceAddress: string ) { const transactions = JSON.parse(fs.readFileSync(getL2TransactionsFileName(environment)).toString()); - const proposeTransparentUpgradeCalldata = transactions.proposeTransparentUpgradeCalldata; + let to; + let calldata; + if (newGovernanceAddress != null) { + to = newGovernanceAddress; + calldata = transactions.scheduleTransparentOperation; + } else { + to = zksyncAddress ?? process.env.CONTRACTS_DIAMOND_PROXY_ADDR; + calldata = transactions.proposeTransparentUpgradeCalldata; + } console.log(`Proposing upgrade for protocolVersion ${transactions.protocolVersion}`); - await sendTransaction( - proposeTransparentUpgradeCalldata, - privateKey, - l1rpc, - zksyncAddress, - environment, - gasPrice, - nonce - ); + await sendTransaction(calldata, privateKey, l1rpc, to, environment, gasPrice, nonce); } async function executeUpgrade( @@ -352,12 +414,21 @@ async function executeUpgrade( zksyncAddress: string, environment: string, gasPrice: ethers.BigNumber, - nonce: number + nonce: number, + newGovernanceAddress: string ) { const transactions = JSON.parse(fs.readFileSync(getL2TransactionsFileName(environment)).toString()); - const executeUpgradeCalldata = transactions.executeUpgradeCalldata; + let to; + let calldata; + if (newGovernanceAddress != null) { + to = newGovernanceAddress; + calldata = transactions.executeOperation; + } else { + to = zksyncAddress ?? process.env.CONTRACTS_DIAMOND_PROXY_ADDR; + calldata = transactions.executeUpgradeCalldata; + } console.log(`Execute upgrade for protocolVersion ${transactions.protocolVersion}`); - await sendTransaction(executeUpgradeCalldata, privateKey, l1rpc, zksyncAddress, environment, gasPrice, nonce); + await sendTransaction(calldata, privateKey, l1rpc, to, environment, gasPrice, nonce); } async function cancelUpgrade( @@ -367,28 +438,57 @@ async function cancelUpgrade( environment: string, gasPrice: ethers.BigNumber, nonce: number, - execute: boolean + execute: boolean, + newGovernanceAddress: string ) { - zksyncAddress = zksyncAddress ?? process.env.CONTRACTS_DIAMOND_PROXY_ADDR; - let wallet = getWallet(l1rpc, privateKey); - let zkSync = IZkSyncFactory.connect(zksyncAddress, wallet); - const transactions = JSON.parse(fs.readFileSync(getL2TransactionsFileName(environment)).toString()); + if (newGovernanceAddress != null) { + let wallet = getWallet(l1rpc, privateKey); + const transactions = JSON.parse(fs.readFileSync(getL2TransactionsFileName(environment)).toString()); + + let governance = GovernanceFactory.connect(newGovernanceAddress, wallet); + const operation = transactions.governanceOperation; + + const operationId = await governance.hashOperation(operation); + + console.log(`Cancel upgrade operation with id: ${operationId}`); + if (execute) { + const tx = await governance.cancel(operationId); + await tx.wait(); + console.log('Operation canceled'); + } else { + const calldata = governance.interface.encodeFunctionData('cancel', [operationId]); + console.log(`Cancel upgrade calldata: ${calldata}`); + } + } else { + zksyncAddress = zksyncAddress ?? process.env.CONTRACTS_DIAMOND_PROXY_ADDR; + let wallet = getWallet(l1rpc, privateKey); + let zkSync = IZkSyncFactory.connect(zksyncAddress, wallet); + const transactions = JSON.parse(fs.readFileSync(getL2TransactionsFileName(environment)).toString()); - const transparentUpgrade = transactions.transparentUpgrade; - const diamondUpgradeProposalId = transactions.diamondUpgradeProposalId; + const transparentUpgrade = transactions.transparentUpgrade; + const diamondUpgradeProposalId = transactions.diamondUpgradeProposalId; - const proposalHash = await zkSync.upgradeProposalHash( - transparentUpgrade, - diamondUpgradeProposalId, - ethers.constants.HashZero - ); + const proposalHash = await zkSync.upgradeProposalHash( + transparentUpgrade, + diamondUpgradeProposalId, + ethers.constants.HashZero + ); - console.log(`Cancel upgrade with hash: ${proposalHash}`); - let cancelUpgradeCalldata = zkSync.interface.encodeFunctionData('cancelUpgradeProposal', [proposalHash]); - if (execute) { - await sendTransaction(cancelUpgradeCalldata, privateKey, l1rpc, zksyncAddress, environment, gasPrice, nonce); - } else { - console.log(`Cancel upgrade calldata: ${cancelUpgradeCalldata}`); + console.log(`Cancel upgrade with hash: ${proposalHash}`); + let cancelUpgradeCalldata = zkSync.interface.encodeFunctionData('cancelUpgradeProposal', [proposalHash]); + if (execute) { + await sendTransaction( + cancelUpgradeCalldata, + privateKey, + l1rpc, + zksyncAddress, + environment, + gasPrice, + nonce + ); + } else { + console.log(`Cancel upgrade calldata: ${cancelUpgradeCalldata}`); + } } } @@ -421,9 +521,10 @@ command .option('--diamond-upgrade-proposal-id ') .option('--l1rpc ') .option('--zksync-address ') + .option('--use-new-governance') .action(async (options) => { let diamondUpgradeProposalId = options.diamondUpgradeProposalId; - if (!diamondUpgradeProposalId) { + if (!diamondUpgradeProposalId && !options.useNewGovernance) { diamondUpgradeProposalId = await getNewDiamondUpgradeProposalId(options.l1rpc, options.zksyncAddress); } @@ -433,7 +534,9 @@ command options.upgradeAddress, options.l2UpgraderAddress, options.upgradeTimestamp, - options.newAllowList + options.newAllowList, + options.zksyncAddress, + options.useNewGovernance ); }); @@ -445,6 +548,7 @@ command .option('--gas-price ') .option('--nonce ') .option('--l1rpc ') + .option('--new-governance ') .action(async (options) => { await proposeUpgrade( options.privateKey, @@ -452,7 +556,8 @@ command options.zksyncAddress, options.environment, options.gasPrice, - options.nonce + options.nonce, + options.newGovernance ); }); @@ -464,6 +569,7 @@ command .option('--gas-price ') .option('--nonce ') .option('--l1rpc ') + .option('--new-governance ') .action(async (options) => { await executeUpgrade( options.privateKey, @@ -471,7 +577,8 @@ command options.zksyncAddress, options.environment, options.gasPrice, - options.nonce + options.nonce, + options.newGovernance ); }); @@ -484,6 +591,7 @@ command .option('--nonce ') .option('--l1rpc ') .option('--execute') + .option('--new-governance ') .action(async (options) => { await cancelUpgrade( options.privateKey, @@ -492,6 +600,7 @@ command options.environment, options.gasPrice, options.nonce, - options.execute + options.execute, + options.newGovernance ); });