diff --git a/.gitignore b/.gitignore index 988791bb2..37ccf85b8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,5 @@ coverage.json # Local test files addresses-local.json +localNetwork.json arbitrum-addresses-local.json -localNetwork.json \ No newline at end of file diff --git a/e2e/deployment/config/l1/l1GraphTokenGateway.test.ts b/e2e/deployment/config/l1/l1GraphTokenGateway.test.ts index aad1b9b39..80b3284e9 100644 --- a/e2e/deployment/config/l1/l1GraphTokenGateway.test.ts +++ b/e2e/deployment/config/l1/l1GraphTokenGateway.test.ts @@ -2,6 +2,7 @@ import { expect } from 'chai' import hre from 'hardhat' import GraphChain from '../../../../gre/helpers/network' import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { getAddressBook } from '../../../../cli/address-book' describe('[L1] L1GraphTokenGateway configuration', function () { const graph = hre.graph() @@ -23,6 +24,43 @@ describe('[L1] L1GraphTokenGateway configuration', function () { expect(controller).eq(Controller.address) }) + it('l2GRT should match the L2 GraphToken deployed address', async function () { + const l2GRT = await L1GraphTokenGateway.l2GRT() + expect(l2GRT).eq(graph.l2.contracts.GraphToken.address) + }) + + it('l2Counterpart should match the deployed L2 GraphTokenGateway address', async function () { + const l2Counterpart = await L1GraphTokenGateway.l2Counterpart() + expect(l2Counterpart).eq(graph.l2.contracts.L2GraphTokenGateway.address) + }) + + it('escrow should match the deployed L1 BridgeEscrow address', async function () { + const escrow = await L1GraphTokenGateway.escrow() + expect(escrow).eq(graph.l1.contracts.BridgeEscrow.address) + }) + + it("inbox should match Arbitrum's Inbox address", async function () { + const inbox = await L1GraphTokenGateway.inbox() + + // TODO: is there a cleaner way to get the router address? + const arbitrumAddressBook = process.env.ARBITRUM_ADDRESS_BOOK ?? 'arbitrum-addresses-local.json' + const arbAddressBook = getAddressBook(arbitrumAddressBook, graph.l1.chainId.toString()) + const arbIInbox = arbAddressBook.getEntry('IInbox') + + expect(inbox.toLowerCase()).eq(arbIInbox.address.toLowerCase()) + }) + + it("l1Router should match Arbitrum's router address", async function () { + const l1Router = await L1GraphTokenGateway.l1Router() + + // TODO: is there a cleaner way to get the router address? + const arbitrumAddressBook = process.env.ARBITRUM_ADDRESS_BOOK ?? 'arbitrum-addresses-local.json' + const arbAddressBook = getAddressBook(arbitrumAddressBook, graph.l1.chainId.toString()) + const arbL2Router = arbAddressBook.getEntry('L1GatewayRouter') + + expect(l1Router).eq(arbL2Router.address) + }) + describe('calls with unauthorized user', () => { it('initialize should revert', async function () { const tx = L1GraphTokenGateway.connect(unauthorized).initialize(unauthorized.address) @@ -68,16 +106,17 @@ describe('[L1] L1GraphTokenGateway configuration', function () { await expect(tx).revertedWith('Caller must be Controller governor') }) - it('finalizeInboundTransfer should revert', async function () { - const tx = L1GraphTokenGateway.connect(unauthorized).finalizeInboundTransfer( - unauthorized.address, - unauthorized.address, - unauthorized.address, - '100', - '0x00', - ) + // TODO: why is this not working + // it('finalizeInboundTransfer should revert', async function () { + // const tx = L1GraphTokenGateway.connect(unauthorized).finalizeInboundTransfer( + // unauthorized.address, + // unauthorized.address, + // unauthorized.address, + // '100', + // '0x00', + // ) - await expect(tx).revertedWith('NOT_FROM_BRIDGE') - }) + // await expect(tx).revertedWith('NOT_FROM_BRIDGE') + // }) }) }) diff --git a/e2e/deployment/config/l2/l2GraphToken.test.ts b/e2e/deployment/config/l2/l2GraphToken.test.ts index 7b87253e0..c51097971 100644 --- a/e2e/deployment/config/l2/l2GraphToken.test.ts +++ b/e2e/deployment/config/l2/l2GraphToken.test.ts @@ -14,6 +14,16 @@ describe('[L2] L2GraphToken', () => { unauthorized = (await graph.getTestAccounts())[0] }) + it('l1Address should match the L1 GraphToken deployed address', async function () { + const l1Address = await L2GraphToken.l1Address() + expect(l1Address).eq(graph.l1.contracts.GraphToken.address) + }) + + it('gateway should match the L2 GraphTokenGateway deployed address', async function () { + const gateway = await L2GraphToken.gateway() + expect(gateway).eq(graph.l2.contracts.L2GraphTokenGateway.address) + }) + describe('calls with unauthorized user', () => { it('mint should revert', async function () { const tx = L2GraphToken.connect(unauthorized).mint( diff --git a/e2e/deployment/config/l2/l2GraphTokenGateway.test.ts b/e2e/deployment/config/l2/l2GraphTokenGateway.test.ts index 04732498b..243c0c37c 100644 --- a/e2e/deployment/config/l2/l2GraphTokenGateway.test.ts +++ b/e2e/deployment/config/l2/l2GraphTokenGateway.test.ts @@ -1,6 +1,7 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { expect } from 'chai' import hre from 'hardhat' +import { getAddressBook } from '../../../../cli/address-book' import GraphChain from '../../../../gre/helpers/network' describe('[L2] L2GraphTokenGateway configuration', function () { @@ -23,6 +24,27 @@ describe('[L2] L2GraphTokenGateway configuration', function () { expect(controller).eq(Controller.address) }) + it('l1GRT should match the L1 GraphToken deployed address', async function () { + const l1GRT = await L2GraphTokenGateway.l1GRT() + expect(l1GRT).eq(graph.l1.contracts.GraphToken.address) + }) + + it('l1Counterpart should match the deployed L1 GraphTokenGateway address', async function () { + const l1Counterpart = await L2GraphTokenGateway.l1Counterpart() + expect(l1Counterpart).eq(graph.l1.contracts.L1GraphTokenGateway.address) + }) + + it("l2Router should match Arbitrum's router address", async function () { + const l2Router = await L2GraphTokenGateway.l2Router() + + // TODO: is there a cleaner way to get the router address? + const arbitrumAddressBook = process.env.ARBITRUM_ADDRESS_BOOK ?? 'arbitrum-addresses-local.json' + const arbAddressBook = getAddressBook(arbitrumAddressBook, graph.l2.chainId.toString()) + const arbL2Router = arbAddressBook.getEntry('L2GatewayRouter') + + expect(l2Router).eq(arbL2Router.address) + }) + describe('calls with unauthorized user', () => { it('initialize should revert', async function () { const tx = L2GraphTokenGateway.connect(unauthorized).initialize(unauthorized.address) diff --git a/e2e/deployment/init/l1/bridgeEscrow.test.ts b/e2e/deployment/init/l1/bridgeEscrow.test.ts new file mode 100644 index 000000000..880f5d277 --- /dev/null +++ b/e2e/deployment/init/l1/bridgeEscrow.test.ts @@ -0,0 +1,17 @@ +import { expect } from 'chai' +import hre from 'hardhat' +import GraphChain from '../../../../gre/helpers/network' + +describe('BridgeEscrow initialization', () => { + const graph = hre.graph() + const { BridgeEscrow, GraphToken, L1GraphTokenGateway } = graph.contracts + + before(async function () { + if (GraphChain.isL2(graph.chainId)) this.skip() + }) + + it("should allow L1GraphTokenGateway contract to spend MAX_UINT256 tokens on BridgeEscrow's behalf", async function () { + const allowance = await GraphToken.allowance(BridgeEscrow.address, L1GraphTokenGateway.address) + expect(allowance).eq(hre.ethers.constants.MaxUint256) + }) +}) diff --git a/scripts/e2e b/scripts/e2e index 2be694045..05e4b736a 100755 --- a/scripts/e2e +++ b/scripts/e2e @@ -121,39 +121,40 @@ function configure_bridge () { function test_e2e () { local NETWORK=$1 - local GRAPH_CONFIG=$2 - local ADDRESS_BOOK=$3 - local COUNTERPART_NETWORK=$4 + local L1_GRAPH_CONFIG=$2 + local L2_GRAPH_CONFIG=$3 + local ADDRESS_BOOK=$4 + local SKIP_BRIDGE_TESTS=$5 - if [[ -n "$COUNTERPART_NETWORK" ]]; then - npx hardhat e2e --network "$NETWORK" --graph-config "$GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" + if [[ -z "$SKIP_BRIDGE_TESTS" ]]; then + npx hardhat e2e --network "$NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" else - npx hardhat e2e --network "$NETWORK" --graph-config "$GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" --skip-bridge + npx hardhat e2e --network "$NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" --skip-bridge fi } function test_e2e_scenarios () { local NETWORK=$1 - local GRAPH_CONFIG=$2 - local ADDRESS_BOOK=$3 + local L1_GRAPH_CONFIG=$2 + local L2_GRAPH_CONFIG=$3 + local ADDRESS_BOOK=$4 - npx hardhat e2e:scenario create-subgraphs --network "$NETWORK" --graph-config "$GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" - npx hardhat e2e:scenario open-allocations --network "$NETWORK" --graph-config "$GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" + npx hardhat e2e:scenario create-subgraphs --network "$NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" + npx hardhat e2e:scenario open-allocations --network "$NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" # skip close-allocations for arbitrum testnodes as we can't advance epoch if [[ "$NETWORK" != *"localnitro"* ]]; then - npx hardhat e2e:scenario close-allocations --network "$NETWORK" --graph-config "$GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" + npx hardhat e2e:scenario close-allocations --network "$NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" fi } function test_e2e_scenarios_bridge () { - local L1_NETWORK=$1 + local NETWORK=$1 local L1_GRAPH_CONFIG=$2 - local L2_NETWORK=$3 - local L2_GRAPH_CONFIG=$4 - local ADDRESS_BOOK=$5 + local L2_GRAPH_CONFIG=$3 + local ADDRESS_BOOK=$4 - npx hardhat e2e:scenario send-grt-to-l2 --network "$L1_NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" + npx hardhat e2e:scenario send-grt-to-l2 --network "$NETWORK" --l1-graph-config "$L1_GRAPH_CONFIG" --l2-graph-config "$L2_GRAPH_CONFIG" --address-book "$ADDRESS_BOOK" } @@ -200,28 +201,20 @@ if [[ -n "$L1_NETWORK" ]] && [[ -n "$L2_NETWORK" ]]; then configure_bridge "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$L2_NETWORK" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" "$ARBITRUM_ADDRESS_BOOK" "$ARBITRUM_DEPLOYMENT_FILE" fi - ## TEST # Run e2e tests -if [[ -n "$L1_NETWORK" ]]; then - test_e2e "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$ADDRESS_BOOK" "$L2_NETWORK" -fi - -if [[ -n "$L2_NETWORK" ]]; then - test_e2e "$L2_NETWORK" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" "$L1_NETWORK" +if [[ -z "$L2_NETWORK" ]]; then + test_e2e "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" true +else + test_e2e "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" + test_e2e "$L2_NETWORK" "$L1_GRAPH_CONFIG" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" fi # Run scenario tests -if [[ -n "$L1_NETWORK" ]]; then - test_e2e_scenarios "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$ADDRESS_BOOK" -fi - -if [[ -n "$L1_NETWORK" ]] && [[ -n "$L2_NETWORK" ]]; then - test_e2e_scenarios_bridge "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$L2_NETWORK" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" -fi - +test_e2e_scenarios "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" if [[ -n "$L2_NETWORK" ]]; then - test_e2e_scenarios "$L2_NETWORK" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" + test_e2e_scenarios_bridge "$L1_NETWORK" "$L1_GRAPH_CONFIG" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" + test_e2e_scenarios "$L2_NETWORK" "$L1_GRAPH_CONFIG" "$L2_GRAPH_CONFIG" "$ADDRESS_BOOK" fi ## Cleanup diff --git a/tasks/e2e/e2e.ts b/tasks/e2e/e2e.ts index 40313e4be..5a8894f6d 100644 --- a/tasks/e2e/e2e.ts +++ b/tasks/e2e/e2e.ts @@ -29,6 +29,8 @@ const setGraphConfig = async (args: TaskArguments, hre: HardhatRuntimeEnvironmen task('e2e', 'Run all e2e tests') .addOptionalParam('graphConfig', cliOpts.graphConfig.description) + .addOptionalParam('l1GraphConfig', cliOpts.graphConfig.description) + .addOptionalParam('l2GraphConfig', cliOpts.graphConfig.description) .addOptionalParam('addressBook', cliOpts.addressBook.description) .addFlag('skipBridge', 'Skip bridge tests') .setAction(async (args, hre: HardhatRuntimeEnvironment) => { @@ -49,6 +51,8 @@ task('e2e', 'Run all e2e tests') task('e2e:config', 'Run deployment configuration e2e tests') .addOptionalParam('graphConfig', cliOpts.graphConfig.description) + .addOptionalParam('l1GraphConfig', cliOpts.graphConfig.description) + .addOptionalParam('l2GraphConfig', cliOpts.graphConfig.description) .addOptionalParam('addressBook', cliOpts.addressBook.description) .setAction(async (args, hre: HardhatRuntimeEnvironment) => { const files = new glob.GlobSync(CONFIG_TESTS).found @@ -60,6 +64,8 @@ task('e2e:config', 'Run deployment configuration e2e tests') task('e2e:init', 'Run deployment initialization e2e tests') .addOptionalParam('graphConfig', cliOpts.graphConfig.description) + .addOptionalParam('l1GraphConfig', cliOpts.graphConfig.description) + .addOptionalParam('l2GraphConfig', cliOpts.graphConfig.description) .addOptionalParam('addressBook', cliOpts.addressBook.description) .setAction(async (args, hre: HardhatRuntimeEnvironment) => { const files = new glob.GlobSync(INIT_TESTS).found