| 
 | 1 | +import { ethers } from 'hardhat';  | 
 | 2 | +import { BigNumber } from 'ethers';  | 
 | 3 | +const hre = require('hardhat');  | 
 | 4 | +const fs = require('fs');  | 
 | 5 | + | 
 | 6 | +async function main() {  | 
 | 7 | +  const output = {  | 
 | 8 | +    walletImplementation: '',  | 
 | 9 | +    walletFactory: '',  | 
 | 10 | +    forwarderImplementation: '',  | 
 | 11 | +    forwarderFactory: ''  | 
 | 12 | +  };  | 
 | 13 | + | 
 | 14 | +  const feeData = await ethers.provider.getFeeData();  | 
 | 15 | + | 
 | 16 | +  const [walletDeployer, forwarderDeployer] = await ethers.getSigners();  | 
 | 17 | + | 
 | 18 | +  const gasParams = {  | 
 | 19 | +    gasPrice: feeData.gasPrice!.mul('2'),  | 
 | 20 | +    gasLimit: 5000000  | 
 | 21 | +  };  | 
 | 22 | +  const walletTxCount = await walletDeployer.getTransactionCount();  | 
 | 23 | + | 
 | 24 | +  console.log('Deploying wallet contracts....');  | 
 | 25 | +  console.log('Wallet Tx Count: ', walletTxCount);  | 
 | 26 | +  const walletSelfTransactions = 2 - walletTxCount;  | 
 | 27 | +  for (let i = 0; i < walletSelfTransactions; i++) {  | 
 | 28 | +    const tx = await walletDeployer.sendTransaction({  | 
 | 29 | +      to: walletDeployer.address,  | 
 | 30 | +      value: ethers.utils.parseEther('0'),  | 
 | 31 | +      gasPrice: gasParams.gasPrice  | 
 | 32 | +    });  | 
 | 33 | +    await tx.wait();  | 
 | 34 | +    console.log(`Self transaction with nonce: ${i} complete`);  | 
 | 35 | +  }  | 
 | 36 | + | 
 | 37 | +  const walletImplementationContractName = 'AvaxcWalletSimple';  | 
 | 38 | +  const walletFactoryContractName = 'WalletFactory';  | 
 | 39 | + | 
 | 40 | +  const WalletImplementation = await ethers.getContractFactory(  | 
 | 41 | +    walletImplementationContractName,  | 
 | 42 | +    walletDeployer  | 
 | 43 | +  );  | 
 | 44 | +  const walletImplementation = await WalletImplementation.deploy(gasParams);  | 
 | 45 | +  await walletImplementation.deployed();  | 
 | 46 | +  output.walletImplementation = walletImplementation.address;  | 
 | 47 | +  console.log(  | 
 | 48 | +    `${walletImplementationContractName} deployed at ` +  | 
 | 49 | +      walletImplementation.address  | 
 | 50 | +  );  | 
 | 51 | + | 
 | 52 | +  const WalletFactory = await ethers.getContractFactory(  | 
 | 53 | +    walletFactoryContractName,  | 
 | 54 | +    walletDeployer  | 
 | 55 | +  );  | 
 | 56 | +  const walletFactory = await WalletFactory.deploy(  | 
 | 57 | +    walletImplementation.address,  | 
 | 58 | +    gasParams  | 
 | 59 | +  );  | 
 | 60 | +  await walletFactory.deployed();  | 
 | 61 | +  output.walletFactory = walletFactory.address;  | 
 | 62 | +  console.log(  | 
 | 63 | +    `${walletFactoryContractName} deployed at ` + walletFactory.address  | 
 | 64 | +  );  | 
 | 65 | + | 
 | 66 | +  const forwarderTxCount = await forwarderDeployer.getTransactionCount();  | 
 | 67 | + | 
 | 68 | +  console.log('Deploying forwarder contracts....');  | 
 | 69 | +  console.log('Forwarder Tx Count: ', forwarderTxCount);  | 
 | 70 | +  const forwarderSelfTransactions = 234 - forwarderTxCount;  | 
 | 71 | + | 
 | 72 | +  for (let i = 0; i < forwarderSelfTransactions; i++) {  | 
 | 73 | +    const tx = await forwarderDeployer.sendTransaction({  | 
 | 74 | +      to: forwarderDeployer.address,  | 
 | 75 | +      value: ethers.utils.parseEther('0'),  | 
 | 76 | +      gasPrice: gasParams.gasPrice  | 
 | 77 | +    });  | 
 | 78 | +    await tx.wait();  | 
 | 79 | +    console.log(`Self transaction with nonce: ${i} complete`);  | 
 | 80 | +  }  | 
 | 81 | + | 
 | 82 | +  const forwarderImplementationContractName = 'Forwarder';  | 
 | 83 | +  const forwarderFactoryContractName = 'ForwarderFactory';  | 
 | 84 | + | 
 | 85 | +  const ForwarderImplementation = await ethers.getContractFactory(  | 
 | 86 | +    forwarderImplementationContractName,  | 
 | 87 | +    forwarderDeployer  | 
 | 88 | +  );  | 
 | 89 | + | 
 | 90 | +  const forwarderImplementation = await ForwarderImplementation.deploy(  | 
 | 91 | +    gasParams  | 
 | 92 | +  );  | 
 | 93 | +  await forwarderImplementation.deployed();  | 
 | 94 | +  output.forwarderImplementation = forwarderImplementation.address;  | 
 | 95 | + | 
 | 96 | +  console.log(  | 
 | 97 | +    `${forwarderImplementationContractName} deployed at ` +  | 
 | 98 | +      forwarderImplementation.address  | 
 | 99 | +  );  | 
 | 100 | + | 
 | 101 | +  const ForwarderFactory = await ethers.getContractFactory(  | 
 | 102 | +    forwarderFactoryContractName,  | 
 | 103 | +    forwarderDeployer  | 
 | 104 | +  );  | 
 | 105 | + | 
 | 106 | +  const forwarderFactory = await ForwarderFactory.deploy(  | 
 | 107 | +    forwarderImplementation.address,  | 
 | 108 | +    gasParams  | 
 | 109 | +  );  | 
 | 110 | + | 
 | 111 | +  await forwarderFactory.deployed();  | 
 | 112 | +  output.forwarderFactory = forwarderFactory.address;  | 
 | 113 | +  console.log(  | 
 | 114 | +    `${forwarderFactoryContractName} deployed at ` + forwarderFactory.address  | 
 | 115 | +  );  | 
 | 116 | + | 
 | 117 | +  fs.writeFileSync('output.json', JSON.stringify(output));  | 
 | 118 | + | 
 | 119 | +  // Wait 5 minutes. It takes some time for the etherscan backend to index the transaction and store the contract.  | 
 | 120 | +  console.log('Waiting for 5 minutes before verifying....');  | 
 | 121 | +  await new Promise((r) => setTimeout(r, 1000 * 300));  | 
 | 122 | + | 
 | 123 | +  // We have to wait for a minimum of 10 block confirmations before we can call the etherscan api to verify  | 
 | 124 | + | 
 | 125 | +  await walletImplementation.deployTransaction.wait(10);  | 
 | 126 | +  await walletFactory.deployTransaction.wait(10);  | 
 | 127 | +  await forwarderImplementation.deployTransaction.wait(10);  | 
 | 128 | +  await forwarderFactory.deployTransaction.wait(10);  | 
 | 129 | + | 
 | 130 | +  console.log('Done waiting, verifying');  | 
 | 131 | +  await verifyContract(  | 
 | 132 | +    walletImplementationContractName,  | 
 | 133 | +    walletImplementation.address,  | 
 | 134 | +    []  | 
 | 135 | +  );  | 
 | 136 | +  await verifyContract('WalletFactory', walletFactory.address, [  | 
 | 137 | +    walletImplementation.address  | 
 | 138 | +  ]);  | 
 | 139 | + | 
 | 140 | +  await verifyContract(  | 
 | 141 | +    forwarderImplementationContractName,  | 
 | 142 | +    forwarderImplementation.address,  | 
 | 143 | +    []  | 
 | 144 | +  );  | 
 | 145 | + | 
 | 146 | +  await verifyContract('ForwarderFactory', forwarderFactory.address, [  | 
 | 147 | +    forwarderImplementation.address  | 
 | 148 | +  ]);  | 
 | 149 | + | 
 | 150 | +  console.log('Contracts verified');  | 
 | 151 | +}  | 
 | 152 | + | 
 | 153 | +async function verifyContract(  | 
 | 154 | +  contractName: string,  | 
 | 155 | +  contractAddress: string,  | 
 | 156 | +  constructorArguments: string[],  | 
 | 157 | +  contract?: string  | 
 | 158 | +) {  | 
 | 159 | +  try {  | 
 | 160 | +    const verifyContractArgs: {  | 
 | 161 | +      address: string;  | 
 | 162 | +      constructorArguments: string[];  | 
 | 163 | +      contract?: string;  | 
 | 164 | +    } = {  | 
 | 165 | +      address: contractAddress,  | 
 | 166 | +      constructorArguments: constructorArguments  | 
 | 167 | +    };  | 
 | 168 | + | 
 | 169 | +    if (contract) {  | 
 | 170 | +      verifyContractArgs.contract = contract;  | 
 | 171 | +    }  | 
 | 172 | + | 
 | 173 | +    await hre.run('verify:verify', verifyContractArgs);  | 
 | 174 | +  } catch (e) {  | 
 | 175 | +    // @ts-ignore  | 
 | 176 | +    // We get a failure API response if the source code has already been uploaded, don't throw in this case.  | 
 | 177 | +    if (!e.message.includes('Reason: Already Verified')) {  | 
 | 178 | +      throw e;  | 
 | 179 | +    }  | 
 | 180 | +  }  | 
 | 181 | +  console.log(`Verified ${contractName} on Etherscan!`);  | 
 | 182 | +}  | 
 | 183 | + | 
 | 184 | +main().catch((error) => {  | 
 | 185 | +  console.error(error);  | 
 | 186 | +  process.exitCode = 1;  | 
 | 187 | +});  | 
0 commit comments