Skip to content

Commit

Permalink
update upgrade script
Browse files Browse the repository at this point in the history
  • Loading branch information
invocamanman committed Jan 5, 2023
1 parent afc55f3 commit 7a08069
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 116 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ docs/mocks
.vscode/launch.json
deploy_output.json
deploy_parameters.json
deployments
deployments
upgrade_parameters.json
2 changes: 1 addition & 1 deletion deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ A new folder will be created witth the following name `deployments/${network}_$(

## Notes

- `gensis.json` has been generated using the tool: `src/create-genesis.js` using as generator file: `genesis-gen.json`
- `genesis.json` has been generated using the tool: `src/create-genesis.js` using as generator file: `genesis-gen.json`
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"docgen": "npx solidity-docgen --solc-module solc-0.8 -t ./docs/templates -e ./contracts/verifiers,./contracts/mocks",
"deploy:ZkEVM:hardhat": "npx hardhat run deployment/deployContracts.js --network hardhat",
"deploy:ZkEVM:goerli": "npx hardhat run deployment/deployContracts.js --network goerli && npm run saveDeployment:goerli",
"upgrade:timelock:goerli": "npx hardhat run deployment/timeLockUpgrade.js --network goerli",
"upgrade:timelock:goerli": "npx hardhat run upgrade/timeLockUpgrade.js --network goerli",
"verify:ZkEVM:goerli": "npx hardhat run deployment/verifyContracts.js --network goerli",
"lint": "npx eslint ./test && npx eslint ./docker/scripts && npx eslint ./deployment && npx eslint ./src",
"lint:fix": "npx eslint ./test --fix && npx eslint ./docker/scripts --fix && npx eslint ./deployment --fix && npx eslint ./src --fix",
Expand Down
37 changes: 28 additions & 9 deletions upgrade/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,37 @@ In order to upgrade the contracts we will need the information on `deployments/$
In project root, copy the `${network}.json` of the deployment that you want to upgrade and copy it on the `./.openzeppelin`
e.g. `cp deployments/${network}_$(date +%s)/${network}.json ./.openzeppelin`

Then fill the upgrade parameters:

```
cd deployment
cp upgrade_parameters.json.example upgrade_parameters.json
```

Fill created `upgrade_parameters.json` with appropiate parameters.
You should fullfill the upgrades array, with all the updates that you intend to do ( more information in `upgrade-parameters.json` section)

if the deployment was deployed without a timelock you can use the `simpleUpgradeScript.js`:

- Update the `proxyPolygonAddress` with the proxy address you want to update
- Update the `polygonZkEVMFactory` with the new implementation contract you want to upgrade
- Run the script

Otherwise, inc ase of timelock use `timeLockUpgrade.js`
Otherwise, in case of timelock use `timeLockUpgrade.js`

- Update the `proxyPolygonAddress` with the proxy address you want to update
- Update the `polygonZkEVMFactory` with the new implementation contract you want to upgrade
- Update the `minDelay` with the delay that you want to use
- Run the script
- Now the necessary transactions to interact with the timelock are printed in the screen `schedule` and `execute`
- With the owner of the timelock ( multisig or account), send the data printed by `schedule` to the `Timelock` contract.
- Once the necessary timeout has pass, with the same account you can now send the data printed by `execute` to the `Timelock` contract and the contracts will be upgraded.
- Now the necessary transactions to interact with the timelock are printed in the screen `schedule` and `execute`, also will be saved in
`./upgrade_output_${new Date().getTime() / 1000}.json` file
- With the owner of the timelock (multisig or account), send the data printed by `schedule` to the `Timelock` contract.
- Once the necessary `timelockMinDelay` has expired, with the same account you can now send the data printed by `execute` to the `Timelock` contract and the contracts will be upgraded.

## upgrade-parameters.json

- `timelockMinDelay`: number, timelock delay between the schedule and execution, must be bigger than current min delay
- `upgrades`: Object, Indicates which address and to which implementation must upgrade
- address: address of the current proxy
- contractName: string, contract name that the proxy will be updated to.s

### Optional Parameters

- `multiplierGas`: number, Gas multiplier. If maxFeePerGas and maxPriorityFeePerGas are set, will not take effect
- `deployerPvtKey`: string, deployerPvtKey of the deployer
- `timelockSalt`: string, Optional salt for the timelock
53 changes: 53 additions & 0 deletions upgrade/simpleUpgrade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable no-console, no-unused-vars */
const hre = require('hardhat');
const { ethers, upgrades } = require('hardhat');
const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '../.env') });
const upgradeParameters = require('./upgrade_parameters.json');

async function main() {
// Set multiplier Gas
let currentProvider = ethers.provider;
if (upgradeParameters.multiplierGas) {
if (process.env.HARDHAT_NETWORK !== 'hardhat') {
const multiplierGas = upgradeParameters.multiplierGas;
currentProvider = new ethers.providers.JsonRpcProvider(`https://${process.env.HARDHAT_NETWORK}.infura.io/v3/${process.env.INFURA_PROJECT_ID}`);
async function overrideFeeData() {
const feedata = await ethers.provider.getFeeData();
return {
maxFeePerGas: feedata.maxFeePerGas.mul(multiplierGas),
maxPriorityFeePerGas: feedata.maxPriorityFeePerGas.mul(multiplierGas),
};
}
currentProvider.getFeeData = overrideFeeData;
}
}
let deployer;
if (upgradeParameters.deployerPvtKey) {
deployer = new ethers.Wallet(upgradeParameters.deployerPvtKey, currentProvider);
} else if (process.env.MNEMONIC) {
deployer = ethers.Wallet.fromMnemonic(process.env.MNEMONIC, 'm/44\'/60\'/0\'/0/0').connect(currentProvider);
} else {
[deployer] = (await ethers.getSigners());
}

// compìle contracts
await hre.run('compile');

for (const upgrade of upgradeParameters.upgrades) {
const proxyPolygonAddress = upgrade.address;
const polygonZkEVMFactory = await ethers.getContractFactory(upgrade.contractName, deployer);

const txZKEVM = await upgrades.upgradeProxy(proxyPolygonAddress, polygonZkEVMFactory);

console.log(txZKEVM.deployTransaction);
console.log(await txZKEVM.deployTransaction.wait());
console.log('upgrade succesfull', upgrade.contractName);
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
45 changes: 0 additions & 45 deletions upgrade/simpleUpgradeScript.js

This file was deleted.

139 changes: 80 additions & 59 deletions upgrade/timeLockUpgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,85 +3,106 @@ const hre = require('hardhat');
const { ethers, upgrades } = require('hardhat');
const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '../.env') });
const fs = require('fs');

const upgradeParameters = require('./upgrade_parameters.json');
const pathOutputJson = path.join(__dirname, `./upgrade_output_${new Date().getTime() / 1000}.json`);

async function main() {
// Set multiplier Gas
const multiplierGas = 3;
const currentProvider = new ethers.providers.JsonRpcProvider(`https://${process.env.HARDHAT_NETWORK}.infura.io/v3/${process.env.INFURA_PROJECT_ID}`);
async function overrideFeeData() {
const feedata = await ethers.provider.getFeeData();
return {
maxFeePerGas: feedata.maxFeePerGas.mul(multiplierGas),
maxPriorityFeePerGas: feedata.maxPriorityFeePerGas.mul(multiplierGas),
};
let currentProvider = ethers.provider;
if (upgradeParameters.multiplierGas) {
if (process.env.HARDHAT_NETWORK !== 'hardhat') {
const multiplierGas = upgradeParameters.multiplierGas;
currentProvider = new ethers.providers.JsonRpcProvider(`https://${process.env.HARDHAT_NETWORK}.infura.io/v3/${process.env.INFURA_PROJECT_ID}`);
async function overrideFeeData() {
const feedata = await ethers.provider.getFeeData();
return {
maxFeePerGas: feedata.maxFeePerGas.mul(multiplierGas),
maxPriorityFeePerGas: feedata.maxPriorityFeePerGas.mul(multiplierGas),
};
}
currentProvider.getFeeData = overrideFeeData;
}
}
currentProvider.getFeeData = overrideFeeData;

let deployer;
if (process.env.MNEMONIC) {
if (upgradeParameters.deployerPvtKey) {
deployer = new ethers.Wallet(upgradeParameters.deployerPvtKey, currentProvider);
} else if (process.env.MNEMONIC) {
deployer = ethers.Wallet.fromMnemonic(process.env.MNEMONIC, 'm/44\'/60\'/0\'/0/0').connect(currentProvider);
} else {
[deployer] = (await ethers.getSigners());
}

// compìle contracts
await hre.run('compile');

const proxyPolygonAddress = '0xfefefefefefefefefefefefee';
const polygonZkEVMFactory = await ethers.getContractFactory('PolygonZkEVMMock', deployer);
const proxyAdmin = await upgrades.admin.getInstance();
const output = [];

// Upgrade zkevm
const newImplPolygonAddress = await upgrades.prepareUpgrade(proxyPolygonAddress, polygonZkEVMFactory);
const proxyAdmin = await upgrades.admin.getInstance();
for (const upgrade of upgradeParameters.upgrades) {
const proxyPolygonAddress = upgrade.address;
const polygonZkEVMFactory = await ethers.getContractFactory(upgrade.contractName, deployer);

console.log({ newImplPolygonAddress });
console.log("you can verify the new impl address with:")
console.log(`npx hardhat verify ${proxyPolygonAddress} --network ${process.env.HARDHAT_NETWORK}`);
const newImplPolygonAddress = await upgrades.prepareUpgrade(proxyPolygonAddress, polygonZkEVMFactory);

// show timelock address
// Use timelock
const operation = genOperation(
proxyAdmin.address,
0, // value
proxyAdmin.interface.encodeFunctionData(
'upgrade',
[proxyPolygonAddress,
newImplPolygonAddress],
),
ethers.constants.HashZero, // predecesoor
ethers.constants.HashZero, // salt TODO
);
console.log({ newImplPolygonAddress });
console.log("you can verify the new impl address with:")
console.log(`npx hardhat verify ${newImplPolygonAddress} --network ${process.env.HARDHAT_NETWORK}`);

// Timelock operations
const TimelockFactory = await ethers.getContractFactory('PolygonZkEVMTimelock', deployer);
const minDelay = 10; // TODO upgrade parameter
// Use timelock
const salt = upgradeParameters.timelockSalt || ethers.constants.HashZero;
const operation = genOperation(
proxyAdmin.address,
0, // value
proxyAdmin.interface.encodeFunctionData(
'upgrade',
[proxyPolygonAddress,
newImplPolygonAddress],
),
ethers.constants.HashZero, // predecesoor
salt, // salt
);

// Schedule operation
const scheduleData = TimelockFactory.interface.encodeFunctionData(
'schedule',
[
operation.target,
operation.value,
operation.data,
operation.predecessor,
operation.salt,
minDelay,
],
);
// Executre operation
const executeData = TimelockFactory.interface.encodeFunctionData(
'execute',
[
operation.target,
operation.value,
operation.data,
operation.predecessor,
operation.salt,
],
);
// Timelock operations
const TimelockFactory = await ethers.getContractFactory('PolygonZkEVMTimelock', deployer);
const minDelay = upgradeParameters.timelockMinDelay || 0;

// Schedule operation
const scheduleData = TimelockFactory.interface.encodeFunctionData(
'schedule',
[
operation.target,
operation.value,
operation.data,
operation.predecessor,
operation.salt,
minDelay,
],
);
// Executre operation
const executeData = TimelockFactory.interface.encodeFunctionData(
'execute',
[
operation.target,
operation.value,
operation.data,
operation.predecessor,
operation.salt,
],
);

console.log({ scheduleData });
console.log({ executeData });
output.push({
contractName: upgrade.contractName,
scheduleData,
executeData
})
}

console.log({ scheduleData });
console.log({ executeData });
fs.writeFileSync(pathOutputJson, JSON.stringify(output, null, 1));
}
main()
.then(() => process.exit(0))
Expand Down
16 changes: 16 additions & 0 deletions upgrade/upgrade_parameters.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"timelockMinDelay":10,
"upgrades": [
{
"address": "0x6958d5f1AFa6f668c7D7F37a444d09E2330eB104",
"contractName": "PolygonZkEVM"
},
{
"address": "0x5cA95a1629e7dDD51b66Bf1505560cd7edA91d83",
"contractName": "PolygonZkEVMBridgeMock"
}
],
"multiplierGas": 0,
"deployerPvtKey": "",
"timelockSalt": ""
}

0 comments on commit 7a08069

Please sign in to comment.