From 8d5ffc8ddaa725154eeaabeb12b0ffc1eea81b32 Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Mon, 5 Jun 2023 16:47:20 +0200 Subject: [PATCH 1/8] feat: initial deployer script adapter --- cli-tools/deployer.js | 142 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 cli-tools/deployer.js diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js new file mode 100644 index 00000000..48800229 --- /dev/null +++ b/cli-tools/deployer.js @@ -0,0 +1,142 @@ +const { Wallet } = require("ethers"); +const fs = require("fs"); +const chalk = require("chalk"); +const dotenv = require("dotenv"); +const { Readable } = require("stream"); + +dotenv.config(); + +if (process.argv.length != 4) { + console.error(chalk.red(`Must provide deployment operation and target network!`)); + process.exit(1); +} + +const [op, networkId] = process.argv.slice(2); + +const rpcUrl = process.env[`ETH_${networkId}_RPC_URL`]; +const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); + +const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; +const systemAdminAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; + +if (op === "deploy") { + console.log(`[ ${chalk.green(networkId)} ] Deploying new diamond`); + + const deployNewDiamondCmd = deployDiamondCmd(rpcUrl, networkId, ownerAddress, systemAdminAddress); + execute(deployNewDiamondCmd); + + const initSimCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); + const result = execute(initSimCmd); + const hashLine = result + .split("\n") + .find((line) => line.includes("Upgrade is not scheduled for this hash")) + .trim() + .split(" "); + const upgradeHash = hashLine[hashLine.length - 1]; + + const scheduleCommand = schedule({ + rpcUrl, + networkId, + upgradeHash, + systemAdminAddress, + mnemonicFile: "./nayms_mnemonic.txt", + mnemonicIndex: 0, + }); + execute(scheduleCommand); + + const initCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress); + execute(initCmd); +} else if (op === "upgrade") { + const addressesRaw = fs.readFileSync("deployedAddresses.json"); + const addresses = JSON.parse(addressesRaw); + + console.log(`[ ${chalk.green(networkId)} ] upgrade => ${chalk.greenBright(addresses[networkId])}`); +} else { + console.log(chalk.red("Supported operations are: 'deploy' and 'upgrade'!")); + process.exit(1); +} + +function deployDiamondCmd(rpcUrl, networkId, owner, sysAdmin, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { + return smartDeploy({ + rpcUrl, + networkId, + newDeploy: true, + owner, + sysAdmin, + initDiamond: false, + facetAction: 2, + facetsToCutIn, + salt, + sender: owner, + mnemonicFile: "./nayms_mnemonic.txt", + mnemonicIndex: 19, + broadcast: true, + }); +} + +function upgradeInit(rpcUrl, networkId, owner, sysAdmin, broadcast = true, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { + return smartDeploy({ + rpcUrl, + networkId, + newDeploy: false, + owner, + sysAdmin, + initDiamond: true, + facetAction: 1, + facetsToCutIn, + salt, + sender: owner, + mnemonicFile: "./nayms_mnemonic.txt", + mnemonicIndex: 19, + broadcast, + }); +} + +function smartDeploy(config) { + let command = `forge script SmartDeploy \\ + -s "smartDeploy(bool, address, address, bool, uint8, string[] memory, bytes32)" ${config.newDeploy} ${config.owner} ${config.sysAdmin} ${config.initDiamond} ${config.facetAction} ${config.facetsToCutIn} ${config.salt} \\ + -f ${config.rpcUrl} \\ + --chain-id ${config.networkId}`; + + if (config.broadcast) { + command += ` \\ + --sender ${config.sender} \\ + --mnemonic-paths ${config.mnemonicFile} \\ + --mnemonic-indexes ${config.mnemonicIndex}`; + } + + command += ` \\ + -vv \\ + --ffi`; + + if (config.broadcast) { + command += ` \\ + --broadcast`; + } + + return command; +} + +function schedule(config) { + return `forge script SmartDeploy \\ + -s "schedule(bytes32)" ${config.upgradeHash} \\ + -f ${config.rpcUrl} \\ + --chain-id ${config.networkId} \\ + --sender ${config.systemAdminAddress} \\ + --mnemonic-paths ${config.mnemonicFile} \\ + --mnemonic-indexes ${config.mnemonicIndex} \\ + -vv \\ + --ffi \\ + --broadcast + `; +} + +function execute(cmd) { + const { execSync } = require("child_process"); + console.log("\n == Executing ==\n\n", cmd); + + const result = execSync(cmd).toString(); + console.log("\n == Result ==\n\n", result); + + return result; +} From 5d7b2eaa132d4906970d6f1a614246cc1b10e620 Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Thu, 8 Jun 2023 13:33:59 +0200 Subject: [PATCH 2/8] feat: script upgrade procedure --- cli-tools/deployer.js | 86 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index 48800229..48f43016 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -2,7 +2,6 @@ const { Wallet } = require("ethers"); const fs = require("fs"); const chalk = require("chalk"); const dotenv = require("dotenv"); -const { Readable } = require("stream"); dotenv.config(); @@ -11,7 +10,7 @@ if (process.argv.length != 4) { process.exit(1); } -const [op, networkId] = process.argv.slice(2); +const [operation, networkId] = process.argv.slice(2); const rpcUrl = process.env[`ETH_${networkId}_RPC_URL`]; const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); @@ -19,21 +18,19 @@ const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; const systemAdminAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; -if (op === "deploy") { +if (operation === "deploy") { console.log(`[ ${chalk.green(networkId)} ] Deploying new diamond`); + console.log("\n>> deploying new diamond\n"); const deployNewDiamondCmd = deployDiamondCmd(rpcUrl, networkId, ownerAddress, systemAdminAddress); execute(deployNewDiamondCmd); + console.log("\n>> initializing upgrade\n"); const initSimCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); const result = execute(initSimCmd); - const hashLine = result - .split("\n") - .find((line) => line.includes("Upgrade is not scheduled for this hash")) - .trim() - .split(" "); - const upgradeHash = hashLine[hashLine.length - 1]; + const upgradeHash = getUpgradeHash(result); + console.log("\n>> scheduling upgrade\n"); const scheduleCommand = schedule({ rpcUrl, networkId, @@ -44,18 +41,59 @@ if (op === "deploy") { }); execute(scheduleCommand); - const initCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress); - execute(initCmd); -} else if (op === "upgrade") { + console.log("\n>> do upgrade\n"); + const upgradeCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress); + execute(upgradeCmd); +} else if (operation === "upgrade") { const addressesRaw = fs.readFileSync("deployedAddresses.json"); const addresses = JSON.parse(addressesRaw); console.log(`[ ${chalk.green(networkId)} ] upgrade => ${chalk.greenBright(addresses[networkId])}`); + + console.log("\n>> deploy upgrade\n"); + const upgradeCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); + const result = execute(upgradeCmd); + const upgradeHash = getUpgradeHash(result); + + console.log("\n>> scheduling upgrade\n"); + const scheduleCommand = schedule({ + rpcUrl, + networkId, + upgradeHash, + systemAdminAddress, + mnemonicFile: "./nayms_mnemonic.txt", + mnemonicIndex: 0, + }); + execute(scheduleCommand); + + console.log("\n>> prep upgrade\n"); + const prepCmd = `node ./cli-tools/prep-upgrade.js broadcast/SmartDeploy.s.sol/${networkId}/smartDeploy-latest.json`; + execute(prepCmd); + + console.log("\n>> diamond cut\n"); + const diamondCutCmd = diamondCut({ + rpcUrl, + networkId, + upgradeHash, + ownerAddress, + mnemonicFile: "./nayms_mnemonic.txt", + mnemonicIndex: 19, + }); + execute(diamondCutCmd); } else { console.log(chalk.red("Supported operations are: 'deploy' and 'upgrade'!")); process.exit(1); } +function getUpgradeHash(result) { + const hashLine = result + .split("\n") + .find((line) => line.includes("upgradeHash: bytes32")) + .trim() + .split(" "); + return hashLine[hashLine.length - 1]; +} + function deployDiamondCmd(rpcUrl, networkId, owner, sysAdmin, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { return smartDeploy({ rpcUrl, @@ -74,14 +112,14 @@ function deployDiamondCmd(rpcUrl, networkId, owner, sysAdmin, facetsToCutIn = '" }); } -function upgradeInit(rpcUrl, networkId, owner, sysAdmin, broadcast = true, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { +function upgradeInit(rpcUrl, networkId, owner, sysAdmin, initDiamond = true, broadcast = true, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { return smartDeploy({ rpcUrl, networkId, newDeploy: false, owner, sysAdmin, - initDiamond: true, + initDiamond, facetAction: 1, facetsToCutIn, salt, @@ -127,16 +165,28 @@ function schedule(config) { --mnemonic-indexes ${config.mnemonicIndex} \\ -vv \\ --ffi \\ - --broadcast - `; + --broadcast`; +} + +function diamondCut(config) { + return `forge script S03UpgradeDiamond \ + -s "run(address)" ${config.ownerAddress} \ + -f ${config.rpcUrl} \\ + --chain-id ${config.networkId} \\ + --sender ${config.ownerAddress} \\ + --mnemonic-paths ${config.mnemonicFile} \\ + --mnemonic-indexes ${config.mnemonicIndex} \\ + -vv \\ + --ffi \\ + --broadcast`; } function execute(cmd) { const { execSync } = require("child_process"); - console.log("\n == Executing ==\n\n", cmd); + console.log(cmd); const result = execSync(cmd).toString(); - console.log("\n == Result ==\n\n", result); + console.log("\n\n ------------------ \n\n", result); return result; } From c2b38de157a85ca63484d94beaa9a3bee450421b Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Thu, 8 Jun 2023 15:19:47 +0200 Subject: [PATCH 3/8] feat(deployer): add fork support --- cli-tools/deployer.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index 48f43016..2fc957f7 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -5,14 +5,18 @@ const dotenv = require("dotenv"); dotenv.config(); -if (process.argv.length != 4) { +if (process.argv.length != 4 && process.argv.length != 5) { console.error(chalk.red(`Must provide deployment operation and target network!`)); process.exit(1); } -const [operation, networkId] = process.argv.slice(2); +const [operation, networkId, fork] = process.argv.slice(2); -const rpcUrl = process.env[`ETH_${networkId}_RPC_URL`]; +if (fork) { + console.log(`[ ${chalk.green("FORKING")} ]`); +} + +const rpcUrl = fork ? "http://localhost:8545" : process.env[`ETH_${networkId}_RPC_URL`]; const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; From 193e78b22927dc8762d0aa502b34b871bbbf9f4e Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Thu, 8 Jun 2023 15:29:59 +0200 Subject: [PATCH 4/8] refactor: improve logging --- cli-tools/deployer.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index 2fc957f7..e67d4a03 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -12,10 +12,6 @@ if (process.argv.length != 4 && process.argv.length != 5) { const [operation, networkId, fork] = process.argv.slice(2); -if (fork) { - console.log(`[ ${chalk.green("FORKING")} ]`); -} - const rpcUrl = fork ? "http://localhost:8545" : process.env[`ETH_${networkId}_RPC_URL`]; const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); @@ -23,18 +19,18 @@ const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; const systemAdminAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; if (operation === "deploy") { - console.log(`[ ${chalk.green(networkId)} ] Deploying new diamond`); + console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] Deploying new diamond`); - console.log("\n>> deploying new diamond\n"); + console.log(`\n[ ${chalk.green("Deploying contracts")} ]\n`); const deployNewDiamondCmd = deployDiamondCmd(rpcUrl, networkId, ownerAddress, systemAdminAddress); execute(deployNewDiamondCmd); - console.log("\n>> initializing upgrade\n"); + console.log(`\n[ ${chalk.green("Initializing upgrade")} ]\n`); const initSimCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); const result = execute(initSimCmd); const upgradeHash = getUpgradeHash(result); - console.log("\n>> scheduling upgrade\n"); + console.log(`\n[ ${chalk.green("Scheduling upgrade")} ]\n`); const scheduleCommand = schedule({ rpcUrl, networkId, @@ -45,21 +41,21 @@ if (operation === "deploy") { }); execute(scheduleCommand); - console.log("\n>> do upgrade\n"); + console.log(`\n[ ${chalk.green("Doing upgrade")} ]\n`); const upgradeCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress); execute(upgradeCmd); } else if (operation === "upgrade") { const addressesRaw = fs.readFileSync("deployedAddresses.json"); const addresses = JSON.parse(addressesRaw); - console.log(`[ ${chalk.green(networkId)} ] upgrade => ${chalk.greenBright(addresses[networkId])}`); + console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] upgrade => ${chalk.greenBright(addresses[networkId])}`); - console.log("\n>> deploy upgrade\n"); + console.log(`\n[ ${chalk.green("Deploying contracts")} ]\n`); const upgradeCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); const result = execute(upgradeCmd); const upgradeHash = getUpgradeHash(result); - console.log("\n>> scheduling upgrade\n"); + console.log(`\n[ ${chalk.green("Scheduling upgrade")} ]\n`); const scheduleCommand = schedule({ rpcUrl, networkId, @@ -70,11 +66,11 @@ if (operation === "deploy") { }); execute(scheduleCommand); - console.log("\n>> prep upgrade\n"); + console.log(`\n[ ${chalk.green("Preparing upgrade")} ]\n`); const prepCmd = `node ./cli-tools/prep-upgrade.js broadcast/SmartDeploy.s.sol/${networkId}/smartDeploy-latest.json`; execute(prepCmd); - console.log("\n>> diamond cut\n"); + console.log(`\n[ ${chalk.green("Diamond cut")} ]\n`); const diamondCutCmd = diamondCut({ rpcUrl, networkId, From 383dd236ae7446354f0bc5fe39f4e4e7a526d092 Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Fri, 9 Jun 2023 15:28:47 +0200 Subject: [PATCH 5/8] fix: mainnet fork support --- cli-tools/deployer.js | 50 ++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index e67d4a03..d9da9041 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -16,7 +16,10 @@ const rpcUrl = fork ? "http://localhost:8545" : process.env[`ETH_${networkId}_RP const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; -const systemAdminAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; +const systemAdminAddress = + networkId === "1" + ? "0xE6aD24478bf7E1C0db07f7063A4019C83b1e5929" // mainnet sysAdminB + : Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; if (operation === "deploy") { console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] Deploying new diamond`); @@ -26,7 +29,7 @@ if (operation === "deploy") { execute(deployNewDiamondCmd); console.log(`\n[ ${chalk.green("Initializing upgrade")} ]\n`); - const initSimCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); + const initSimCmd = upgrade(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); const result = execute(initSimCmd); const upgradeHash = getUpgradeHash(result); @@ -42,16 +45,27 @@ if (operation === "deploy") { execute(scheduleCommand); console.log(`\n[ ${chalk.green("Doing upgrade")} ]\n`); - const upgradeCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress); + const upgradeCmd = upgrade(rpcUrl, networkId, ownerAddress, systemAdminAddress); execute(upgradeCmd); } else if (operation === "upgrade") { const addressesRaw = fs.readFileSync("deployedAddresses.json"); const addresses = JSON.parse(addressesRaw); - console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] upgrade => ${chalk.greenBright(addresses[networkId])}`); + console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] upgrade => ${chalk.greenBright(addresses[networkId])}\n`); + + if (networkId === "1" && fork) { + // transfer ownership + execute(`cast rpc anvil_impersonateAccount ${systemAdminAddress}`); + execute(`cast send ${addresses[networkId]} "transferOwnership(address)" \ + ${ownerAddress} \ + -r http:\\127.0.0.1:8545 \ + --unlocked \ + --from ${systemAdminAddress}`); + execute(`cast rpc anvil_setBalance ${ownerAddress} 10000000000000000000 -r http:\\127.0.0.1:8545`); + } console.log(`\n[ ${chalk.green("Deploying contracts")} ]\n`); - const upgradeCmd = upgradeInit(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); + const upgradeCmd = upgrade(rpcUrl, networkId, ownerAddress, systemAdminAddress, false); const result = execute(upgradeCmd); const upgradeHash = getUpgradeHash(result); @@ -63,6 +77,8 @@ if (operation === "deploy") { systemAdminAddress, mnemonicFile: "./nayms_mnemonic.txt", mnemonicIndex: 0, + fork, + diamondAddress: addresses[networkId], }); execute(scheduleCommand); @@ -112,7 +128,7 @@ function deployDiamondCmd(rpcUrl, networkId, owner, sysAdmin, facetsToCutIn = '" }); } -function upgradeInit(rpcUrl, networkId, owner, sysAdmin, initDiamond = true, broadcast = true, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { +function upgrade(rpcUrl, networkId, owner, sysAdmin, initDiamond = true, broadcast = true, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { return smartDeploy({ rpcUrl, networkId, @@ -156,16 +172,20 @@ function smartDeploy(config) { } function schedule(config) { - return `forge script SmartDeploy \\ - -s "schedule(bytes32)" ${config.upgradeHash} \\ - -f ${config.rpcUrl} \\ + const isFork = config.networkId === "1" && config.fork; + const impersonateIfNeeded = isFork ? `cast rpc anvil_impersonateAccount ${config.systemAdminAddress} && ` : ""; + const mnemonicIfNeeded = isFork + ? "" + : ` \\ --chain-id ${config.networkId} \\ - --sender ${config.systemAdminAddress} \\ - --mnemonic-paths ${config.mnemonicFile} \\ - --mnemonic-indexes ${config.mnemonicIndex} \\ - -vv \\ - --ffi \\ - --broadcast`; + --mnemonic ${config.mnemonicFile} \\ + --mnemonic-index ${config.mnemonicIndex} + `; + + return `${impersonateIfNeeded} cast send ${config.diamondAddress} "createUpgrade(bytes32)" \ + ${config.upgradeHash} \ + --rpc-url ${config.rpcUrl} ${isFork ? "--unlocked" : ""} \ + --from ${config.systemAdminAddress} ${mnemonicIfNeeded}`; } function diamondCut(config) { From bce92c408b97b16bfe0d3be77a586784ca6a1f91 Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Thu, 22 Jun 2023 16:11:46 +0200 Subject: [PATCH 6/8] feat: add dry run option --- cli-tools/deployer.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index d9da9041..9bc192af 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -5,15 +5,18 @@ const dotenv = require("dotenv"); dotenv.config(); -if (process.argv.length != 4 && process.argv.length != 5) { +if (process.argv.length <= 3) { console.error(chalk.red(`Must provide deployment operation and target network!`)); process.exit(1); } -const [operation, networkId, fork] = process.argv.slice(2); +const [operation, networkId, ...otherArgs] = process.argv.slice(2); + +const fork = otherArgs.includes("--fork"); +const dryRun = otherArgs.includes("--dry-run"); const rpcUrl = fork ? "http://localhost:8545" : process.env[`ETH_${networkId}_RPC_URL`]; -const mnemonic = fs.readFileSync("nayms_mnemonic.txt").toString(); +const mnemonic = networkId === "1" ? fs.readFileSync("nayms_mnemonic.txt").toString() : fs.readFileSync("nayms_mnemonic_mainnet.txt").toString(); const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; const systemAdminAddress = @@ -202,11 +205,13 @@ function diamondCut(config) { } function execute(cmd) { - const { execSync } = require("child_process"); console.log(cmd); - const result = execSync(cmd).toString(); - console.log("\n\n ------------------ \n\n", result); + if (!dryRun) { + const { execSync } = require("child_process"); - return result; + const result = execSync(cmd).toString(); + console.log("\n\n ------------------ \n\n", result); + return result; + } } From 7da18f555dac7b4ed70195b07e11f47a15236071 Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Fri, 23 Jun 2023 10:57:04 +0200 Subject: [PATCH 7/8] refactor: improve flow and arguments for mainnet operation --- cli-tools/deployer.js | 65 ++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index 9bc192af..9d25013e 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -16,19 +16,20 @@ const fork = otherArgs.includes("--fork"); const dryRun = otherArgs.includes("--dry-run"); const rpcUrl = fork ? "http://localhost:8545" : process.env[`ETH_${networkId}_RPC_URL`]; -const mnemonic = networkId === "1" ? fs.readFileSync("nayms_mnemonic.txt").toString() : fs.readFileSync("nayms_mnemonic_mainnet.txt").toString(); +const mnemonicFile = networkId === "1" ? "nayms_mnemonic_mainnet.txt" : "nayms_mnemonic.txt"; +const mnemonic = fs.readFileSync(mnemonicFile).toString(); -const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; +const ownerAddress = Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/19`).address; // acc20 const systemAdminAddress = networkId === "1" ? "0xE6aD24478bf7E1C0db07f7063A4019C83b1e5929" // mainnet sysAdminB - : Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; + : Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; // acc1 if (operation === "deploy") { console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] Deploying new diamond`); console.log(`\n[ ${chalk.green("Deploying contracts")} ]\n`); - const deployNewDiamondCmd = deployDiamondCmd(rpcUrl, networkId, ownerAddress, systemAdminAddress); + const deployNewDiamondCmd = deployDiamond(rpcUrl, networkId, ownerAddress, systemAdminAddress); execute(deployNewDiamondCmd); console.log(`\n[ ${chalk.green("Initializing upgrade")} ]\n`); @@ -37,12 +38,12 @@ if (operation === "deploy") { const upgradeHash = getUpgradeHash(result); console.log(`\n[ ${chalk.green("Scheduling upgrade")} ]\n`); - const scheduleCommand = schedule({ + const scheduleCommand = scheduleUpgrade({ rpcUrl, networkId, upgradeHash, systemAdminAddress, - mnemonicFile: "./nayms_mnemonic.txt", + mnemonicFile: mnemonicFile, mnemonicIndex: 0, }); execute(scheduleCommand); @@ -57,7 +58,7 @@ if (operation === "deploy") { console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] upgrade => ${chalk.greenBright(addresses[networkId])}\n`); if (networkId === "1" && fork) { - // transfer ownership + // transfer ownership to non-mainnet account execute(`cast rpc anvil_impersonateAccount ${systemAdminAddress}`); execute(`cast send ${addresses[networkId]} "transferOwnership(address)" \ ${ownerAddress} \ @@ -72,18 +73,22 @@ if (operation === "deploy") { const result = execute(upgradeCmd); const upgradeHash = getUpgradeHash(result); - console.log(`\n[ ${chalk.green("Scheduling upgrade")} ]\n`); - const scheduleCommand = schedule({ - rpcUrl, - networkId, - upgradeHash, - systemAdminAddress, - mnemonicFile: "./nayms_mnemonic.txt", - mnemonicIndex: 0, - fork, - diamondAddress: addresses[networkId], - }); - execute(scheduleCommand); + if (networkId === "1" && !fork) { + console.log(`Please get the following upgrade hash approved: ${chalk.green(upgradeHash)}`); + } else { + console.log(`\n[ ${chalk.green("Scheduling upgrade")} ]\n`); + const scheduleCommand = scheduleUpgrade({ + rpcUrl, + networkId, + upgradeHash, + systemAdminAddress, + mnemonicFile: mnemonicFile, + mnemonicIndex: 0, + fork, + diamondAddress: addresses[networkId], + }); + execute(scheduleCommand); + } console.log(`\n[ ${chalk.green("Preparing upgrade")} ]\n`); const prepCmd = `node ./cli-tools/prep-upgrade.js broadcast/SmartDeploy.s.sol/${networkId}/smartDeploy-latest.json`; @@ -95,16 +100,24 @@ if (operation === "deploy") { networkId, upgradeHash, ownerAddress, - mnemonicFile: "./nayms_mnemonic.txt", - mnemonicIndex: 19, + mnemonicFile: mnemonicFile, + mnemonicIndex: networkId === "1" ? 1 : 19, }); - execute(diamondCutCmd); + if (networkId === "1" && !fork) { + console.log("Execute the following command to cut in the facets, once the upgrade hash is approved"); + console.log(chalk.blue(diamondCutCmd)); + } else { + execute(diamondCutCmd); + } } else { console.log(chalk.red("Supported operations are: 'deploy' and 'upgrade'!")); process.exit(1); } function getUpgradeHash(result) { + if (!result) { + return "not found"; + } const hashLine = result .split("\n") .find((line) => line.includes("upgradeHash: bytes32")) @@ -113,7 +126,7 @@ function getUpgradeHash(result) { return hashLine[hashLine.length - 1]; } -function deployDiamondCmd(rpcUrl, networkId, owner, sysAdmin, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { +function deployDiamond(rpcUrl, networkId, owner, sysAdmin, facetsToCutIn = '"[]"', salt = `0xdeffffffff`) { return smartDeploy({ rpcUrl, networkId, @@ -174,7 +187,7 @@ function smartDeploy(config) { return command; } -function schedule(config) { +function scheduleUpgrade(config) { const isFork = config.networkId === "1" && config.fork; const impersonateIfNeeded = isFork ? `cast rpc anvil_impersonateAccount ${config.systemAdminAddress} && ` : ""; const mnemonicIfNeeded = isFork @@ -192,8 +205,8 @@ function schedule(config) { } function diamondCut(config) { - return `forge script S03UpgradeDiamond \ - -s "run(address)" ${config.ownerAddress} \ + return `forge script S03UpgradeDiamond \\ + -s "run(address)" ${config.ownerAddress} \\ -f ${config.rpcUrl} \\ --chain-id ${config.networkId} \\ --sender ${config.ownerAddress} \\ From 5954ddc0ecb47d99b0916f84c468450a66340f5d Mon Sep 17 00:00:00 2001 From: Aleksandar Marinkovic Date: Fri, 23 Jun 2023 11:05:39 +0200 Subject: [PATCH 8/8] refactor: better logging and argument handling --- cli-tools/deployer.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cli-tools/deployer.js b/cli-tools/deployer.js index 9d25013e..268f0475 100644 --- a/cli-tools/deployer.js +++ b/cli-tools/deployer.js @@ -5,12 +5,20 @@ const dotenv = require("dotenv"); dotenv.config(); -if (process.argv.length <= 3) { - console.error(chalk.red(`Must provide deployment operation and target network!`)); + +if (process.argv.length < 4) { + console.error(chalk.red(`Must provide deployment action and target network!`)); + console.log(`Allowed actions are: ${chalk.green("deploy")} and ${chalk.green("upgrade")}`); process.exit(1); } -const [operation, networkId, ...otherArgs] = process.argv.slice(2); +const [action, networkId, ...otherArgs] = process.argv.slice(2); + +const flags = new Set(["--fork", "--dry-run"]); +if (!otherArgs.every((a) => flags.has(a))) { + console.log(`Allowed flags are only: ${chalk.green("--fork")} and ${chalk.green("--dry-run")}`); + process.exit(1); +} const fork = otherArgs.includes("--fork"); const dryRun = otherArgs.includes("--dry-run"); @@ -25,7 +33,7 @@ const systemAdminAddress = ? "0xE6aD24478bf7E1C0db07f7063A4019C83b1e5929" // mainnet sysAdminB : Wallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/0`).address; // acc1 -if (operation === "deploy") { +if (action === "deploy") { console.log(`[ ${chalk.green(networkId + (fork ? "-fork" : ""))} ] Deploying new diamond`); console.log(`\n[ ${chalk.green("Deploying contracts")} ]\n`); @@ -51,7 +59,7 @@ if (operation === "deploy") { console.log(`\n[ ${chalk.green("Doing upgrade")} ]\n`); const upgradeCmd = upgrade(rpcUrl, networkId, ownerAddress, systemAdminAddress); execute(upgradeCmd); -} else if (operation === "upgrade") { +} else if (action === "upgrade") { const addressesRaw = fs.readFileSync("deployedAddresses.json"); const addresses = JSON.parse(addressesRaw); @@ -110,7 +118,7 @@ if (operation === "deploy") { execute(diamondCutCmd); } } else { - console.log(chalk.red("Supported operations are: 'deploy' and 'upgrade'!")); + console.log(chalk.red("Supported actions are: 'deploy' and 'upgrade'!")); process.exit(1); }