From bd4db8b6afa9a64d3956650e2ac2c3eff46546cd Mon Sep 17 00:00:00 2001 From: Shirren Date: Mon, 18 Dec 2023 21:42:30 +1100 Subject: [PATCH] More work to scripts to prep for mainnet --- hardhat.config.ts | 1 - package.json | 4 -- scripts/README.md | 16 +++++-- scripts/contract.ts | 68 +++++++++++++++++++++++++++ scripts/deploy.ts | 92 ++++++++++++------------------------- scripts/environment.ts | 8 ++-- scripts/helper-functions.ts | 13 +++++- scripts/step1.ts | 57 +++++++++++++++++++++++ scripts/step2.ts | 51 ++++++++++++++++++++ scripts/step3.ts | 44 ++++++++++++++++++ scripts/step4.ts | 51 ++++++++++++++++++++ scripts/step5.ts | 47 +++++++++++++++++++ scripts/step6.ts | 63 +++++++++++++++++++++++++ tsconfig.json | 18 ++++---- 14 files changed, 448 insertions(+), 85 deletions(-) create mode 100644 scripts/contract.ts create mode 100644 scripts/step1.ts create mode 100644 scripts/step2.ts create mode 100644 scripts/step3.ts create mode 100644 scripts/step4.ts create mode 100644 scripts/step5.ts create mode 100644 scripts/step6.ts diff --git a/hardhat.config.ts b/hardhat.config.ts index 711d187..7e432cf 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,7 +15,6 @@ dotenv.config(); loadAndValidateEnvironment(); const config: HardhatUserConfig = { - defaultNetwork: "localhost", solidity: { compilers: [{ version: '0.8.17' }], settings: { diff --git a/package.json b/package.json index 0fb44f0..f96bdac 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,6 @@ "stop:ganache": "ps aux | grep ganache | grep -v grep | awk '{print $2}' | xargs kill -9", "deploy:ganache": "hardhat run --network ganache utils/deploy-contracts.ts", "deploy": "hardhat run utils/deploy-contracts.ts --network", - "deployToLocal": "npx hardhat run scripts/deploy.ts --network localhost", - "deployToDevnet": "npx hardhat run scripts/deploy.ts --network devnet", - "deployToTestnet": "npx hardhat run scripts/deploy.ts --network testnet", - "deployToMainnet": "npx hardhat run scripts/deploy.ts --network mainnet", "verify": "hardhat verify --network", "release": "yarn publish src" }, diff --git a/scripts/README.md b/scripts/README.md index 4cdcb2b..b3c25b3 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -7,9 +7,19 @@ only entity allowed to call the deploy function on the contract; 1. forge create --rpc-url --constructor-args "" --legacy --hd-path "m/44'/60'/0'/0/0" src/OwnableCreate2Deployer.sol:OwnableCreate2Deployer. 4. Set the value of DEPLOYER_CONTRACT_ADDRESS in the environment to equal the address of the OwnableCreate2Deployer contract deployed of step 3 above. 5. Set the deployer key to be a unique value for the run. -6. Execute the command `npx npm run deployToLocal` - 1. IMPORTANT: Remember to copy the correct `.env.X` file into `.env` before execution. -7. Edit the following environment variables in the Relayer in the `.env.local` and `local-deployment.yaml` files +6. Copy the relevant `.env.X` file to `.env`. For example in the case of Devnet `cp .env.devnet .env` +7. Execute the command `npx hardhat run scripts/step1.ts --network ` +8. Execute the command `npx hardhat run scripts/step2.ts --network ` +9. Execute the command `npx hardhat run scripts/step3.ts --network ` + 1. WARNING: COPY the `LatestWalletImplLocator` address into the `step3.ts` script from step2. +10. Execute the command `npx hardhat run scripts/step4.ts --network ` + 1. WARNING: COPY the `FactoryAddress` address into the `step4.ts` script from step1. + 2. WARNING: COPY the `StartupWalletImpl` address into the `step4.ts` script from step3. +11. Execute the command `npx hardhat run scripts/step5.ts --network ` +12. Execute the command `npx hardhat run scripts/step6.ts --network ` + 1. WARNING: COPY the `MainModuleDynamicAuth` address into the `step6.ts` script from step4. + 1. WARNING: COPY the `LatestWalletImplLocator` address into the `step6.ts` script from step2. +13. Edit the following environment variables in the Relayer in the `.env.local` and `local-deployment.yaml` files 1. DEPLOY_AND_EXECUTE_ADDRESS to equal the address of the `MultiCallDeploy` 2. FACTORY_ADDRESS to equal the address of the `Factory` 3. MAIN_MODULE_ADDRESS to equal the address of the `StartupWalletImpl` diff --git a/scripts/contract.ts b/scripts/contract.ts new file mode 100644 index 0000000..b86ec61 --- /dev/null +++ b/scripts/contract.ts @@ -0,0 +1,68 @@ +import { BytesLike, Contract, ContractFactory, utils } from 'ethers'; + +import { EnvironmentInfo } from './environment'; +import { newContractFactory } from './helper-functions'; +import { WalletOptions } from './wallet-options'; +import ContractDeployerInterface from './abi/OwnableCreate2Deployer.json'; + +// Key for the salt, use this to change the address of the contract + +/** + * We use the key to generate a salt to generate a deterministic address for + * the contract that isn't dependent on the nonce of the contract deployer account. +*/ +const getSaltFromKey = (): string => { + let key: string = 'relayer-deployer-key-2'; + return utils.keccak256(utils.defaultAbiCoder.encode(['string'], [key])); +}; + +/** + * Load the OwnableCreate2Deployer + */ +const loadDeployerContract = async (env: EnvironmentInfo, walletOptions: WalletOptions): Promise => { + return new Contract(env.deployerContractAddress, ContractDeployerInterface.abi, walletOptions.getWallet()); +} + +/** + * Deploy the contract using the OwnableCreate2Deployer contract. + */ +export async function deployContractViaCREATE2( + env: EnvironmentInfo, + walletsOptions: WalletOptions, + contractName: string, + constructorArgs: Array): Promise { + + const salt: string = getSaltFromKey(); + const deployer: Contract = await loadDeployerContract(env, walletsOptions); + const contractFactory: ContractFactory = await newContractFactory(walletsOptions.getWallet(), contractName); + const bytecode: BytesLike | undefined = contractFactory.getDeployTransaction(...constructorArgs).data; + + // Deploy the contract + let tx = await deployer.deploy(bytecode, salt, { + gasLimit: 30000000, + maxFeePerGas: 10000000000, + maxPriorityFeePerGas: 10000000000, + }); + await tx.wait(); + + // Calculate the address the contract is deployed to, and attach to return it + const contractAddress = await deployer.deployedAddress(bytecode, await walletsOptions.getWallet().getAddress(), salt); + console.log(`[${env.network}] Deployed ${contractName} to ${contractAddress}`); + + return contractFactory.attach(contractAddress); +} + +/** + * Deploy the contract via a wallet + */ +export async function deployContract( + env: EnvironmentInfo, + walletsOptions: WalletOptions, + contractName: string, + constructorArgs: Array): Promise { + + const contractFactory: ContractFactory = await newContractFactory(walletsOptions.getWallet(), contractName); + const contract: Contract = await contractFactory.connect(walletsOptions.getWallet()).deploy(...constructorArgs); + console.log(`[${env.network}] Deployed ${contractName} to ${contract.address}`); + return contract; +} \ No newline at end of file diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 26d0d72..8149818 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -1,57 +1,10 @@ import * as fs from 'fs'; import * as hre from 'hardhat'; -import { BytesLike, Contract, ContractFactory, utils } from 'ethers'; import { ethers as hardhat } from 'hardhat'; import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; -import { newContractFactory } from './helper-functions'; import { newWalletOptions, WalletOptions } from './wallet-options'; -import ContractDeployerInterface from './abi/OwnableCreate2Deployer.json'; - -/** - * We use the key to generate a salt to generate a deterministic address for - * the contract that isn't dependent on the nonce of the contract deployer account. - */ -const getSaltFromKey = (key: string): string => { - return utils.keccak256(utils.defaultAbiCoder.encode(['string'], [key])); -}; - -/** - * Load the OwnableCreate2Deployer - */ -const loadDeployerContract = async (env: EnvironmentInfo, walletOptions: WalletOptions): Promise => { - return new Contract(env.deployerContractAddress, ContractDeployerInterface.abi, walletOptions.getWallet()); -} - -/** - * Deploy the contract using the OwnableCreate2Deployer contract. - */ -async function deployContract( - env: EnvironmentInfo, - walletsOptions: WalletOptions, - deployerKey: string, - contractName: string, - constructorArgs: Array): Promise { - - const salt: string = getSaltFromKey(deployerKey); - const deployer: Contract = await loadDeployerContract(env, walletsOptions); - const contractFactory: ContractFactory = await newContractFactory(walletsOptions.getWallet(), contractName); - const bytecode: BytesLike | undefined = contractFactory.getDeployTransaction(...constructorArgs).data; - - // Deploy the contract - let tx = await deployer.deploy(bytecode, salt, { - gasLimit: 30000000, - maxFeePerGas: 10000000000, - maxPriorityFeePerGas: 10000000000, - }); - await tx.wait(); - - // Calculate the address the contract is deployed to, and attach to return it - const contractAddress = await deployer.deployedAddress(bytecode, await walletsOptions.getWallet().getAddress(), salt); - console.log(`[${env.network}] Deployed ${contractName} to ${contractAddress} with hash ${tx.hash}`); - - return contractFactory.attach(contractAddress); -} +import { deployContractViaCREATE2 } from './contract'; /** * main function deploys all the SCW infrastructure. @@ -68,8 +21,6 @@ async function main(): Promise { // Administration accounts let multiCallAdminPubKey = '0x575be326c482a487add43974e0eaf232e3366e13'; let factoryAdminPubKey = '0xddb70ddcd14dbd57ae18ec591f47454e4fc818bb'; - - // CHANGEME: When deploying to mainnet, this address needs to match the second address from the wallet let walletImplLocatorAdmin = '0xb49c99a17776c10350c2be790e13d4d8dfb1c578'; let signerRootAdminPubKey = '0x65af83f71a05d7f6d06ef9a57c9294b4128ccc2c'; let signerAdminPubKey = '0x69d09644159e7327dbfd0af9a66f8e332c593e79'; @@ -82,28 +33,45 @@ async function main(): Promise { console.log(`[${network}] Deploying contracts...`); + // Addresses that need to be pre-determined + // 1. Factory + // 2. StartupWalletImpl + // 3. SignerContract + // Key for the salt, use this to change the address of the contract let key: string = 'relayer-deployer-key-1'; - // 1. Deploy multi call deploy - const multiCallDeploy = await deployContract(env, wallets, key, 'MultiCallDeploy', [multiCallAdminPubKey, submitterAddress]); + // --- STEP 1: Deployed using Passport Nonce Reserver. + + // 1. Deploy multi call deploy (PNR) + const multiCallDeploy = await deployContractViaCREATE2(env, wallets, 'MultiCallDeploy', [multiCallAdminPubKey, submitterAddress]); - // 2. Deploy factory with multi call deploy address as deployer role EST - const factory = await deployContract(env, wallets, key, 'Factory', [factoryAdminPubKey, multiCallDeploy.address]); + // 2. Deploy factory with multi call deploy address as deployer role EST (PNR) + const factory = await deployContractViaCREATE2(env, wallets, 'Factory', [factoryAdminPubKey, multiCallDeploy.address]); - // 3. Deploy wallet impl locator - const walletImplLocator = await deployContract(env, wallets, key, 'LatestWalletImplLocator', [ + // --- Step 2: Deployed using CREATE2 Factory + + // 3. Deploy wallet impl locator (CFC) + const walletImplLocator = await deployContractViaCREATE2(env, wallets, 'LatestWalletImplLocator', [ walletImplLocatorAdmin, await wallets.getWalletImplLocatorChanger().getAddress() ]); - // 4. Deploy startup wallet impl - const startupWalletImpl = await deployContract(env, wallets, key, 'StartupWalletImpl', [walletImplLocator.address]); + // --- Step 3: Deployed using Passport Nonce Reserver. + + // 4. Deploy startup wallet impl (PNR) + const startupWalletImpl = await deployContractViaCREATE2(env, wallets, 'StartupWalletImpl', [walletImplLocator.address]); + + // --- Step 4: Deployed using CREATE2 Factory. + + // 5. Deploy main module dynamic auth (CFC) + const mainModuleDynamicAuth = await deployContractViaCREATE2(env, wallets, 'MainModuleDynamicAuth', [factory.address, startupWalletImpl.address]); + + // --- Step 5: Deployed using Passport Nonce Reserver. - // 5. Deploy main module dynamic auth - const mainModuleDynamicAuth = await deployContract(env, wallets, key, 'MainModuleDynamicAuth', [factory.address, startupWalletImpl.address]); + // 6. Deploy immutable signer (PNR) + const immutableSigner = await deployContractViaCREATE2(env, wallets, 'ImmutableSigner', [signerRootAdminPubKey, signerAdminPubKey, signerAddress]); - // 6. Deploy immutable signer - const immutableSigner = await deployContract(env, wallets, key, 'ImmutableSigner', [signerRootAdminPubKey, signerAdminPubKey, signerAddress]); + // --- Step 6: Deployed using alternate wallet (?) // Fund the implementation changer // WARNING: If the deployment fails at this step, DO NOT RERUN without commenting out the code a prior which deploys the contracts. diff --git a/scripts/environment.ts b/scripts/environment.ts index ee6fb62..5e9c682 100644 --- a/scripts/environment.ts +++ b/scripts/environment.ts @@ -5,8 +5,8 @@ import * as path from 'path'; * and signer address. */ export interface EnvironmentInfo { - submitterAddress?: string; - signerAddress?: string; + submitterAddress: string; + signerAddress: string; deployerContractAddress: string; outputPath: string; network: string; @@ -22,8 +22,8 @@ export interface EnvironmentInfo { **/ export function loadEnvironmentInfo(hreNetworkName: string): EnvironmentInfo { return { - submitterAddress: process.env.RELAYER_SUBMITTER_EOA_PUB_KEY, - signerAddress: process.env.IMMUTABLE_SIGNER_PUB_KEY, + submitterAddress: process.env.RELAYER_SUBMITTER_EOA_PUB_KEY || '', + signerAddress: process.env.IMMUTABLE_SIGNER_PUB_KEY || '', deployerContractAddress: process.env.DEPLOYER_CONTRACT_ADDRESS || '', outputPath: path.join(__dirname, process.env.OUTPUT_FILE_NAME || ''), network: hreNetworkName diff --git a/scripts/helper-functions.ts b/scripts/helper-functions.ts index 23a974c..b7c00c1 100644 --- a/scripts/helper-functions.ts +++ b/scripts/helper-functions.ts @@ -1,6 +1,5 @@ +import * as readline from 'readline'; import { ethers as hardhat } from 'hardhat'; - -import { WalletOptions } from './wallet-options'; import { ContractFactory, Signer } from 'ethers'; /** @@ -10,3 +9,13 @@ import { ContractFactory, Signer } from 'ethers'; export async function newContractFactory(signer: Signer, contractName: string): Promise { return (await hardhat.getContractFactory(contractName)).connect(signer); } + +export async function waitForInput() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + const it = rl[Symbol.asyncIterator](); + await it.next(); +} \ No newline at end of file diff --git a/scripts/step1.ts b/scripts/step1.ts new file mode 100644 index 0000000..3b6fa17 --- /dev/null +++ b/scripts/step1.ts @@ -0,0 +1,57 @@ +import * as fs from 'fs'; +import * as hre from 'hardhat'; +import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; +import { newWalletOptions, WalletOptions } from './wallet-options'; +import { deployContract } from './contract'; +import { waitForInput } from './helper-functions'; + +// Addresses that need to be pre-determined +// 1. Factory +// 2. StartupWalletImpl +// 3. SignerContract + +/** + * Step 1. + **/ +async function step1(): Promise { + const env = loadEnvironmentInfo(hre.network.name); + const { network, submitterAddress, signerAddress, } = env; + const multiCallAdminPubKey = '0x575be326c482a487add43974e0eaf232e3366e13'; + const factoryAdminPubKey = '0xddb70ddcd14dbd57ae18ec591f47454e4fc818bb'; + + console.log(`[${network}] Starting deployment...`); + console.log(`[${network}] Submitter address ${submitterAddress}`); + console.log(`[${network}] Signer address ${signerAddress}`); + console.log(`[${network}] multiCallAdminPubKey ${multiCallAdminPubKey}`); + console.log(`[${network}] factoryAdminPubKey ${factoryAdminPubKey}`); + + await waitForInput(); + + // Setup wallet + const wallets: WalletOptions = await newWalletOptions(env); + + // --- STEP 1: Deployed using Passport Nonce Reserver. + // Deploy multi call deploy (PNR) + const multiCallDeploy = await deployContract(env, wallets, 'MultiCallDeploy', [multiCallAdminPubKey, submitterAddress]); + + // Deploy factory with multi call deploy address as deployer role EST (PNR) + const factory = await deployContract(env, wallets, 'Factory', [factoryAdminPubKey, multiCallDeploy.address]); + + fs.writeFileSync('step1.json', JSON.stringify({ + multiCallDeploy: multiCallDeploy.address, + factory: factory.address, + }, null, 1)); + + return env; +} + +// Call primary function +step1() + .then((env: EnvironmentInfo) => { + console.log(`[${env.network}] Contracts deployment successful...`); + process.exit(0); + }) + .catch(err => { + console.error(err.message); + process.exit(1); + }); diff --git a/scripts/step2.ts b/scripts/step2.ts new file mode 100644 index 0000000..df0748a --- /dev/null +++ b/scripts/step2.ts @@ -0,0 +1,51 @@ +import * as fs from 'fs'; +import * as hre from 'hardhat'; +import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; +import { newWalletOptions, WalletOptions } from './wallet-options'; +import { deployContractViaCREATE2 } from './contract'; +import { waitForInput } from './helper-functions'; + +/** + * Step 2 + **/ +async function step2(): Promise { + const env = loadEnvironmentInfo(hre.network.name); + const { network, deployerContractAddress } = env; + + console.log(`[${network}] Starting deployment...`); + console.log(`[${network}] CREATE2 Factory address ${deployerContractAddress}`); + + await waitForInput(); + + // Administration accounts + // Is this correct for Mainnet? + let walletImplLocatorAdmin = '0xb49c99a17776c10350c2be790e13d4d8dfb1c578'; + + // Setup wallet + const wallets: WalletOptions = await newWalletOptions(env); + console.log( + `[${network}] Wallet Impl Locator Changer Address: ${await wallets.getWalletImplLocatorChanger().getAddress()}` + ); + + // --- Step 2: Deployed using CREATE2 Factory + const latestWalletImplLocator = await deployContractViaCREATE2(env, wallets, 'LatestWalletImplLocator', [ + walletImplLocatorAdmin, await wallets.getWalletImplLocatorChanger().getAddress() + ]); + + fs.writeFileSync('step2.json', JSON.stringify({ + latestWalletImplLocator: latestWalletImplLocator.address, + }, null, 1)); + + return env; +} + +// Call primary function +step2() + .then((env: EnvironmentInfo) => { + console.log(`[${env.network}] Contracts deployment successful...`); + process.exit(0); + }) + .catch(err => { + console.error(err.message); + process.exit(1); + }); diff --git a/scripts/step3.ts b/scripts/step3.ts new file mode 100644 index 0000000..88221f1 --- /dev/null +++ b/scripts/step3.ts @@ -0,0 +1,44 @@ +import * as fs from 'fs'; +import * as hre from 'hardhat'; +import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; +import { newWalletOptions, WalletOptions } from './wallet-options'; +import { deployContract } from './contract'; +import { waitForInput } from './helper-functions'; + +/** + * Step 3 + **/ +async function step3(): Promise { + const env = loadEnvironmentInfo(hre.network.name); + const { network } = env; + const walletImplLocatorAddress = ''; + + console.log(`[${network}] Starting deployment...`); + console.log(`[${network}] WalletImplLocator address ${walletImplLocatorAddress}`); + + await waitForInput(); + + // Setup wallet + const wallets: WalletOptions = await newWalletOptions(env); + + // --- Step 3: Deployed using Passport Nonce Reserver. + // Deploy startup wallet impl (PNR) + const startupWalletImpl = await deployContract(env, wallets, 'StartupWalletImpl', [walletImplLocatorAddress]); + + fs.writeFileSync('step3.json', JSON.stringify({ + startupWalletImpl: startupWalletImpl.address, + }, null, 1)); + + return env; +} + +// Call primary function +step3() + .then((env: EnvironmentInfo) => { + console.log(`[${env.network}] Contracts deployment successful...`); + process.exit(0); + }) + .catch(err => { + console.error(err.message); + process.exit(1); + }); diff --git a/scripts/step4.ts b/scripts/step4.ts new file mode 100644 index 0000000..668424f --- /dev/null +++ b/scripts/step4.ts @@ -0,0 +1,51 @@ +import * as fs from 'fs'; +import * as hre from 'hardhat'; +import { waitForInput } from './helper-functions'; +import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; +import { newWalletOptions, WalletOptions } from './wallet-options'; +import { deployContractViaCREATE2 } from './contract'; + +/** + * Step 4 + **/ +async function step4(): Promise { + const env = loadEnvironmentInfo(hre.network.name); + const { network } = env; + const factoryAddress = ''; + const startupWalletImplAddress = ''; + + console.log(`[${network}] Starting deployment...`); + console.log(`[${network}] Factory address ${factoryAddress}`); + console.log(`[${network}] StartupWalletImpl address ${startupWalletImplAddress}`); + + await waitForInput(); + + // Setup wallet + const wallets: WalletOptions = await newWalletOptions(env); + + // Addresses that need to be pre-determined + // 1. Factory + // 2. StartupWalletImpl + // 3. SignerContract + + // --- Step 4: Deployed using CREATE2 Factory. + // Deploy main module dynamic auth (CFC) + const mainModuleDynamicAuth = await deployContractViaCREATE2(env, wallets, 'MainModuleDynamicAuth', [factoryAddress, startupWalletImplAddress]); + + fs.writeFileSync('step4.json', JSON.stringify({ + mainModuleDynamicAuth: mainModuleDynamicAuth.address, + }, null, 1)); + + return env; +} + +// Call primary function +step4() + .then((env: EnvironmentInfo) => { + console.log(`[${env.network}] Contracts deployment successful...`); + process.exit(0); + }) + .catch(err => { + console.error(err.message); + process.exit(1); + }); diff --git a/scripts/step5.ts b/scripts/step5.ts new file mode 100644 index 0000000..5e94438 --- /dev/null +++ b/scripts/step5.ts @@ -0,0 +1,47 @@ +import * as fs from 'fs'; +import * as hre from 'hardhat'; +import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; +import { newWalletOptions, WalletOptions } from './wallet-options'; +import { deployContract } from './contract'; +import { waitForInput } from './helper-functions'; + +/** + * main function deploys all the SCW infrastructure. + **/ +async function step5(): Promise { + const env = loadEnvironmentInfo(hre.network.name); + const { network, submitterAddress, signerAddress, } = env; + const signerRootAdminPubKey = '0x65af83f71a05d7f6d06ef9a57c9294b4128ccc2c'; + const signerAdminPubKey = '0x69d09644159e7327dbfd0af9a66f8e332c593e79'; + + console.log(`[${network}] Starting deployment...`); + console.log(`[${network}] SignerRootAdmin address ${signerRootAdminPubKey}`); + console.log(`[${network}] SignerAdmin address ${signerAdminPubKey}`); + console.log(`[${network}] Signer address ${signerAddress}`); + + await waitForInput(); + + // Setup wallet + const wallets: WalletOptions = await newWalletOptions(env); + + // --- Step 5: Deployed using Passport Nonce Reserver. + // Deploy immutable signer (PNR) + const immutableSigner = await deployContract(env, wallets, 'ImmutableSigner', [signerRootAdminPubKey, signerAdminPubKey, signerAddress]); + + fs.writeFileSync('step5.json', JSON.stringify({ + immutableSigner: immutableSigner.address, + }, null, 1)); + + return env; +} + +// Call primary function +step5() + .then((env: EnvironmentInfo) => { + console.log(`[${env.network}] Contracts deployment successful...`); + process.exit(0); + }) + .catch(err => { + console.error(err.message); + process.exit(1); + }); diff --git a/scripts/step6.ts b/scripts/step6.ts new file mode 100644 index 0000000..ab562bb --- /dev/null +++ b/scripts/step6.ts @@ -0,0 +1,63 @@ +import * as hre from 'hardhat'; +import { Contract, ContractFactory, utils } from 'ethers'; +import { newContractFactory, waitForInput } from './helper-functions'; +import { EnvironmentInfo, loadEnvironmentInfo } from './environment'; +import { newWalletOptions, WalletOptions } from './wallet-options'; + +/** + * Step 6 + **/ +async function step6(): Promise { + const env = loadEnvironmentInfo(hre.network.name); + const { network, submitterAddress, signerAddress, } = env; + const mainModuleDynamicAuthAddress = ''; + const walletImplLocatorContractAddress = ''; + + console.log(`[${network}] Starting deployment...`); + console.log(`[${network}] mainModuleDynamicAuth address ${mainModuleDynamicAuthAddress}`); + console.log(`[${network}] walletImplLocatorContract address ${walletImplLocatorContractAddress}`); + console.log(`[${network}] Signer address ${signerAddress}`); + + await waitForInput(); + + // Setup wallet + const wallets: WalletOptions = await newWalletOptions(env); + console.log( + `[${network}] Wallet Impl Locator Changer Address: ${await wallets.getWalletImplLocatorChanger().getAddress()}` + ); + + // --- Step 6: Deployed using alternate wallet + // Fund the implementation changer + // WARNING: If the deployment fails at this step, DO NOT RERUN without commenting out the code a prior which deploys the contracts. + const fundingTx = await wallets.getWallet().sendTransaction({ + to: await wallets.getWalletImplLocatorChanger().getAddress(), + value: utils.parseEther('10'), + gasLimit: 30000000, + maxFeePerGas: 10000000000, + maxPriorityFeePerGas: 10000000000, + }); + await fundingTx.wait(); + console.log(`[${network}] Transfered funds to the wallet locator implementer changer with hash ${fundingTx.hash}`); + + // Set implementation address on impl locator to dynamic module auth addr + const contractFactory: ContractFactory = await newContractFactory(wallets.getWallet(), 'LatestWalletImplLocator'); + const walletImplLocator: Contract = contractFactory.attach(walletImplLocatorContractAddress); + const tx = await walletImplLocator + .connect(wallets.getWalletImplLocatorChanger()) + .changeWalletImplementation(mainModuleDynamicAuthAddress); + await tx.wait(); + console.log(`[${network}] Wallet Impl Locator implementation changed to: ${mainModuleDynamicAuthAddress}`); + + return env; +} + +// Call primary function +step6() + .then((env: EnvironmentInfo) => { + console.log(`[${env.network}] Contracts deployment successful...`); + process.exit(0); + }) + .catch(err => { + console.error(err.message); + process.exit(1); + }); diff --git a/tsconfig.json b/tsconfig.json index 3915d06..b2f680b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,6 @@ "downlevelIteration": true, "removeComments": false, "skipLibCheck": true, - "strictNullChecks": true, "noImplicitUseStrict": true, "noImplicitAny": false, @@ -18,27 +17,28 @@ "noUnusedParameters": false, "noErrorTruncation": true, "esModuleInterop": true, - "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "allowJs": false, "checkJs": false, - "baseUrl": ".", "outDir": "build", - "lib": ["es2020", "dom"], - + "lib": [ + "es2020", + "dom" + ], "typeRoots": [ "./node_modules/@types" ] }, - "include": [ - "./hardhat.config.ts", "typings", "tests", "utils" + "./hardhat.config.ts", + "typings", + "tests", + "utils" ], - "exclude": [ "node_modules", "dist" ] -} +} \ No newline at end of file