diff --git a/hardhat.config.ts b/hardhat.config.ts index ef03adbe1..96d8b82e2 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,4 +1,5 @@ import { HardhatUserConfig } from 'hardhat/types'; +import { HARDHAT_ACCOUNTS } from './hardhatAccounts.js'; import 'hardhat-artifactor'; import 'hardhat-gas-reporter' import '@typechain/hardhat'; @@ -25,6 +26,11 @@ subtask('typechain-generate-types', const config: HardhatUserConfig = { defaultNetwork: 'hardhat', + networks: { + 'hardhat': { + accounts: HARDHAT_ACCOUNTS, + } + }, solidity: { compilers: [{ version: '0.8.5', diff --git a/hardhatAccounts.js b/hardhatAccounts.js new file mode 100644 index 000000000..8bbf157ab --- /dev/null +++ b/hardhatAccounts.js @@ -0,0 +1,48 @@ +exports.HARDHAT_PK_0 = '0000000000000000000000000000000000000000000000000000000000000010'; + + +exports.HARDHAT_PK_1 = '0000000000000000000000000000000000000000000000000000000000000001'; +exports.HARDHAT_PK_2 = '0000000000000000000000000000000000000000000000000000000000000002'; + +exports.HARDHAT_ACCOUNTS = [ + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000010', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000001', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000002', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000003', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000004', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000005', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000006', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000007', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000008', + balance: '1000000000000000000000', + }, + { + privateKey: '0000000000000000000000000000000000000000000000000000000000000009', + balance: '1000000000000000000000', + }, +]; \ No newline at end of file diff --git a/packages/bridges/src/SignatureBridge.ts b/packages/bridges/src/SignatureBridge.ts index 643de38bd..7261730d2 100644 --- a/packages/bridges/src/SignatureBridge.ts +++ b/packages/bridges/src/SignatureBridge.ts @@ -119,7 +119,7 @@ export class SignatureBridge { const initialGovernor = initialGovernors[chainID]; // Create the bridgeSide - const bridgeInstance = await SignatureBridgeSide.createBridgeSide(initialGovernor, deployers[chainID]); + const bridgeInstance = await SignatureBridgeSide.createBridgeSide(deployers[chainID]); const handler = await AnchorHandler.createAnchorHandler( bridgeInstance.contract.address, @@ -129,8 +129,6 @@ export class SignatureBridge { ); await bridgeInstance.setAnchorHandler(handler); - bridgeSides.set(chainID, bridgeInstance); - // Create Treasury and TreasuryHandler const treasuryHandler = await TreasuryHandler.createTreasuryHandler( bridgeInstance.contract.address, @@ -216,8 +214,15 @@ export class SignatureBridge { chainGroupedAnchors.push(anchorInstance); anchors.set(SignatureBridge.createAnchorIdString({ anchorSize, chainId: chainID }), anchorInstance); } + + // Transfer ownership of the bridge to the initialGovernor + const tx = await bridgeInstance.transferOwnership(initialGovernor, 0); + await tx.wait(); + await SignatureBridge.setPermissions(bridgeInstance, chainGroupedAnchors); createdAnchors.push(chainGroupedAnchors); + + bridgeSides.set(chainID, bridgeInstance); } // All anchors created, massage data to group anchors which should be linked together diff --git a/packages/bridges/src/SignatureBridgeSide.ts b/packages/bridges/src/SignatureBridgeSide.ts index 0152e83df..4b2767a07 100644 --- a/packages/bridges/src/SignatureBridgeSide.ts +++ b/packages/bridges/src/SignatureBridgeSide.ts @@ -7,8 +7,8 @@ import { IAnchor, IBridgeSide, Proposal } from '@webb-tools/interfaces'; import { TreasuryHandler } from '@webb-tools/tokens'; import { getChainIdType } from '@webb-tools/utils'; import { signMessage, toHex } from '@webb-tools/sdk-core'; -import EC from 'elliptic'; -const ec = new EC.ec('secp256k1'); + +type SystemSigningFn = (data: any) => Promise; export class SignatureBridgeSide implements IBridgeSide { contract: SignatureBridge; @@ -18,7 +18,7 @@ export class SignatureBridgeSide implements IBridgeSide { tokenHandler: TokenWrapperHandler; treasuryHandler: TreasuryHandler; proposals: Proposal[]; - signingSystemSignFn: (data: any) => Promise; + signingSystemSignFn: SystemSigningFn; ANCHOR_HANDLER_MISSING_ERROR = new Error('Cannot connect an anchor without a handler'); TOKEN_HANDLER_MISSING_ERROR = new Error('Cannot connect to a token wrapper without a handler'); @@ -26,52 +26,76 @@ export class SignatureBridgeSide implements IBridgeSide { private constructor( contract: SignatureBridge, - governor: ethers.Wallet | string, - signer: ethers.Signer, - signingSystemSignFn?: (data: any) => Promise + systemSigningFn: SystemSigningFn, ) { this.contract = contract; - this.admin = signer; - this.governor = governor; this.anchorHandler = null; this.tokenHandler = null; this.treasuryHandler = null; this.proposals = []; - if (signingSystemSignFn) { - // The signing system here is an asynchronous function that - // potentially dispatches a message for a signature and waits - // to receive it. It is potentially a long-running process. - this.signingSystemSignFn = signingSystemSignFn; - } else { - if (typeof governor === 'string') { - throw new Error('Cannot sign with signing system without a governor wallet'); - } - - this.signingSystemSignFn = (data: any) => { - return Promise.resolve(signMessage(governor, data)); - }; - } + + this.signingSystemSignFn = systemSigningFn } + /** + * When a bridgeSide is created, the admin is set as the governor. + * Ownership of the bridge can then be transferred to another entity. + * + * @param admin - The deployer and governor upon creation. + */ public static async createBridgeSide( - initialGovernor: ethers.Wallet | string, - admin: ethers.Signer, - signingSystemSignFn?: (data: any) => Promise + admin: ethers.Wallet ): Promise { const bridgeFactory = new SignatureBridge__factory(admin); - const deployedBridge = (typeof initialGovernor === 'string') - ? await bridgeFactory.deploy(initialGovernor, 0) - : await bridgeFactory.deploy(initialGovernor.address, 0); + const deployedBridge = await bridgeFactory.deploy(admin.address, 0); await deployedBridge.deployed(); - const bridgeSide = (typeof initialGovernor === 'string') - ? new SignatureBridgeSide(deployedBridge, initialGovernor, admin, signingSystemSignFn) - : new SignatureBridgeSide(deployedBridge, initialGovernor, admin, signingSystemSignFn); + const bridgeSide = new SignatureBridgeSide(deployedBridge, (data: any) => { + return Promise.resolve(signMessage(admin,data)); + }); + bridgeSide.admin = admin; + bridgeSide.governor = admin; return bridgeSide; } - public static async connect(address: string, governor: ethers.Wallet, admin: ethers.Wallet) { - const deployedBridge = SignatureBridge__factory.connect(address, admin); - const bridgeSide = new SignatureBridgeSide(deployedBridge, governor, admin); + /** + * When an existing SignatureBridge is connected, the governor must be configured. + * In the case of connectMocked, a wallet address is passed which will act as the governor. + * + * connectMocked is particularly useful for integration testing + * + * @param contractAddress - The contract address of the SignatureBridge contract instance. + * @param mockedGovernor - The ethers.Wallet which will sign messages before execution on the bridgeSide. + */ + public static async connectMocked(contractAddress: string, mockedGovernor: ethers.Wallet) { + const deployedBridge = SignatureBridge__factory.connect(contractAddress, mockedGovernor); + const bridgeSide = new SignatureBridgeSide(deployedBridge, (data: string) => { + return Promise.resolve(signMessage(mockedGovernor,data)); + }); + bridgeSide.governor = mockedGovernor; + bridgeSide.admin = mockedGovernor; + return bridgeSide; + } + + /** + * When an existing SignatureBridge is connected, the governor must be configured. + * In the case of connectGovernor, a network is passed for querying the chain as well + * as a signing function which can keep this class generic. + * + * connectGovernor is necessary for interacting with this class when the private key + * of the governor is unavailable, but signed proposals are available. + * + * @param contractAddress - The contract address of the SignatureBridge contract instance. + * @param provider - The network which the contract address exists upon. + * @param systemSigningFn - a function which will produce a signature that verifies as + * coming from the configured governor on chain. + */ + public static async connectGovernor( + contractAddress: string, + provider: ethers.providers.Provider, + systemSigningFn: SystemSigningFn + ) { + const deployedBridge = SignatureBridge__factory.connect(contractAddress, provider); + const bridgeSide = new SignatureBridgeSide(deployedBridge, systemSigningFn); return bridgeSide; } diff --git a/packages/interfaces/src/bridge/index.ts b/packages/interfaces/src/bridge/index.ts index 8f1c22b8a..52180cf1b 100644 --- a/packages/interfaces/src/bridge/index.ts +++ b/packages/interfaces/src/bridge/index.ts @@ -3,10 +3,10 @@ import { IAnchor } from '..'; import { IBridgeSide } from '../IBridgeSide'; // Deployer config matches the chainId to the signer for that chain -export type DeployerConfig = Record; +export type DeployerConfig = Record; // Initial Governor config the chainId to the initial governor for that chain -export type GovernorConfig = Record; +export type GovernorConfig = Record; export type AnchorIdentifier = { anchorSize?: ethers.BigNumberish; diff --git a/packages/vbridge/src/VBridge.ts b/packages/vbridge/src/VBridge.ts index ba2684729..ef2520c94 100644 --- a/packages/vbridge/src/VBridge.ts +++ b/packages/vbridge/src/VBridge.ts @@ -105,12 +105,15 @@ export class VBridge { return linkedVAnchorMap; } + // Deployments of all contracts for the bridge will be done with the DeployerConfig. + // After deployments, the wallet in the DeployerConfig will transfer ownership + // to the initialGovernor public static async deployVariableAnchorBridge( vBridgeInput: VBridgeInput, deployers: DeployerConfig, initialGovernors: GovernorConfig, smallCircuitZkComponents: ZkComponents, - largeCircuitZkComponents: ZkComponents + largeCircuitZkComponents: ZkComponents, ): Promise { let webbTokenAddresses: Map = new Map(); let vBridgeSides: Map = new Map(); @@ -125,7 +128,7 @@ export class VBridge { for (let chainID of vBridgeInput.chainIDs) { const initialGovernor = initialGovernors[chainID]; // Create the bridgeSide - let vBridgeInstance = await SignatureBridgeSide.createBridgeSide(initialGovernor, deployers[chainID]); + let vBridgeInstance = await SignatureBridgeSide.createBridgeSide(deployers[chainID]); const handler = await AnchorHandler.createAnchorHandler( vBridgeInstance.contract.address, @@ -135,8 +138,6 @@ export class VBridge { ); vBridgeInstance.setAnchorHandler(handler); - vBridgeSides.set(chainID, vBridgeInstance); - // Create Treasury and TreasuryHandler const treasuryHandler = await TreasuryHandler.createTreasuryHandler( vBridgeInstance.contract.address, @@ -226,6 +227,11 @@ export class VBridge { await VBridge.setPermissions(vBridgeInstance, chainGroupedVAnchors); createdVAnchors.push(chainGroupedVAnchors); + + // Transfer ownership of the bridge to the initialGovernor + const tx = await vBridgeInstance.transferOwnership(initialGovernor, 0); + await tx.wait(); + vBridgeSides.set(chainID, vBridgeInstance); } // All anchors created, massage data to group anchors which should be linked together @@ -240,8 +246,9 @@ export class VBridge { groupLinkedVAnchors.push(linkedAnchors); } - // finally, link the anchors + // link the anchors const linkedVAnchorMap = await VBridge.createLinkedVAnchorMap(groupLinkedVAnchors); + return new VBridge(vBridgeSides, webbTokenAddresses, linkedVAnchorMap, vAnchors); } diff --git a/test/bridge/signatureBridge.test.ts b/test/bridge/signatureBridge.test.ts index b72923b6e..4929108c1 100644 --- a/test/bridge/signatureBridge.test.ts +++ b/test/bridge/signatureBridge.test.ts @@ -19,6 +19,7 @@ import { fetchComponentsFromFilePaths, getChainIdType, ZkComponents } from '../. import { BigNumber } from '@ethersproject/bignumber'; import { Signer } from 'ethers'; import { startGanacheServer } from '@webb-tools/test-utils'; +import { HARDHAT_PK_1 } from '../../hardhatAccounts.js'; export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); @@ -37,6 +38,8 @@ describe('multichain tests for erc20 bridges', () => { let zkComponents3: ZkComponents; let zkComponents4: ZkComponents; + let hardhatWallet1 = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); + before('setup networks', async () => { ganacheServer2 = await startGanacheServer(1337, 1337, [ { @@ -117,13 +120,13 @@ describe('multichain tests for erc20 bridges', () => { const signers = await ethers.getSigners(); const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), }; const bridge = await SignatureBridge.deployFixedDepositBridge(bridge2WebbEthInput, deploymentConfig, initialGovernorsConfig, zkComponents2); @@ -177,15 +180,15 @@ describe('multichain tests for erc20 bridges', () => { const signers = await ethers.getSigners(); const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, [chainID3]: ganacheWallet3, }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), - [chainID3]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), + [chainID3]: await ganacheWallet3.getAddress(), }; const bridge = await SignatureBridge.deployFixedDepositBridge(bridge3WebbEthInput, deploymentConfig, initialGovernorsConfig, zkComponents3); @@ -260,15 +263,14 @@ describe('multichain tests for erc20 bridges', () => { chainIDs: [chainID1, chainID2] }; - // setup the config for deployers of contracts (admins) const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, - } + }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), }; // deploy the bridge @@ -512,19 +514,19 @@ describe('multichain tests for erc20 bridges', () => { // setup the config for deployers of contracts (admins) const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, [chainID3]: ganacheWallet3, [chainID4]: ganacheWallet4, } const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), - [chainID3]: ethers.Wallet.createRandom(), - [chainID4]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), + [chainID3]: await ganacheWallet3.getAddress(), + [chainID4]: await ganacheWallet4.getAddress(), }; - + // deploy the bridge bridge = await SignatureBridge.deployFixedDepositBridge(existingTokenBridgeConfig, deploymentConfig, initialGovernorsConfig, zkComponents4); diff --git a/test/bridge/signatureBridgeSide.test.ts b/test/bridge/signatureBridgeSide.test.ts index 118e784b3..768e10fa6 100644 --- a/test/bridge/signatureBridgeSide.test.ts +++ b/test/bridge/signatureBridgeSide.test.ts @@ -15,37 +15,20 @@ import { MintableToken, Treasury, TreasuryHandler } from '../../packages/tokens/ import { fetchComponentsFromFilePaths, getChainIdType, ZkComponents } from '../../packages/utils/src'; import { PoseidonT3__factory } from '../../packages/contracts'; import { GovernedTokenWrapper, TokenWrapperHandler } from '../../packages/tokens/src'; -import { BigNumber, Wallet } from 'ethers'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { BigNumber } from 'ethers'; +import { HARDHAT_PK_1 } from '../../hardhatAccounts.js'; describe('SignatureBridgeSideConstruction', () => { - - let zkComponents: ZkComponents; - - before(async () => { - zkComponents = await fetchComponentsFromFilePaths( - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/anchor/2/poseidon_anchor_2.wasm'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/anchor/2/witness_calculator.cjs'), - path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/anchor/2/circuit_final.zkey') - ); - }) + let hardhatWallet1 = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); - it('should create the signature bridge side which can affect the anchor state', async () => { - const wallet = ethers.Wallet.createRandom(); - const initialGovernor = wallet; - const signers = await ethers.getSigners(); - const admin = signers[1]; - const bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor, admin); + it('should create the signature bridge side', async () => { + await SignatureBridgeSide.createBridgeSide(hardhatWallet1); }) }); describe('SignatureBridgeSide use', () => { - let zkComponents: ZkComponents; - let wallet: Wallet; - let initialGovernor: Wallet; - let admin: SignerWithAddress; - let signers: SignerWithAddress[]; + let admin = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); let bridgeSide: SignatureBridgeSide; before(async () => { @@ -54,14 +37,10 @@ describe('SignatureBridgeSide use', () => { path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/anchor/2/witness_calculator.cjs'), path.resolve(__dirname, '../../protocol-solidity-fixtures/fixtures/anchor/2/circuit_final.zkey') ); - signers = await ethers.getSigners(); }) beforeEach(async () => { - wallet = ethers.Wallet.createRandom(); - initialGovernor = wallet; - admin = signers[1]; - bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor, admin); + bridgeSide = await SignatureBridgeSide.createBridgeSide(admin); }) it('should set resource with signature', async () => { @@ -90,7 +69,7 @@ describe('SignatureBridgeSide use', () => { ); await tokenInstance.approveSpending(anchor.contract.address); - await bridgeSide.setAnchorHandler(anchorHandler); + bridgeSide.setAnchorHandler(anchorHandler); // //Function call below sets resource with signature await bridgeSide.connectAnchorWithSignature(anchor); //Check that proposal nonce is updated on anchor contract since handler prposal has been executed @@ -137,8 +116,8 @@ describe('SignatureBridgeSide use', () => { await tokenInstance.approveSpending(destAnchor.contract.address); await tokenInstance.approveSpending(sourceAnchor.contract.address); - await bridgeSide.setAnchorHandler(anchorHandler); - bridgeSide.setResourceWithSignature(destAnchor); + bridgeSide.setAnchorHandler(anchorHandler); + await bridgeSide.setResourceWithSignature(destAnchor); await sourceAnchor.deposit(await admin.getChainId()); const destResourceID = await destAnchor.createResourceId(); await bridgeSide.executeAnchorProposalWithSig(sourceAnchor, destResourceID); @@ -151,7 +130,6 @@ describe('SignatureBridgeSide use', () => { // Create Treasury and TreasuryHandler const treasuryHandler = await TreasuryHandler.createTreasuryHandler(bridgeSide.contract.address, [],[], admin); const treasury = await Treasury.createTreasury(treasuryHandler.contract.address, admin); - await bridgeSide.setTreasuryHandler(treasuryHandler); // Create a GovernedTokenWrapper const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( @@ -213,7 +191,7 @@ describe('SignatureBridgeSide use', () => { // Create Treasury and TreasuryHandler const treasuryHandler = await TreasuryHandler.createTreasuryHandler(bridgeSide.contract.address, [],[], bridgeSide.admin); const treasury = await Treasury.createTreasury(treasuryHandler.contract.address, bridgeSide.admin); - + //Create a GovernedTokenWrapper const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( `webbETH-test-1`, @@ -384,13 +362,14 @@ describe('SignatureBridgeSide use', () => { await bridgeSide.connectAnchorWithSignature(anchor); assert.strictEqual((await bridgeSide.contract.proposalNonce()).toString(), '5'); }) - }) +}) - describe('Rescue Tokens Tests for ERC20 Tokens', () => { +describe('Rescue Tokens Tests for ERC20 Tokens', () => { let zkComponents: ZkComponents; let sourceAnchor: Anchor; let anchorHandler: AnchorHandler; let erc20TokenInstance: MintableToken; + let admin = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); let bridgeSide: SignatureBridgeSide; let wrappingFee: number; let signers; @@ -398,7 +377,6 @@ describe('SignatureBridgeSide use', () => { let treasuryHandler; let treasury; const zeroAddress = "0x0000000000000000000000000000000000000000"; - before(async () => { zkComponents = await fetchComponentsFromFilePaths( @@ -409,11 +387,8 @@ describe('SignatureBridgeSide use', () => { }) beforeEach(async() => { - const wallet = ethers.Wallet.createRandom(); - const initialGovernor = wallet; signers = await ethers.getSigners(); - const admin = signers[1]; - bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor, admin); + bridgeSide = await SignatureBridgeSide.createBridgeSide(admin); // Create Treasury and TreasuryHandler treasuryHandler = await TreasuryHandler.createTreasuryHandler(bridgeSide.contract.address, [],[], admin); @@ -550,9 +525,8 @@ describe('SignatureBridgeSide use', () => { describe('Rescue Tokens Tests for Native ETH', () => { let zkComponents: ZkComponents; let sourceAnchor: Anchor; - let destAnchor: Anchor; let anchorHandler: AnchorHandler; - let erc20TokenInstance: MintableToken; + let admin = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); let bridgeSide: SignatureBridgeSide; let wrappingFee: number; let signers; @@ -570,11 +544,8 @@ describe('Rescue Tokens Tests for Native ETH', () => { }) beforeEach(async() => { - const wallet = ethers.Wallet.createRandom(); - const initialGovernor = wallet; signers = await ethers.getSigners(); - const admin = signers[1]; - bridgeSide = await SignatureBridgeSide.createBridgeSide(initialGovernor, admin); + bridgeSide = await SignatureBridgeSide.createBridgeSide(admin); // Deploy TokenWrapperHandler const tokenWrapperHandler = await TokenWrapperHandler.createTokenWrapperHandler(bridgeSide.contract.address, [], [], admin); diff --git a/test/vbridge/signatureVBridge.test.ts b/test/vbridge/signatureVBridge.test.ts index 0faeb36d9..52abebc4f 100644 --- a/test/vbridge/signatureVBridge.test.ts +++ b/test/vbridge/signatureVBridge.test.ts @@ -15,6 +15,7 @@ import { fetchComponentsFromFilePaths, getChainIdType, ZkComponents } from '../. import { startGanacheServer } from '@webb-tools/test-utils'; import { CircomUtxo } from '@webb-tools/sdk-core'; import { DeployerConfig, GovernorConfig } from '@webb-tools/interfaces'; +import { HARDHAT_PK_1 } from '../../hardhatAccounts.js'; const path = require('path'); @@ -22,7 +23,12 @@ export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); describe('2-sided multichain tests for signature vbridge', () => { const FIRST_CHAIN_ID = 31337; + let hardhatWallet1 = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); + const SECOND_CHAIN_ID = 10000; + let ganacheProvider2 = new ethers.providers.JsonRpcProvider(`http://localhost:${SECOND_CHAIN_ID}`); + ganacheProvider2.pollingInterval = 1; + let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); const chainID1 = getChainIdType(FIRST_CHAIN_ID); const chainID2 = getChainIdType(SECOND_CHAIN_ID); // setup ganache networks @@ -59,10 +65,6 @@ describe('2-sided multichain tests for signature vbridge', () => { let tokenInstance1: MintableToken; let tokenInstance2: MintableToken; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider(`http://localhost:${SECOND_CHAIN_ID}`); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); - before('construction-tests', async () => { const signers = await ethers.getSigners(); await ganacheProvider2.ready; @@ -72,7 +74,7 @@ describe('2-sided multichain tests for signature vbridge', () => { await tokenInstance1.mintTokens(signers[2].address, '100000000000000000000000000'); }); - it('create 2 side bridge for one token', async () => { + it('should create 2 side bridge with wallet (mocked) governor', async () => { let webbTokens1 = new Map(); webbTokens1.set(chainID1, null!); webbTokens1.set(chainID2, null!); @@ -89,13 +91,13 @@ describe('2-sided multichain tests for signature vbridge', () => { const signers = await ethers.getSigners(); const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), }; const vBridge = await VBridge.deployVariableAnchorBridge(bridge2WebbEthInput, deploymentConfig, initialGovernorsConfig, zkComponents2_2, zkComponents16_2); @@ -139,17 +141,51 @@ describe('2-sided multichain tests for signature vbridge', () => { await vBridge.transact([depositUtxo], [transferUtxo], 0, '0', '0', signers[2]); }); - }); + it('should create properly initialize governor if passed address', async () => { + let governorAddress = '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF'; + let webbTokens1 = new Map(); + webbTokens1.set(chainID1, null!); + webbTokens1.set(chainID2, null!); + bridge2WebbEthInput = { + vAnchorInputs: { + asset: { + [chainID1]: [tokenInstance1.contract.address], + [chainID2]: [tokenInstance2.contract.address], + } + }, + chainIDs: [chainID1, chainID2], + webbTokens: webbTokens1 + }; + + const deploymentConfig: DeployerConfig = { + [chainID1]: hardhatWallet1, + [chainID2]: ganacheWallet2, + }; + + const initialGovernorsConfig: GovernorConfig = { + [chainID1]: governorAddress, + [chainID2]: governorAddress, + }; + + const vBridge = await VBridge.deployVariableAnchorBridge( + bridge2WebbEthInput, + deploymentConfig, + initialGovernorsConfig, + zkComponents2_2, + zkComponents16_2, + ); + + const chainGovernor = await vBridge.getVBridgeSide(chainID1).contract.governor(); + assert.deepEqual(governorAddress, chainGovernor); + }); + }); describe('2 sided bridge existing token use', () => { // ERC20 compliant contracts that can easily create balances for test let existingToken1: MintableToken; let existingToken2: MintableToken; let vBridge: VBridge; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider(`http://localhost:${SECOND_CHAIN_ID}`); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); beforeEach(async () => { const signers = await ethers.getSigners(); @@ -177,15 +213,14 @@ describe('2-sided multichain tests for signature vbridge', () => { webbTokens: webbTokens1 } - // setup the config for deployers of contracts (admins) const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, - } + }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), }; // deploy the bridge @@ -484,9 +519,6 @@ describe('2-sided multichain tests for signature vbridge', () => { let existingToken2: MintableToken; let vBridge: VBridge; - let ganacheProvider2 = new ethers.providers.JsonRpcProvider(`http://localhost:${SECOND_CHAIN_ID}`); - ganacheProvider2.pollingInterval = 1; - let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); beforeEach(async () => { const signers = await ethers.getSigners(); @@ -514,15 +546,14 @@ describe('2-sided multichain tests for signature vbridge', () => { webbTokens: webbTokens1 } - // setup the config for deployers of contracts (admins) const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, - } + }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), }; // deploy the bridge @@ -776,17 +807,21 @@ describe('8-sided multichain tests for signature vbridge', () => { describe('8 sided bridge existing token use', () => { // ERC20 compliant contracts that can easily create balances for test + let vBridge: VBridge; let existingToken1: MintableToken; let existingToken2: MintableToken; let existingToken3: MintableToken; - let vBridge: VBridge; + let hardhatWallet1 = new ethers.Wallet(HARDHAT_PK_1, ethers.provider); + let ganacheProvider2 = new ethers.providers.JsonRpcProvider(`http://localhost:${SECOND_CHAIN_ID}`); ganacheProvider2.pollingInterval = 1; let ganacheWallet2 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider2); + let ganacheProvider3 = new ethers.providers.JsonRpcProvider(`http://localhost:${THIRD_CHAIN_ID}`); ganacheProvider3.pollingInterval = 1; let ganacheWallet3 = new ethers.Wallet('c0d375903fd6f6ad3edafc2c5428900c0757ce1da10e5dd864fe387b32b91d7e', ganacheProvider3); + beforeEach(async () => { const signers = await ethers.getSigners(); @@ -818,17 +853,16 @@ describe('8-sided multichain tests for signature vbridge', () => { webbTokens, } - // setup the config for deployers of contracts (admins) const deploymentConfig: DeployerConfig = { - [chainID1]: signers[1], + [chainID1]: hardhatWallet1, [chainID2]: ganacheWallet2, [chainID3]: ganacheWallet3, - } + }; const initialGovernorsConfig: GovernorConfig = { - [chainID1]: ethers.Wallet.createRandom(), - [chainID2]: ethers.Wallet.createRandom(), - [chainID3]: ethers.Wallet.createRandom(), + [chainID1]: await hardhatWallet1.getAddress(), + [chainID2]: await ganacheWallet2.getAddress(), + [chainID3]: await ganacheWallet3.getAddress(), }; // deploy the bridge diff --git a/tsconfig.build.json b/tsconfig.build.json index 4b509a2d2..46c714d5c 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -11,6 +11,7 @@ ], "compilerOptions": { "declaration": true, + "downlevelIteration": true, "esModuleInterop": true, "module": "commonjs", "moduleResolution": "node",