diff --git a/contracts/.env.example b/contracts/.env.example index 44d2f5d6..d84df08e 100644 --- a/contracts/.env.example +++ b/contracts/.env.example @@ -9,7 +9,6 @@ OPTIMISM_TESETNET_URL=https://kovan.optimism.io OPTIMISM_URL= # Only used for deploying the deployer contract at the same address on each evm network -DEPLOYER_DEPLOYMENT=false DEPLOYER_MNEMONIC= DEPLOYER_SET_INDEX=1 DEPLOYER_ACCOUNT=0xFD55C6Eb365C832a7a292aeE61754eB1BFb8c666, diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index fffb27f2..400db547 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -19,25 +19,12 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { } }); - -// Account used to deploy the deployer contract at the same address on each network -const deployerAccount = { - mnemonic: `${process.env.DEPLOYER_MNEMONIC}`, - initialIndex: Number.parseInt(process.env.DEPLOYER_SET_INDEX!), - count: 1 -}; - // Accounts used for testing and deploying -const mainAccounts = { +const accounts = { mnemonic: `${process.env.MAIN_MNEMONIC}`, count: 5 } -const accounts = ( - `${process.env.DEPLOYER_DEPLOYMENT}` === `true` - ? deployerAccount : mainAccounts -); - const config: HardhatUserConfig = { solidity: { compilers: [ diff --git a/contracts/shared/helpers/create2Contract.ts b/contracts/shared/helpers/Create2Fixture.ts similarity index 91% rename from contracts/shared/helpers/create2Contract.ts rename to contracts/shared/helpers/Create2Fixture.ts index 2704b9f8..df562255 100644 --- a/contracts/shared/helpers/create2Contract.ts +++ b/contracts/shared/helpers/Create2Fixture.ts @@ -6,15 +6,15 @@ import { Wallet, BigNumber, Contract, ContractFactory } from "ethers"; import deployerContract from "./deployDeployer"; import { Create2Deployer } from "../../typechain"; -export default class Create2Factory { +export default class Create2Fixture { private constructor( public deployerWallet?: Wallet ) {} static create( - ): Create2Factory { - return new Create2Factory( + ): Create2Fixture { + return new Create2Fixture( ethers.Wallet.fromMnemonic( `${process.env.DEPLOYER_MNEMONIC}`, `m/44'/60'/0'/0/${process.env.DEPLOYER_SET_INDEX}` @@ -43,7 +43,7 @@ export default class Create2Factory { }); // If deployer contract doesn't exist at expected address, deploy it there - if (Create2Factory.hasContract(deployerAddress)) { + if (Create2Fixture.hasContract(deployerAddress)) { await (await Create2Deployer.deploy()).deployed(); } @@ -68,13 +68,13 @@ export default class Create2Factory { * @returns */ async create2Contract( - factory: ContractFactory, + contractName: string, constructorParamsBytes: string = "0x", salt: BigNumber = BigNumber.from(0) ): Promise { let create2Deployer = await deployerContract(); - + let factory = await ethers.getContractFactory(contractName) let initCode = factory.bytecode + constructorParamsBytes.substr(2); const initCodeHash = ethers.utils.solidityKeccak256( ["bytes"], diff --git a/contracts/shared/helpers/Fixture.ts b/contracts/shared/helpers/Fixture.ts index cc1fa2b9..a440a2c4 100644 --- a/contracts/shared/helpers/Fixture.ts +++ b/contracts/shared/helpers/Fixture.ts @@ -12,6 +12,8 @@ import createBLSWallet from "./createBLSWallet"; import blsSignFunction from "./blsSignFunction"; import blsKeyHash from "./blsKeyHash"; import { exit, send } from "process"; +import Create2Fixture from "./Create2Fixture"; +import { BLSExpander, BLSWallet__factory, VerificationGateway } from "../../typechain"; const DOMAIN_HEX = utils.keccak256("0xfeedbee5"); const DOMAIN = arrayify(DOMAIN_HEX); @@ -52,13 +54,10 @@ export default class Fixture { public blsSigners: BlsSignerInterface[], // private deployerWallet: Wallet, - public VerificationGateway: ContractFactory, - public verificationGateway: Contract, + public verificationGateway: VerificationGateway, + public blsExpander: BLSExpander, - public BLSExpander: ContractFactory, - public blsExpander: Contract, - - public BLSWallet: ContractFactory, + public BLSWallet: BLSWallet__factory, ) {} /// @dev Contracts deployed by first ethers signer @@ -87,42 +86,22 @@ export default class Fixture { blsSigners[i] = blsSignerFactory.getSigner(DOMAIN, "0x"+secretNumber.toString(16)); } - // deploy Verification Gateway - let VerificationGateway = await ethers.getContractFactory("VerificationGateway"); - let verificationGateway; - if (vgAddress) { - verificationGateway = VerificationGateway.attach(vgAddress); - console.log("Attached to VG. blsLib:", await verificationGateway.blsLib()); - } - else { - let BLS = await ethers.getContractFactory("BLSOpen"); - let bls; - if (blsAddress) { - bls = BLS.attach(blsAddress); - } - else { - bls = await BLS.deploy(); - await bls.deployed(); - } - verificationGateway = await VerificationGateway.deploy(); - await verificationGateway.deployed(); - if (initialized) { - await (await verificationGateway.initialize( - bls.address - )).wait(); - } - } + let create2Fixture = Create2Fixture.create(); - let BLSExpander = await ethers.getContractFactory("BLSExpander"); - let blsExpander; - if (expanderAddress) { - blsExpander = BLSExpander.attach(expanderAddress); - } - else { - blsExpander = await BLSExpander.deploy(); - await blsExpander.deployed(); + // deploy Verification Gateway + let verificationGateway = await create2Fixture.create2Contract("VerificationGateway") as VerificationGateway; + let bls = await create2Fixture.create2Contract("BLSOpen"); + try { + await (await verificationGateway.initialize( + bls.address + )).wait(); + } catch (e) {} + + // deploy BLSExpander Gateway + let blsExpander = await create2Fixture.create2Contract("BLSExpander") as BLSExpander; + try { await (await blsExpander.initialize(verificationGateway.address)).wait(); - } + } catch (e) {} let BLSWallet = await ethers.getContractFactory("BLSWallet"); @@ -133,9 +112,7 @@ export default class Fixture { addresses, blsSignerFactory, blsSigners, - VerificationGateway, verificationGateway, - BLSExpander, blsExpander, BLSWallet ); diff --git a/contracts/shared/helpers/deployAndRunPrecompileCostEstimator.ts b/contracts/shared/helpers/deployAndRunPrecompileCostEstimator.ts index ae8f1173..763c3d0c 100644 --- a/contracts/shared/helpers/deployAndRunPrecompileCostEstimator.ts +++ b/contracts/shared/helpers/deployAndRunPrecompileCostEstimator.ts @@ -1,12 +1,11 @@ import { BigNumber } from "@ethersproject/bignumber"; import { ethers } from "hardhat"; -import Create2Factory from "./create2Contract"; +import Create2Fixture from "./Create2Fixture"; export default async function precompileCostEstimator(): Promise { - let create2Factory = Create2Factory.create(); - let bnPairingPrecompileCostEstimator = await create2Factory.create2Contract( - await ethers.getContractFactory("BNPairingPrecompileCostEstimator") - ); + let create2Fixture = Create2Fixture.create(); + let bnPairingPrecompileCostEstimator + = await create2Fixture.create2Contract("BNPairingPrecompileCostEstimator"); await (await bnPairingPrecompileCostEstimator.run()).wait(); return bnPairingPrecompileCostEstimator.address; } diff --git a/contracts/shared/helpers/deployDeployer.ts b/contracts/shared/helpers/deployDeployer.ts index 8dbd2e71..2cf7c4d3 100644 --- a/contracts/shared/helpers/deployDeployer.ts +++ b/contracts/shared/helpers/deployDeployer.ts @@ -5,6 +5,7 @@ import { ethers } from "hardhat"; import { Wallet, BigNumber } from "ethers"; import { Create2Deployer } from "../../typechain"; +dotenv.config(); export function defaultDeployerAddress(): string { return defaultDeployerWallet().address; @@ -14,7 +15,7 @@ export function defaultDeployerAddress(): string { * * @returns Wallet constructed from DEPLOYER_ env vars */ -function defaultDeployerWallet(): Wallet { +export function defaultDeployerWallet(): Wallet { return ethers.Wallet.fromMnemonic( `${process.env.DEPLOYER_MNEMONIC}`, `m/44'/60'/0'/0/${process.env.DEPLOYER_SET_INDEX}` @@ -26,10 +27,9 @@ function defaultDeployerWallet(): Wallet { * @param deployerWallet EOA to deploy contract, otherwise defaultDeployerWallet * @returns create2Deployer Contract at the expected address, deploying one if not yet deployed */ -export default async function deployerContract(deployerWallet?: Wallet): Promise { - if (deployerWallet === undefined) { - deployerWallet = defaultDeployerWallet(); - } +export default async function deployerContract(): Promise { + let deployerWallet = defaultDeployerWallet(); + const Create2Deployer = await ethers.getContractFactory( "Create2Deployer", deployerWallet @@ -37,11 +37,14 @@ export default async function deployerContract(deployerWallet?: Wallet): Promise let deployerAddress = ethers.utils.getContractAddress({ from: deployerWallet.address, - nonce: BigNumber.from(`${process.env.DEPLOYER_SET_INDEX}`) + nonce: 0 // expect first tx to have been deployment }); // If deployer contract doesn't exist at expected address, deploy it there if ((await ethers.provider.getCode(deployerAddress)) === "0x") { + if (await deployerWallet.getTransactionCount() > 0) { + throw("No contract at expected address, and first transaction already used"); + } await (await Create2Deployer.deploy()).deployed(); } diff --git a/contracts/test/deploy-test.ts b/contracts/test/deploy-test.ts index ba6a2abf..c925ef8e 100644 --- a/contracts/test/deploy-test.ts +++ b/contracts/test/deploy-test.ts @@ -5,39 +5,38 @@ import { expectEvent, expectRevert } from "@openzeppelin/test-helpers"; import { BigNumber } from "@ethersproject/bignumber"; import { ethers } from "hardhat"; -import { Create2DeployerInterface } from "../typechain/Create2Deployer"; +import deployerContract, { defaultDeployerAddress, defaultDeployerWallet } from "../shared/helpers/deployDeployer"; +import { Create2Deployer, Create2Deployer__factory } from "../typechain"; +import { ContractFactory } from "@ethersproject/contracts"; -describe('Deployer', async function () { - if (`${process.env.DEPLOYER_DEPLOYMENT}` !== "true") { - console.log("Skipping deployer tests. (DEPLOYER_DEPLOYMENT !== true)"); - return; - } +dotenv.config(); + +describe.only('Deployer', async function () { let deployerSigner; let eoaAddress; - let Create2Deployer; - let create2Deployer; + let Create2Deployer: ContractFactory; + let create2Deployer: Create2Deployer; this.beforeAll(async function () { - deployerSigner = (await ethers.getSigners())[0]; - eoaAddress = deployerSigner.address; - Create2Deployer = await ethers.getContractFactory("Create2Deployer"); + Create2Deployer = await ethers.getContractFactory( + "Create2Deployer", + defaultDeployerWallet() + ); + + // fund deployer wallet address + let fundedSigner = (await ethers.getSigners())[0]; + await (await fundedSigner.sendTransaction({ + to: defaultDeployerWallet().address, + value: ethers.utils.parseEther("1") + })).wait(); //one-time deployment - create2Deployer = await Create2Deployer.deploy(); - await create2Deployer.deployed(); + create2Deployer = await deployerContract(); }); beforeEach(async function() { }); - it('should calculate EOA deployed address', async function () { - let calculatedAddress = ethers.utils.getContractAddress({ - from: eoaAddress, - nonce: BigNumber.from(0) - }); - expect(calculatedAddress).to.equal(create2Deployer.address); - }); - - it('should deploy to caculated address', async function () { + it('should deploy to caculated (create2) address', async function () { let testSalt = BigNumber.from(0); const initCodeHash = ethers.utils.solidityKeccak256( ["bytes"], diff --git a/contracts/test/walletAction-test.ts b/contracts/test/walletAction-test.ts index 6a4862b7..600f3961 100644 --- a/contracts/test/walletAction-test.ts +++ b/contracts/test/walletAction-test.ts @@ -17,7 +17,7 @@ import { formatUnits, parseEther } from "@ethersproject/units"; import deployAndRunPrecompileCostEstimator from "../shared/helpers/deployAndRunPrecompileCostEstimator"; import getDeployedAddresses from "../shared/helpers/getDeployedAddresses"; import deployerContract, { defaultDeployerAddress } from "../shared/helpers/deployDeployer"; -import { Create2Deployer } from "../typechain"; + describe('WalletActions', async function () { if (`${process.env.DEPLOYER_DEPLOYMENT}` === "true") { @@ -32,10 +32,11 @@ describe('WalletActions', async function () { console.log("eaoAddress:", address); // fund deployer wallet address - await (await ethers.getSigners())[0].sendTransaction({ + let fundedSigner = (await ethers.getSigners())[0]; + await (await fundedSigner.sendTransaction({ to: address, value: utils.parseEther("1") - }); + })).wait(); let create2Deployer = await deployerContract(); console.log("create2Deployer:", create2Deployer.address); @@ -239,7 +240,7 @@ describe('WalletActions', async function () { let signatures: any[] = new Array(blsWalletAddresses.length); let encodedParams: string[] = new Array(blsWalletAddresses.length); let startNonce = await fx.BLSWallet.attach(blsWalletAddresses[0]).nonce(); - let nonce = startNonce; + let nonce = startNonce.toNumber(); let reward = BigNumber.from(0); for (let i = 0; i