From b87dcae7f34d696f6e93229bc5928679d176931f Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Thu, 27 Oct 2022 17:02:51 -0400 Subject: [PATCH 1/5] test partial fill --- test/integration-tests/Router.test.ts | 45 +++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/integration-tests/Router.test.ts b/test/integration-tests/Router.test.ts index ce21cef6..b339e3c5 100644 --- a/test/integration-tests/Router.test.ts +++ b/test/integration-tests/Router.test.ts @@ -205,6 +205,51 @@ describe('Router', () => { const covenBalanceAfter = await covenContract.balanceOf(alice.address) expect(covenBalanceAfter.sub(covenBalanceBefore)).to.eq(1) }) + + it.only('completes a trade for ERC20 --> ETH --> NFTs, invalid Seaport order', async () => { + const maxAmountIn = expandTo18DecimalsBN(100_000) + await daiContract.transfer(router.address, maxAmountIn) + planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ + value, + maxAmountIn, + [DAI.address, WETH.address], + router.address, + ]) + planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, value]) + + // invalid Seaport order + let invalidSeaportOrder = JSON.parse(JSON.stringify(seaportOrders[0])) + invalidSeaportOrder.protocol_data.signature = '0xdeadbeef' + let seaportOrder: Order + let seaportValue: BigNumber + ;({ order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder)) + const calldataOpensea = seaportInterface.encodeFunctionData('fulfillAdvancedOrder', [ + seaportOrder, + [], + OPENSEA_CONDUIT_KEY, + alice.address, + ]) + planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea]) + + // valid NFTX order + let nftxValue: BigNumber = expandTo18DecimalsBN(4) + let numCovensNFTX = 2 + const calldataNFTX = nftxZapInterface.encodeFunctionData('buyAndRedeem', [ + NFTX_COVEN_VAULT_ID, + numCovensNFTX, + [], + [WETH.address, NFTX_COVEN_VAULT], + alice.address, + ]) + planner.addCommand(CommandType.NFTX, [nftxValue, calldataNFTX]) + + const { commands, inputs } = planner + let totalValue = seaportValue.add(nftxValue) + const covenBalanceBefore = await covenContract.balanceOf(alice.address) + await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE, { value: totalValue }) + const covenBalanceAfter = await covenContract.balanceOf(alice.address) + expect(covenBalanceAfter.sub(covenBalanceBefore)).to.eq(numCovensNFTX) + }) }) }) From abf95e9fe4d4639ee839ee30bc70ac529b31cb62 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Thu, 27 Oct 2022 17:46:13 -0400 Subject: [PATCH 2/5] test passing --- test/integration-tests/Router.test.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/test/integration-tests/Router.test.ts b/test/integration-tests/Router.test.ts index b339e3c5..ab1c5bb4 100644 --- a/test/integration-tests/Router.test.ts +++ b/test/integration-tests/Router.test.ts @@ -220,20 +220,14 @@ describe('Router', () => { // invalid Seaport order let invalidSeaportOrder = JSON.parse(JSON.stringify(seaportOrders[0])) invalidSeaportOrder.protocol_data.signature = '0xdeadbeef' - let seaportOrder: Order - let seaportValue: BigNumber - ;({ order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder)) - const calldataOpensea = seaportInterface.encodeFunctionData('fulfillAdvancedOrder', [ - seaportOrder, - [], - OPENSEA_CONDUIT_KEY, - alice.address, - ]) - planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea]) + const { order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder) + const calldataOpensea = seaportInterface.encodeFunctionData('fulfillOrder', [seaportOrder, OPENSEA_CONDUIT_KEY]) + planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea], true) // valid NFTX order let nftxValue: BigNumber = expandTo18DecimalsBN(4) let numCovensNFTX = 2 + const calldataNFTX = nftxZapInterface.encodeFunctionData('buyAndRedeem', [ NFTX_COVEN_VAULT_ID, numCovensNFTX, From ee02b8d1eedf8c5a7bef75e18a0a348923df0057 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Fri, 28 Oct 2022 14:07:30 -0400 Subject: [PATCH 3/5] updated test --- test/integration-tests/Router.test.ts | 61 +++++++++++++++++-- test/integration-tests/SeaportRouter.test.ts | 44 +++++-------- .../shared/protocolHelpers/seaport.ts | 32 ++++++++++ 3 files changed, 104 insertions(+), 33 deletions(-) diff --git a/test/integration-tests/Router.test.ts b/test/integration-tests/Router.test.ts index ab1c5bb4..b107da01 100644 --- a/test/integration-tests/Router.test.ts +++ b/test/integration-tests/Router.test.ts @@ -22,6 +22,7 @@ import { getAdvancedOrderParams, AdvancedOrder, Order, + defaultAvailableAdvancedOrders, } from './shared/protocolHelpers/seaport' import { resetFork, WETH, DAI } from './shared/mainnetForkHelpers' import { CommandType, RoutePlanner } from './shared/planner' @@ -209,18 +210,18 @@ describe('Router', () => { it.only('completes a trade for ERC20 --> ETH --> NFTs, invalid Seaport order', async () => { const maxAmountIn = expandTo18DecimalsBN(100_000) await daiContract.transfer(router.address, maxAmountIn) + let invalidSeaportOrder = JSON.parse(JSON.stringify(seaportOrders[0])) + const { order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder) planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ - value, + seaportValue, maxAmountIn, [DAI.address, WETH.address], router.address, ]) - planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, value]) + planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, seaportValue]) - // invalid Seaport order - let invalidSeaportOrder = JSON.parse(JSON.stringify(seaportOrders[0])) + // invalidate Seaport order invalidSeaportOrder.protocol_data.signature = '0xdeadbeef' - const { order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder) const calldataOpensea = seaportInterface.encodeFunctionData('fulfillOrder', [seaportOrder, OPENSEA_CONDUIT_KEY]) planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea], true) @@ -244,6 +245,56 @@ describe('Router', () => { const covenBalanceAfter = await covenContract.balanceOf(alice.address) expect(covenBalanceAfter.sub(covenBalanceBefore)).to.eq(numCovensNFTX) }) + + it.only('completes a trade for ERC20 --> ETH --> NFTs with Seaport, partial fill', async () => { + const maxAmountIn = expandTo18DecimalsBN(100_000) + await daiContract.transfer(router.address, maxAmountIn) + + const { advancedOrder: advancedOrder0, value: value1 } = getAdvancedOrderParams(seaportOrders[0]) + const { advancedOrder: advancedOrder1, value: value2 } = getAdvancedOrderParams(seaportOrders[1]) + const params0 = advancedOrder0.parameters + const params1 = advancedOrder1.parameters + const totalValue = value1.add(value2) + + planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ + totalValue, + maxAmountIn, + [DAI.address, WETH.address], + router.address, + ]) + planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, totalValue]) + + const calldata = defaultAvailableAdvancedOrders(alice.address, advancedOrder0, advancedOrder1) + planner.addCommand(CommandType.SEAPORT, [totalValue, calldata]) + const { commands, inputs } = planner + + const nftId0 = params0.offer[0].identifierOrCriteria + const nftId1 = params1.offer[0].identifierOrCriteria + + const owner0Before = await covenContract.ownerOf(nftId0) + const owner1Before = await covenContract.ownerOf(nftId1) + const ethBefore = await ethers.provider.getBalance(alice.address) + + // shouldn't have to send eth bc we are unwrapping the dai - weth trade, but this fails: + const receipt = await (await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE)).wait() + + // This succeeds: + // const receipt = await ( + // await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE, { value: totalValue }) + // ).wait() + + const owner0After = await covenContract.ownerOf(nftId0) + const owner1After = await covenContract.ownerOf(nftId1) + const ethAfter = await ethers.provider.getBalance(alice.address) + const gasSpent = receipt.gasUsed.mul(receipt.effectiveGasPrice) + const ethDelta = ethBefore.sub(ethAfter) + + expect(owner0Before.toLowerCase()).to.eq(params0.offerer) + expect(owner1Before.toLowerCase()).to.eq(params1.offerer) + expect(owner0After).to.eq(alice.address) + expect(owner1After).to.eq(alice.address) + expect(ethDelta).to.eq(gasSpent) // eth spent only on gas bc trade came from DAI + }) }) }) diff --git a/test/integration-tests/SeaportRouter.test.ts b/test/integration-tests/SeaportRouter.test.ts index 135f459d..2b57811a 100644 --- a/test/integration-tests/SeaportRouter.test.ts +++ b/test/integration-tests/SeaportRouter.test.ts @@ -4,7 +4,12 @@ import { expect } from './shared/expect' import { BigNumber } from 'ethers' import { Router } from '../../typechain' import { abi as ERC721_ABI } from '../../artifacts/solmate/src/tokens/ERC721.sol/ERC721.json' -import { seaportOrders, seaportInterface, getAdvancedOrderParams } from './shared/protocolHelpers/seaport' +import { + seaportOrders, + seaportInterface, + getAdvancedOrderParams, + defaultAvailableAdvancedOrders, +} from './shared/protocolHelpers/seaport' import deployRouter from './shared/deployRouter' import { resetFork } from './shared/mainnetForkHelpers' import { ALICE_ADDRESS, COVEN_ADDRESS, DEADLINE, OPENSEA_CONDUIT_KEY } from './shared/constants' @@ -56,46 +61,29 @@ describe('Seaport', () => { expect(ethDelta.sub(gasSpent)).to.eq(value) }) - it('completes a fulfillAvailableAdvancedOrders type', async () => { + it.only('completes a fulfillAvailableAdvancedOrders type', async () => { const { advancedOrder: advancedOrder0, value: value1 } = getAdvancedOrderParams(seaportOrders[0]) const { advancedOrder: advancedOrder1, value: value2 } = getAdvancedOrderParams(seaportOrders[1]) const params0 = advancedOrder0.parameters const params1 = advancedOrder1.parameters const value = value1.add(value2) - const considerationFulfillment = [ - [[0, 0]], - [ - [0, 1], - [1, 1], - ], - [ - [0, 2], - [1, 2], - ], - [[1, 0]], - ] - - const calldata = seaportInterface.encodeFunctionData('fulfillAvailableAdvancedOrders', [ - [advancedOrder0, advancedOrder1], - [], - [[[0, 0]], [[1, 0]]], - considerationFulfillment, - OPENSEA_CONDUIT_KEY, - alice.address, - 100, - ]) + + const calldata = defaultAvailableAdvancedOrders(alice.address, advancedOrder0, advancedOrder1) planner.addCommand(CommandType.SEAPORT, [value.toString(), calldata]) const { commands, inputs } = planner - const owner0Before = await covenContract.ownerOf(params0.offer[0].identifierOrCriteria) - const owner1Before = await covenContract.ownerOf(params1.offer[0].identifierOrCriteria) + const nftId0 = params0.offer[0].identifierOrCriteria + const nftId1 = params1.offer[0].identifierOrCriteria + + const owner0Before = await covenContract.ownerOf(nftId0) + const owner1Before = await covenContract.ownerOf(nftId1) const ethBefore = await ethers.provider.getBalance(alice.address) const receipt = await (await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE, { value })).wait() - const owner0After = await covenContract.ownerOf(params0.offer[0].identifierOrCriteria) - const owner1After = await covenContract.ownerOf(params1.offer[0].identifierOrCriteria) + const owner0After = await covenContract.ownerOf(nftId0) + const owner1After = await covenContract.ownerOf(nftId1) const ethAfter = await ethers.provider.getBalance(alice.address) const gasSpent = receipt.gasUsed.mul(receipt.effectiveGasPrice) const ethDelta = ethBefore.sub(ethAfter) diff --git a/test/integration-tests/shared/protocolHelpers/seaport.ts b/test/integration-tests/shared/protocolHelpers/seaport.ts index becc534c..7affa408 100644 --- a/test/integration-tests/shared/protocolHelpers/seaport.ts +++ b/test/integration-tests/shared/protocolHelpers/seaport.ts @@ -3,6 +3,7 @@ import { BigNumber } from 'ethers' import { expandTo18DecimalsBN } from '../helpers' import fs from 'fs' import hre from 'hardhat' +import { OPENSEA_CONDUIT_KEY } from '../constants' const { ethers } = hre export const seaportOrders = JSON.parse( @@ -75,3 +76,34 @@ export function calculateValue(considerations: ConsiderationItem[]): BigNumber { expandTo18DecimalsBN(0) ) } + +export function defaultAvailableAdvancedOrders( + address: string, + advancedOrder0: AdvancedOrder, + advancedOrder1: AdvancedOrder +): string { + const considerationFulfillment = [ + [[0, 0]], + [ + [0, 1], + [1, 1], + ], + [ + [0, 2], + [1, 2], + ], + [[1, 0]], + ] + + const calldata = seaportInterface.encodeFunctionData('fulfillAvailableAdvancedOrders', [ + [advancedOrder0, advancedOrder1], + [], + [[[0, 0]], [[1, 0]]], + considerationFulfillment, + OPENSEA_CONDUIT_KEY, + address, + 100, + ]) + + return calldata +} From 5aa7d6814cdb9ba013ce12b0dcf4514277f3b063 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Fri, 28 Oct 2022 14:23:02 -0400 Subject: [PATCH 4/5] updated tests --- test/integration-tests/Router.test.ts | 29 ++++++++------------ test/integration-tests/SeaportRouter.test.ts | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/test/integration-tests/Router.test.ts b/test/integration-tests/Router.test.ts index b107da01..3b20b53c 100644 --- a/test/integration-tests/Router.test.ts +++ b/test/integration-tests/Router.test.ts @@ -198,27 +198,30 @@ describe('Router', () => { [DAI.address, WETH.address], router.address, ]) - planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, value]) + planner.addCommand(CommandType.UNWRAP_WETH, [router.address, value]) planner.addCommand(CommandType.SEAPORT, [value.toString(), calldata]) const { commands, inputs } = planner const covenBalanceBefore = await covenContract.balanceOf(alice.address) - await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE, { value }) + await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE) const covenBalanceAfter = await covenContract.balanceOf(alice.address) expect(covenBalanceAfter.sub(covenBalanceBefore)).to.eq(1) }) - it.only('completes a trade for ERC20 --> ETH --> NFTs, invalid Seaport order', async () => { + it('completes a trade for ERC20 --> ETH --> NFTs, invalid Seaport order', async () => { const maxAmountIn = expandTo18DecimalsBN(100_000) + await daiContract.transfer(router.address, maxAmountIn) let invalidSeaportOrder = JSON.parse(JSON.stringify(seaportOrders[0])) const { order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder) + let nftxValue: BigNumber = expandTo18DecimalsBN(4) + let totalValue = seaportValue.add(nftxValue) planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ - seaportValue, + totalValue, maxAmountIn, [DAI.address, WETH.address], router.address, ]) - planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, seaportValue]) + planner.addCommand(CommandType.UNWRAP_WETH, [router.address, totalValue]) // invalidate Seaport order invalidSeaportOrder.protocol_data.signature = '0xdeadbeef' @@ -226,9 +229,7 @@ describe('Router', () => { planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea], true) // valid NFTX order - let nftxValue: BigNumber = expandTo18DecimalsBN(4) let numCovensNFTX = 2 - const calldataNFTX = nftxZapInterface.encodeFunctionData('buyAndRedeem', [ NFTX_COVEN_VAULT_ID, numCovensNFTX, @@ -239,14 +240,14 @@ describe('Router', () => { planner.addCommand(CommandType.NFTX, [nftxValue, calldataNFTX]) const { commands, inputs } = planner - let totalValue = seaportValue.add(nftxValue) + const covenBalanceBefore = await covenContract.balanceOf(alice.address) - await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE, { value: totalValue }) + await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE) const covenBalanceAfter = await covenContract.balanceOf(alice.address) expect(covenBalanceAfter.sub(covenBalanceBefore)).to.eq(numCovensNFTX) }) - it.only('completes a trade for ERC20 --> ETH --> NFTs with Seaport, partial fill', async () => { + it('completes a trade for ERC20 --> ETH --> NFTs with Seaport, partial fill', async () => { const maxAmountIn = expandTo18DecimalsBN(100_000) await daiContract.transfer(router.address, maxAmountIn) @@ -262,7 +263,7 @@ describe('Router', () => { [DAI.address, WETH.address], router.address, ]) - planner.addCommand(CommandType.UNWRAP_WETH, [alice.address, totalValue]) + planner.addCommand(CommandType.UNWRAP_WETH, [router.address, totalValue]) const calldata = defaultAvailableAdvancedOrders(alice.address, advancedOrder0, advancedOrder1) planner.addCommand(CommandType.SEAPORT, [totalValue, calldata]) @@ -275,14 +276,8 @@ describe('Router', () => { const owner1Before = await covenContract.ownerOf(nftId1) const ethBefore = await ethers.provider.getBalance(alice.address) - // shouldn't have to send eth bc we are unwrapping the dai - weth trade, but this fails: const receipt = await (await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE)).wait() - // This succeeds: - // const receipt = await ( - // await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE, { value: totalValue }) - // ).wait() - const owner0After = await covenContract.ownerOf(nftId0) const owner1After = await covenContract.ownerOf(nftId1) const ethAfter = await ethers.provider.getBalance(alice.address) diff --git a/test/integration-tests/SeaportRouter.test.ts b/test/integration-tests/SeaportRouter.test.ts index 2b57811a..55b25a0e 100644 --- a/test/integration-tests/SeaportRouter.test.ts +++ b/test/integration-tests/SeaportRouter.test.ts @@ -61,7 +61,7 @@ describe('Seaport', () => { expect(ethDelta.sub(gasSpent)).to.eq(value) }) - it.only('completes a fulfillAvailableAdvancedOrders type', async () => { + it('completes a fulfillAvailableAdvancedOrders type', async () => { const { advancedOrder: advancedOrder0, value: value1 } = getAdvancedOrderParams(seaportOrders[0]) const { advancedOrder: advancedOrder1, value: value2 } = getAdvancedOrderParams(seaportOrders[1]) const params0 = advancedOrder0.parameters From 48f8ea86b2ac09cf466ddee09443548bd6000d27 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Mon, 31 Oct 2022 18:35:25 -0400 Subject: [PATCH 5/5] some fixes --- test/integration-tests/Router.test.ts | 36 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/test/integration-tests/Router.test.ts b/test/integration-tests/Router.test.ts index 3b20b53c..49dd8ca9 100644 --- a/test/integration-tests/Router.test.ts +++ b/test/integration-tests/Router.test.ts @@ -209,24 +209,17 @@ describe('Router', () => { it('completes a trade for ERC20 --> ETH --> NFTs, invalid Seaport order', async () => { const maxAmountIn = expandTo18DecimalsBN(100_000) - + // in this case there is leftover dai in the router, and the unspent eth gets sent to alice await daiContract.transfer(router.address, maxAmountIn) + let invalidSeaportOrder = JSON.parse(JSON.stringify(seaportOrders[0])) const { order: seaportOrder, value: seaportValue } = getOrderParams(invalidSeaportOrder) let nftxValue: BigNumber = expandTo18DecimalsBN(4) let totalValue = seaportValue.add(nftxValue) - planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ - totalValue, - maxAmountIn, - [DAI.address, WETH.address], - router.address, - ]) - planner.addCommand(CommandType.UNWRAP_WETH, [router.address, totalValue]) // invalidate Seaport order invalidSeaportOrder.protocol_data.signature = '0xdeadbeef' const calldataOpensea = seaportInterface.encodeFunctionData('fulfillOrder', [seaportOrder, OPENSEA_CONDUIT_KEY]) - planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea], true) // valid NFTX order let numCovensNFTX = 2 @@ -237,18 +230,35 @@ describe('Router', () => { [WETH.address, NFTX_COVEN_VAULT], alice.address, ]) + + planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ + totalValue, + maxAmountIn, + [DAI.address, WETH.address], + router.address, + ]) + planner.addCommand(CommandType.UNWRAP_WETH, [router.address, totalValue]) + planner.addCommand(CommandType.SEAPORT, [seaportValue.toString(), calldataOpensea], true) + planner.addCommand(CommandType.NFTX, [nftxValue, calldataNFTX]) const { commands, inputs } = planner + const routerEthBalanceBefore = await ethers.provider.getBalance(router.address) const covenBalanceBefore = await covenContract.balanceOf(alice.address) + await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE) + const covenBalanceAfter = await covenContract.balanceOf(alice.address) + const routerEthBalanceAfter = await ethers.provider.getBalance(router.address) + expect(covenBalanceAfter.sub(covenBalanceBefore)).to.eq(numCovensNFTX) + expect(routerEthBalanceAfter).to.eq(routerEthBalanceBefore) }) - it('completes a trade for ERC20 --> ETH --> NFTs with Seaport, partial fill', async () => { + it('completes a trade for ERC20 --> ETH --> NFTs with Seaport, fulfillAvailableAdvancedOrders fill', async () => { const maxAmountIn = expandTo18DecimalsBN(100_000) + // in this case there is leftover dai in the router and all eth gets spent on the nfts await daiContract.transfer(router.address, maxAmountIn) const { advancedOrder: advancedOrder0, value: value1 } = getAdvancedOrderParams(seaportOrders[0]) @@ -257,6 +267,8 @@ describe('Router', () => { const params1 = advancedOrder1.parameters const totalValue = value1.add(value2) + const calldata = defaultAvailableAdvancedOrders(alice.address, advancedOrder0, advancedOrder1) + planner.addCommand(CommandType.V2_SWAP_EXACT_OUT, [ totalValue, maxAmountIn, @@ -265,7 +277,6 @@ describe('Router', () => { ]) planner.addCommand(CommandType.UNWRAP_WETH, [router.address, totalValue]) - const calldata = defaultAvailableAdvancedOrders(alice.address, advancedOrder0, advancedOrder1) planner.addCommand(CommandType.SEAPORT, [totalValue, calldata]) const { commands, inputs } = planner @@ -275,12 +286,14 @@ describe('Router', () => { const owner0Before = await covenContract.ownerOf(nftId0) const owner1Before = await covenContract.ownerOf(nftId1) const ethBefore = await ethers.provider.getBalance(alice.address) + const routerEthBalanceBefore = await ethers.provider.getBalance(router.address) const receipt = await (await router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE)).wait() const owner0After = await covenContract.ownerOf(nftId0) const owner1After = await covenContract.ownerOf(nftId1) const ethAfter = await ethers.provider.getBalance(alice.address) + const routerEthBalanceAfter = await ethers.provider.getBalance(router.address) const gasSpent = receipt.gasUsed.mul(receipt.effectiveGasPrice) const ethDelta = ethBefore.sub(ethAfter) @@ -289,6 +302,7 @@ describe('Router', () => { expect(owner0After).to.eq(alice.address) expect(owner1After).to.eq(alice.address) expect(ethDelta).to.eq(gasSpent) // eth spent only on gas bc trade came from DAI + expect(routerEthBalanceBefore).to.eq(routerEthBalanceAfter) // ensure no eth is left in the router }) }) })