From 1d098665f3dc786d04a66b9beeb773e5d6e0e501 Mon Sep 17 00:00:00 2001 From: byshape Date: Tue, 5 Dec 2023 16:32:10 +0000 Subject: [PATCH 1/5] Merged several fixtures into one --- test/LimitOrderProtocol.js | 1255 +++++++++++++++++------------------- 1 file changed, 589 insertions(+), 666 deletions(-) diff --git a/test/LimitOrderProtocol.js b/test/LimitOrderProtocol.js index be1b8cdd..ac3225a3 100644 --- a/test/LimitOrderProtocol.js +++ b/test/LimitOrderProtocol.js @@ -25,135 +25,179 @@ describe('LimitOrderProtocol', function () { await weth.connect(addr1).approve(swap.address, ether('100')); }; - describe('wip', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; + const deployContractsAndInit = async function () { + const { dai, weth, usdc, swap, chainId } = await deploySwapTokens(); + const tokens = { dai, weth, usdc }; + const contracts = { swap }; + await initContracts(dai, weth, swap); + + const ETHOrders = await ethers.getContractFactory('ETHOrders'); + contracts.ethOrders = await ETHOrders.deploy(weth.address, swap.address); + await contracts.ethOrders.deployed(); + const orderLibFactory = await ethers.getContractFactory('OrderLib'); + + const { arbitraryPredicate } = await deployArbitraryPredicate(); + contracts.arbitraryPredicate = arbitraryPredicate; + + const permits = { taker: {}, maker: {} }; + // Taker permit + permits.taker.order = buildOrder({ + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: 1, + takingAmount: 1, + maker: addr1.address, + }); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(permits.taker.order, chainId, swap.address, addr1)); + permits.taker.signature = { r, vs }; + + // Maker permit + const permit = withTarget( + weth.address, + await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'), + ); + permits.maker.permit = permit; + permits.maker.order = buildOrder( + { + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: 1, + takingAmount: 1, + maker: addr.address, + }, + { + permit, + }, + ); + const { r: r1, _vs: vs1 } = ethers.utils.splitSignature(await signOrder(permits.maker.order, chainId, swap.address, addr)); + permits.maker.signature = { r: r1, vs: vs1 }; + + return { tokens, contracts, chainId, orderLibFactory, permits }; + }; + describe('wip', function () { it('transferFrom', async function () { - const { dai } = await loadFixture(deployContractsAndInit); + const { tokens } = await loadFixture(deployContractsAndInit); - await dai.connect(addr1).approve(addr.address, '2'); - await dai.transferFrom(addr1.address, addr.address, '1'); + await tokens.dai.connect(addr1).approve(addr.address, '2'); + await tokens.dai.transferFrom(addr1.address, addr.address, '1'); }); it('should not swap with bad signature', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, }); const fakeOrder = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(fakeOrder, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'BadSignature'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(fakeOrder, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'BadSignature'); }); it('should not fill above threshold', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'TakingAmountTooHigh'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'TakingAmountTooHigh'); }); it('should not fill below threshold', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 2, 3)) - .to.be.revertedWithCustomError(swap, 'MakingAmountTooLow'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 2, 3)) + .to.be.revertedWithCustomError(contracts.swap, 'MakingAmountTooLow'); }); it('should fill without checks with threshold == 0', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 10, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: true }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const swapWithoutThreshold = await swap.fillOrder(order, r, vs, 5, 0); + const swapWithoutThreshold = await contracts.swap.fillOrder(order, r, vs, 5, 0); const gasUsedWithoutThreshold = (await swapWithoutThreshold.wait()).gasUsed; await loadFixture(deployContractsAndInit); - const swapWithThreshold = await swap.fillOrder(order, r, vs, 5, 1); + const swapWithThreshold = await contracts.swap.fillOrder(order, r, vs, 5, 1); expect((await swapWithThreshold.wait()).gasUsed).to.gt(gasUsedWithoutThreshold); }); it('should fail when amount is zero', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 100, takingAmount: 1, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 0, 0)) - .to.be.revertedWithCustomError(swap, 'SwapWithZeroAmount'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 0, 0)) + .to.be.revertedWithCustomError(contracts.swap, 'SwapWithZeroAmount'); }); it('should swap fully based on signature', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 1 DAI => 1 WETH // Swap: 1 DAI => 1 WETH for (const nonce of [0, 1]) { const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); if (hre.__SOLIDITY_COVERAGE_RUNNING === undefined) { - const trace = findTrace(tracer, 'CALL', swap.address); + const trace = findTrace(tracer, 'CALL', contracts.swap.address); const opcodes = trace.children.map(item => item.opcode); expect(countAllItems(opcodes)).to.deep.equal({ STATICCALL: 1, CALL: 2, SLOAD: 1, SSTORE: 1, LOG1: 1 }); } @@ -161,117 +205,117 @@ describe('LimitOrderProtocol', function () { }); it('should swap half based on signature', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 2 DAI => 2 WETH // Swap: 1 DAI => 1 WETH const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); if (hre.__SOLIDITY_COVERAGE_RUNNING === undefined) { - const trace = findTrace(tracer, 'CALL', swap.address); + const trace = findTrace(tracer, 'CALL', contracts.swap.address); const opcodes = trace.children.map(item => item.opcode); expect(countAllItems(opcodes)).to.deep.equal({ STATICCALL: 1, CALL: 2, SLOAD: 1, SSTORE: 1, LOG1: 1 }); } }); it('should floor maker amount', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 2 DAI => 10 WETH // Swap: 9 WETH <= 1 DAI const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 10, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 9, 1); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-9, 9]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 9, 1); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-9, 9]); }); it('should fail on floor maker amount = 0', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 2 DAI => 10 WETH // Swap: 4 WETH <= 0 DAI const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 10, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 4, 0)) - .to.be.revertedWithCustomError(swap, 'SwapWithZeroAmount'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 4, 0)) + .to.be.revertedWithCustomError(contracts.swap, 'SwapWithZeroAmount'); }); it('should ceil taker amount', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [4, -4]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [4, -4]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('should unwrap weth', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: weth.address, - takerAsset: dai.address, + makerAsset: tokens.weth.address, + takerAsset: tokens.dai.address, makingAmount: ether('2'), takingAmount: ether('10'), maker: addr1.address, }); - await weth.connect(addr1).deposit({ value: ether('2') }); + await tokens.weth.connect(addr1).deposit({ value: ether('2') }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, ether('5'), unwrapWethTaker(ether('1'))); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [ether('-5'), ether('5')]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [ether('0'), ether('-1')]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, ether('5'), unwrapWethTaker(ether('1'))); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [ether('-5'), ether('5')]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [ether('0'), ether('-1')]); await expect(fillTx).to.changeEtherBalance(addr, ether('1')); }); it('ERC721Proxy should work', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const ERC721Proxy = await ethers.getContractFactory('ERC721Proxy'); - const erc721proxy = await ERC721Proxy.deploy(swap.address); + const erc721proxy = await ERC721Proxy.deploy(contracts.swap.address); await erc721proxy.deployed(); - await dai.connect(addr1).approve(erc721proxy.address, '10'); - await weth.approve(erc721proxy.address, '10'); + await tokens.dai.connect(addr1).approve(erc721proxy.address, '10'); + await tokens.weth.approve(erc721proxy.address, '10'); const order = buildOrder( { @@ -283,145 +327,133 @@ describe('LimitOrderProtocol', function () { maker: addr1.address, }, { - makerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [addr1.address, constants.ZERO_ADDRESS, 0, 10, dai.address]).substring(202), - takerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [constants.ZERO_ADDRESS, addr1.address, 0, 10, weth.address]).substring(202), + makerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [addr1.address, constants.ZERO_ADDRESS, 0, 10, tokens.dai.address]).substring(202), + takerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [constants.ZERO_ADDRESS, addr1.address, 0, 10, tokens.weth.address]).substring(202), }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 10n, makingAmount: true, extension: order.extension, }); - const fillTx = swap.fillOrderArgs(order, r, vs, 10, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-10, 10]); + const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 10, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-10, 10]); }); }); describe('MakerTraits', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - it('disallow multiple fills', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [4, -4]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [4, -4]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); - await expect(swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'BitInvalidatedOrder'); + await expect(contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'BitInvalidatedOrder'); }); it('need epoch manager, success', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ shouldCheckEpoch: true }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [4, -4]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [4, -4]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('need epoch manager, fail', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ shouldCheckEpoch: true, nonce: 1 }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'WrongSeriesNonce'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'WrongSeriesNonce'); }); it('unwrap weth for maker', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 10 DAI => 2 ETH const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ unwrapWeth: true }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(2)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalance(weth, addr, -2); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(2)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalance(tokens.weth, addr, -2); await expect(fillTx).to.changeEtherBalance(addr1, 2); }); }); describe('TakerTraits', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - it('DAI => WETH, send WETH to address different from msg.sender when fill', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const otherAddress = addr2; const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1800, takingAmount: 1, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ target: otherAddress.address, }); - const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalance(dai, addr1, -1800); - await expect(fillTx).to.changeTokenBalance(weth, addr, -1); + await expect(fillTx).to.changeTokenBalance(tokens.dai, addr1, -1800); + await expect(fillTx).to.changeTokenBalance(tokens.weth, addr, -1); // Pay out happened to otherAddress, specified in taker traits - await expect(fillTx).to.changeTokenBalance(dai, otherAddress, 1800); + await expect(fillTx).to.changeTokenBalance(tokens.dai, otherAddress, 1800); }); }); @@ -432,373 +464,302 @@ describe('LimitOrderProtocol', function () { // ok permit | - | + | // bad permit | + | + | - const deployContractsAndInitPermit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - - const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: 1, - takingAmount: 1, - maker: addr1.address, - }); - await weth.approve(swap.address, '0'); - const signature = await signOrder(order, chainId, swap.address, addr1); - - return { dai, weth, swap, chainId, order, signature }; - }; - it('DAI => WETH', async function () { - const { dai, weth, swap, chainId, order, signature } = await loadFixture(deployContractsAndInitPermit); + const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.taker.signature; - const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'); - const { r, _vs: vs } = ethers.utils.splitSignature(signature); + const permit = await getPermit(addr.address, addr, tokens.weth, '1', chainId, contracts.swap.address, '1'); const takerTraits = buildTakerTraits({ minReturn: 1n, makingAmount: true, }); - const fillTx = swap.permitAndCall( + + await tokens.weth.approve(contracts.swap.address, '0'); + const fillTx = contracts.swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [weth.address, permit], + [tokens.weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - order, r, vs, 1, takerTraits.traits, takerTraits.args, + contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ + permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('skips expired permit if allowance is enough', async function () { - const { dai, weth, swap, chainId, order, signature } = await loadFixture(deployContractsAndInitPermit); + const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.taker.signature; - await weth.approve(swap.address, '1'); + // await tokens.weth.approve(contracts.swap.address, '1'); const deadline = (await time.latest()) - time.duration.weeks(1); - const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1', deadline); + const permit = await getPermit(addr.address, addr, tokens.weth, '1', chainId, contracts.swap.address, '1', deadline); - const { r, _vs: vs } = ethers.utils.splitSignature(signature); const takerTraits = buildTakerTraits({ minReturn: 1n }); - const fillTx = swap.permitAndCall( + const fillTx = contracts.swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [weth.address, permit], + [tokens.weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - order, r, vs, 1, takerTraits.traits, takerTraits.args, + contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ + permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('rejects expired permit when allowance is not enough', async function () { - const { weth, swap, chainId, order, signature } = await loadFixture(deployContractsAndInitPermit); + const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.taker.signature; const deadline = (await time.latest()) - time.duration.weeks(1); - const permit = await getPermit(addr.address, addr1, weth, '1', chainId, swap.address, '1', deadline); + const permit = await getPermit(addr.address, addr1, tokens.weth, '1', chainId, contracts.swap.address, '1', deadline); - const { r, _vs: vs } = ethers.utils.splitSignature(signature); + await tokens.weth.approve(contracts.swap.address, '0'); const takerTraits = buildTakerTraits({ minReturn: 1n }); - await expect(swap.permitAndCall( + await expect(contracts.swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [weth.address, permit], + [tokens.weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - order, r, vs, 1, takerTraits.traits, takerTraits.args, + contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ + permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, ]), - )).to.be.revertedWithCustomError(swap, 'TransferFromTakerToMakerFailed'); + )).to.be.revertedWithCustomError(contracts.swap, 'TransferFromTakerToMakerFailed'); }); }); describe('Maker permit', function () { - const deployContractsAndInitPermit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - - const permit = withTarget( - weth.address, - await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'), - ); - - weth.approve(swap.address, '0'); - - const order = buildOrder( - { - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: 1, - takingAmount: 1, - maker: addr.address, - }, - { - permit, - }, - ); - - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr)); - return { dai, weth, swap, order, r, vs, permit }; - }; - it('maker permit works', async function () { - const { dai, weth, swap, order, r, vs } = await loadFixture(deployContractsAndInitPermit); + const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.maker.signature; const takerTraits = buildTakerTraits({ minReturn: 1n, makingAmount: true, - extension: order.extension, + extension: permits.maker.order.extension, }); - const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + await tokens.weth.approve(contracts.swap.address, '0'); + const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('skips order permit flag', async function () { - const { dai, weth, swap, order, r, vs, permit } = await loadFixture(deployContractsAndInitPermit); + const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.maker.signature; - await addr1.sendTransaction({ to: weth.address, data: '0xd505accf' + permit.substring(42) }); + await tokens.weth.approve(contracts.swap.address, '0'); + await addr1.sendTransaction({ to: tokens.weth.address, data: '0xd505accf' + permits.maker.permit.substring(42) }); const takerTraits = buildTakerTraits({ minReturn: 0n, skipMakerPermit: true, - extension: order.extension, + extension: permits.maker.order.extension, }); - const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); }); }); describe('Permit2', function () { describe('Taker Permit', function () { - // TODO: Consider refactoring to use only one fixture in all tests - const deployContractsAndInitPermit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - - const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: 1, - takingAmount: 1, - maker: addr1.address, - }); - await weth.approve(swap.address, '0'); - const signature = await signOrder(order, chainId, swap.address, addr1); - - return { dai, weth, swap, chainId, order, signature }; - }; - it('DAI => WETH, permit2', async function () { - const { dai, weth, swap, chainId, order } = await loadFixture(deployContractsAndInitPermit); + const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.taker.signature; const permit2 = await permit2Contract(); - await weth.approve(permit2.address, 1); - const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); + await tokens.weth.approve(permit2.address, 1); + const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, makingAmount: true, usePermit2: true, }); - const fillTx = swap.permitAndCall( + await tokens.weth.approve(contracts.swap.address, '0'); + const fillTx = contracts.swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [weth.address, permit], + [tokens.weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - order, r, vs, 1, takerTraits.traits, takerTraits.args, + contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ + permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); }); }); describe('Amount Calculator', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - it('empty takingAmountData should work on full fill', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(10)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-10, 10]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(10)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-10, 10]); }); it('empty takingAmountData should revert on partial fill', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 5, fillWithMakingAmount(5))) - .to.be.revertedWithCustomError(swap, 'PartialFillNotAllowed'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 5, fillWithMakingAmount(5))) + .to.be.revertedWithCustomError(contracts.swap, 'PartialFillNotAllowed'); }); it('empty makingAmountData should revert on partial fill', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 5, 5)) - .to.be.revertedWithCustomError(swap, 'PartialFillNotAllowed'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 5, 5)) + .to.be.revertedWithCustomError(contracts.swap, 'PartialFillNotAllowed'); }); it('empty makingAmountData should work on full fill', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 10, 10); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-10, 10]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 10, 10); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-10, 10]); }); }); describe('ETH Maker Orders', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - const ETHOrders = await ethers.getContractFactory('ETHOrders'); - const ethOrders = await ETHOrders.deploy(weth.address, swap.address); - await ethOrders.deployed(); - const orderLibFactory = await ethers.getContractFactory('OrderLib'); - return { dai, weth, swap, orderLibFactory, chainId, ethOrders }; - }; - it('Partial fill', async function () { - const { dai, weth, swap, chainId, ethOrders } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: ethOrders.address, + maker: contracts.ethOrders.address, receiver: addr1.address, - makerAsset: weth.address, - takerAsset: dai.address, + makerAsset: tokens.weth.address, + takerAsset: tokens.dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: ethOrders.address, + postInteraction: contracts.ethOrders.address, }, ); - const orderHash = await swap.hashOrder(order); + const orderHash = await contracts.swap.hashOrder(order); - const deposittx = ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); + const deposittx = contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); await expect(deposittx).to.changeEtherBalance(addr1, ether('-0.3')); - await expect(deposittx).to.changeTokenBalance(weth, ethOrders, ether('0.3')); + await expect(deposittx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('0.3')); - let orderMakerBalance = await ethOrders.ordersMakersBalances(orderHash); + let orderMakerBalance = await contracts.ethOrders.ordersMakersBalances(orderHash); expect(orderMakerBalance.balance).to.equal(ether('0.3')); expect(orderMakerBalance.maker).to.equal(addr1.address); - const ethOrdersBatch = await ethOrders.ethOrdersBatch([orderHash]); + const ethOrdersBatch = await contracts.ethOrders.ethOrdersBatch([orderHash]); expect(ethOrdersBatch[0].balance).to.equal(ether('0.3')); expect(ethOrdersBatch[0].maker).to.equal(addr1.address); - const signature = await signOrder(order, chainId, swap.address, addr1); + const signature = await signOrder(order, chainId, contracts.swap.address, addr1); /// Partial fill const takerTraits1 = buildTakerTraits({ minReturn: ether('0.2'), extension: order.extension, }); - const fillTx1 = swap.fillContractOrderArgs(order, signature, ether('200'), takerTraits1.traits, takerTraits1.args); - await expect(fillTx1).to.changeTokenBalances(dai, [addr, ethOrders, addr1], [ether('-200'), '0', ether('200')]); - await expect(fillTx1).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); + const fillTx1 = contracts.swap.fillContractOrderArgs(order, signature, ether('200'), takerTraits1.traits, takerTraits1.args); + await expect(fillTx1).to.changeTokenBalances(tokens.dai, [addr, contracts.ethOrders, addr1], [ether('-200'), '0', ether('200')]); + await expect(fillTx1).to.changeTokenBalances(tokens.weth, [addr, contracts.ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); /// Remaining fill const takerTraits2 = buildTakerTraits({ minReturn: ether('0.1'), extension: order.extension, }); - const fillTx2 = swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits2.traits, takerTraits2.args); - await expect(fillTx2).to.changeTokenBalances(dai, [addr, ethOrders, addr1], [ether('-100'), '0', ether('100')]); - await expect(fillTx2).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.1'), ether('-0.1'), '0']); + const fillTx2 = contracts.swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits2.traits, takerTraits2.args); + await expect(fillTx2).to.changeTokenBalances(tokens.dai, [addr, contracts.ethOrders, addr1], [ether('-100'), '0', ether('100')]); + await expect(fillTx2).to.changeTokenBalances(tokens.weth, [addr, contracts.ethOrders, addr1], [ether('0.1'), ether('-0.1'), '0']); - orderMakerBalance = await ethOrders.ordersMakersBalances(orderHash); + orderMakerBalance = await contracts.ethOrders.ordersMakersBalances(orderHash); expect(orderMakerBalance.balance).to.equal(0); expect(orderMakerBalance.maker).to.equal(addr1.address); }); it('Partial fill -> cancel -> refund maker -> fail to fill', async function () { - const { dai, weth, swap, chainId, ethOrders } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: ethOrders.address, + maker: contracts.ethOrders.address, receiver: addr1.address, - makerAsset: weth.address, - takerAsset: dai.address, + makerAsset: tokens.weth.address, + takerAsset: tokens.dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: ethOrders.address, + postInteraction: contracts.ethOrders.address, }, ); - const orderHash = await swap.hashOrder(order); + const orderHash = await contracts.swap.hashOrder(order); - const deposittx = ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); + const deposittx = contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); await expect(deposittx).to.changeEtherBalance(addr1, ether('-0.3')); - await expect(deposittx).to.changeTokenBalance(weth, ethOrders, ether('0.3')); + await expect(deposittx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('0.3')); - const signature = await signOrder(order, chainId, swap.address, addr1); + const signature = await signOrder(order, chainId, contracts.swap.address, addr1); /// Partial fill const fillTakerTraits = buildTakerTraits({ minReturn: ether('0.2'), extension: order.extension, }); - const fillTx = swap.fillContractOrderArgs(order, signature, ether('200'), fillTakerTraits.traits, fillTakerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, ethOrders, addr1], [ether('-200'), '0', ether('200')]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); + const fillTx = contracts.swap.fillContractOrderArgs(order, signature, ether('200'), fillTakerTraits.traits, fillTakerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, contracts.ethOrders, addr1], [ether('-200'), '0', ether('200')]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, contracts.ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); /// Cancel order - const canceltx = ethOrders.connect(addr1).cancelOrder(order.makerTraits, orderHash); - await expect(canceltx).to.changeTokenBalance(weth, ethOrders, ether('-0.1')); + const canceltx = contracts.ethOrders.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await expect(canceltx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('-0.1')); await expect(canceltx).to.changeEtherBalance(addr1, ether('0.1')); /// Remaining fill failure @@ -806,236 +767,224 @@ describe('LimitOrderProtocol', function () { minReturn: ether('0.1'), extension: order.extension, }); - await expect(swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(swap, 'InvalidatedOrder'); + await expect(contracts.swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(contracts.swap, 'InvalidatedOrder'); }); it('Invalid order (missing post-interaction)', async function () { - const { dai, weth, ethOrders } = await loadFixture(deployContractsAndInit); + const { tokens, contracts } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - maker: ethOrders.address, + maker: contracts.ethOrders.address, receiver: addr1.address, - makerAsset: weth.address, - takerAsset: dai.address, + makerAsset: tokens.weth.address, + takerAsset: tokens.dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }); - await expect(ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') })) - .to.be.revertedWithCustomError(ethOrders, 'InvalidOrder'); + await expect(contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') })) + .to.be.revertedWithCustomError(contracts.ethOrders, 'InvalidOrder'); }); it('Invalid extension (empty extension)', async function () { - const { dai, weth, orderLibFactory, ethOrders } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, orderLibFactory } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: ethOrders.address, + maker: contracts.ethOrders.address, receiver: addr1.address, - makerAsset: weth.address, - takerAsset: dai.address, + makerAsset: tokens.weth.address, + takerAsset: tokens.dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: ethOrders.address, + postInteraction: contracts.ethOrders.address, }, ); - await expect(ethOrders.connect(addr1).ethOrderDeposit(order, [], { value: ether('0.3') })) + await expect(contracts.ethOrders.connect(addr1).ethOrderDeposit(order, [], { value: ether('0.3') })) .to.be.revertedWithCustomError(orderLibFactory, 'MissingOrderExtension'); }); it('Invalid extension (mismatched extension)', async function () { - const { dai, weth, orderLibFactory, ethOrders } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, orderLibFactory } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: ethOrders.address, + maker: contracts.ethOrders.address, receiver: addr1.address, - makerAsset: weth.address, - takerAsset: dai.address, + makerAsset: tokens.weth.address, + takerAsset: tokens.dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: ethOrders.address, + postInteraction: contracts.ethOrders.address, }, ); - await expect(ethOrders.connect(addr1).ethOrderDeposit(order, order.extension.slice(0, -6), { value: ether('0.3') })) + await expect(contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension.slice(0, -6), { value: ether('0.3') })) .to.be.revertedWithCustomError(orderLibFactory, 'InvalidExtensionHash'); }); }); describe('Remaining invalidator', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - const orderCancelationInit = async function () { - const { dai, weth, swap, chainId } = await deployContractsAndInit(); + const { tokens, contracts, chainId } = await deployContractsAndInit(); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: true }), }); - return { dai, weth, swap, chainId, order }; + return { tokens, contracts, chainId, order }; }; it('should revert for new order', async function () { - const { swap, chainId, order } = await loadFixture(orderCancelationInit); - const data = buildOrderData(chainId, swap.address, order); + const { contracts, chainId, order } = await loadFixture(orderCancelationInit); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await expect(swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.be.revertedWithCustomError(swap, 'RemainingInvalidatedOrder'); + await expect(contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.be.revertedWithCustomError(contracts.swap, 'RemainingInvalidatedOrder'); }); it('should return correct remaining for partially filled order', async function () { - const { swap, chainId, order } = await loadFixture(orderCancelationInit); - const signature = await signOrder(order, chainId, swap.address, addr1); + const { contracts, chainId, order } = await loadFixture(orderCancelationInit); + const signature = await signOrder(order, chainId, contracts.swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, swap.address, order); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('1'); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('1'); }); it('should return zero remaining for filled order', async function () { - const { swap, chainId, order } = await loadFixture(orderCancelationInit); - const signature = await signOrder(order, chainId, swap.address, addr1); + const { contracts, chainId, order } = await loadFixture(orderCancelationInit); + const signature = await signOrder(order, chainId, contracts.swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, swap.address, order); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2)); + await contracts.swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2)); - expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); }); it('should return zero remaining for cancelled order', async function () { - const { swap, chainId, order } = await loadFixture(orderCancelationInit); - const data = buildOrderData(chainId, swap.address, order); + const { contracts, chainId, order } = await loadFixture(orderCancelationInit); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); }); }); describe('Order Cancelation', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - const orderCancelationInit = async function () { - const { dai, weth, swap, chainId } = await deployContractsAndInit(); + const { tokens, contracts, chainId } = await deployContractsAndInit(); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: true }), }); - return { dai, weth, swap, chainId, order }; + return { tokens, contracts, chainId, order }; }; const orderWithEpochInit = async function () { - const { dai, weth, swap, chainId } = await deployContractsAndInit(); + const { tokens, contracts, chainId } = await deployContractsAndInit(); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: true, shouldCheckEpoch: true, nonce: 0, series: 1 }), }); - return { dai, weth, swap, chainId, order }; + return { tokens, contracts, chainId, order }; }; // TODO: it could be canceled with another makerTraits, 1n << ALLOW_MUTIPLE_FILLS_FLAG (254n) for example it('should cancel own order', async function () { - const { swap, chainId, order } = await loadFixture(orderCancelationInit); - const data = buildOrderData(chainId, swap.address, order); + const { contracts, chainId, order } = await loadFixture(orderCancelationInit); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); }); it('should cancel own order with massInvalidate', async function () { - const { dai, weth, swap, chainId } = await loadFixture(orderCancelationInit); + const { tokens, contracts, chainId } = await loadFixture(orderCancelationInit); const orderNonce = 0; const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }), }); - const data = buildOrderData(chainId, swap.address, order); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - const invalidator = await swap.bitInvalidatorForOrder(addr1.address, orderNonce); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + const invalidator = await contracts.swap.bitInvalidatorForOrder(addr1.address, orderNonce); expect(invalidator).to.equal('1'); }); it('should cancel own order with massInvalidate, huge nonce', async function () { - const { dai, weth, swap, chainId } = await loadFixture(orderCancelationInit); + const { tokens, contracts, chainId } = await loadFixture(orderCancelationInit); const orderNonce = 1023; const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }), }); - const data = buildOrderData(chainId, swap.address, order); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - const invalidator = await swap.bitInvalidatorForOrder(addr1.address, orderNonce); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + const invalidator = await contracts.swap.bitInvalidatorForOrder(addr1.address, orderNonce); expect(invalidator).to.equal(1n << 255n); }); it('should cancel any hash', async function () { - const { swap, order } = await loadFixture(orderCancelationInit); - await swap.connect(addr1).cancelOrder(order.makerTraits, '0x0000000000000000000000000000000000000000000000000000000000000001'); - expect(await swap.remainingInvalidatorForOrder(addr1.address, '0x0000000000000000000000000000000000000000000000000000000000000001')).to.equal('0'); + const { contracts, order } = await loadFixture(orderCancelationInit); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, '0x0000000000000000000000000000000000000000000000000000000000000001'); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, '0x0000000000000000000000000000000000000000000000000000000000000001')).to.equal('0'); }); // TODO: fix simulate test it('can simulate order cancelation', async function () { - const { swap, order } = await loadFixture(orderCancelationInit); + const { contracts, order } = await loadFixture(orderCancelationInit); - const calldata = swap.interface.encodeFunctionData('cancelOrder', [ + const calldata = contracts.swap.interface.encodeFunctionData('cancelOrder', [ order.makerTraits, '0x0000000000000000000000000000000000000000000000000000000000000001', ]); - const cancelationSimulate = swap.simulate(addr1.address, calldata); + const cancelationSimulate = contracts.swap.simulate(addr1.address, calldata); await expect(cancelationSimulate) - .to.be.revertedWithCustomError(swap, 'SimulationResults') + .to.be.revertedWithCustomError(contracts.swap, 'SimulationResults') .withArgs(true, '0x'); }); it('should cancel several orders by hash', async function () { - const { swap, order } = await loadFixture(orderCancelationInit); + const { contracts, order } = await loadFixture(orderCancelationInit); const firstOrder = order; const secondOrder = order; @@ -1043,170 +992,156 @@ describe('LimitOrderProtocol', function () { const firstOrderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000001'; const secondOrderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000002'; - await swap.connect(addr1).cancelOrders( + await contracts.swap.connect(addr1).cancelOrders( [firstOrder.makerTraits, secondOrder.makerTraits], [firstOrderFakeHash, secondOrderFakeHash], ); - expect(await swap.remainingInvalidatorForOrder(addr1.address, firstOrderFakeHash)).to.equal('0'); - expect(await swap.remainingInvalidatorForOrder(addr1.address, secondOrderFakeHash)).to.equal('0'); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, firstOrderFakeHash)).to.equal('0'); + expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, secondOrderFakeHash)).to.equal('0'); }); it('rawRemainingInvalidatorForOrder returns method works', async function () { - const { swap, order } = await loadFixture(orderCancelationInit); + const { contracts, order } = await loadFixture(orderCancelationInit); const orderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000001'; - expect(await swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal('0'); + expect(await contracts.swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal('0'); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderFakeHash); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderFakeHash); const minusOne = '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - expect(await swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal(minusOne); + expect(await contracts.swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal(minusOne); }); it('should not fill cancelled order', async function () { - const { swap, chainId, order } = await loadFixture(orderCancelationInit); - const signature = await signOrder(order, chainId, swap.address, addr1); + const { contracts, chainId, order } = await loadFixture(orderCancelationInit); + const signature = await signOrder(order, chainId, contracts.swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, swap.address, order); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'InvalidatedOrder'); + await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'InvalidatedOrder'); }); it('should not fill cancelled order, massInvalidate', async function () { - const { dai, weth, swap, chainId } = await loadFixture(orderCancelationInit); + const { tokens, contracts, chainId } = await loadFixture(orderCancelationInit); const orderNonce = 0; const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }), }); - const signature = await signOrder(order, chainId, swap.address, addr1); + const signature = await signOrder(order, chainId, contracts.swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, swap.address, order); + const data = buildOrderData(chainId, contracts.swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'BitInvalidatedOrder'); + await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'BitInvalidatedOrder'); }); it('epoch change, order should fail', async function () { - const { swap, chainId, order } = await loadFixture(orderWithEpochInit); + const { contracts, chainId, order } = await loadFixture(orderWithEpochInit); - await swap.connect(addr1).increaseEpoch(1); + await contracts.swap.connect(addr1).increaseEpoch(1); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2))) - .to.be.revertedWithCustomError(swap, 'WrongSeriesNonce'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2))) + .to.be.revertedWithCustomError(contracts.swap, 'WrongSeriesNonce'); }); it('epoch change should not affect other addresses', async function () { - const { dai, weth, swap, chainId, order } = await loadFixture(orderWithEpochInit); + const { tokens, contracts, chainId, order } = await loadFixture(orderWithEpochInit); - await swap.connect(addr2).increaseEpoch(1); + await contracts.swap.connect(addr2).increaseEpoch(1); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('epoch change, partially filled order should fail', async function () { - const { dai, weth, swap, chainId, order } = await loadFixture(orderWithEpochInit); + const { tokens, contracts, chainId, order } = await loadFixture(orderWithEpochInit); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); - await swap.connect(addr1).increaseEpoch(1); + await contracts.swap.connect(addr1).increaseEpoch(1); - await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'WrongSeriesNonce'); + await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'WrongSeriesNonce'); }); it('advance nonce', async function () { - const { swap } = await loadFixture(deployContractsAndInit); - await swap.increaseEpoch(0); - expect(await swap.epoch(addr.address, 0)).to.equal('1'); + const { contracts } = await loadFixture(deployContractsAndInit); + await contracts.swap.increaseEpoch(0); + expect(await contracts.swap.epoch(addr.address, 0)).to.equal('1'); }); }); describe('Private Orders', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - it('should fill with correct taker', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ allowedSender: addr.address }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('should not fill with incorrect taker', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ allowedSender: addr1.address }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'PrivateOrder'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'PrivateOrder'); }); }); describe('Predicate', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - const { arbitraryPredicate } = await deployArbitraryPredicate(); - await initContracts(dai, weth, swap); - const orderLibFactory = await ethers.getContractFactory('OrderLib'); - return { dai, weth, swap, chainId, arbitraryPredicate, orderLibFactory }; - }; - it('arbitrary call predicate should pass', async function () { - const { dai, weth, swap, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); + const predicate = contracts.swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1216,29 +1151,29 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension, }); - const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('arbitrary call predicate should fail', async function () { - const { dai, weth, swap, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = swap.interface.encodeFunctionData('gt', [10, arbitraryCall]); + const predicate = contracts.swap.interface.encodeFunctionData('gt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1248,32 +1183,32 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension, }); - await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(swap, 'PredicateIsNotTrue'); + await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(contracts.swap, 'PredicateIsNotTrue'); }); it('`or` should pass', async function () { - const { dai, weth, swap, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); - const comparegt = swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); + const comparelt = contracts.swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); + const comparegt = contracts.swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = swap.interface.encodeFunctionData('or', [offsets, data]); + const predicate = contracts.swap.interface.encodeFunctionData('or', [offsets, data]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1283,33 +1218,33 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension, }); - const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('`or` should fail', async function () { - const { dai, weth, swap, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); - const comparegt = swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); + const comparelt = contracts.swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); + const comparegt = contracts.swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = swap.interface.encodeFunctionData('or', [offsets, data]); + const predicate = contracts.swap.interface.encodeFunctionData('or', [offsets, data]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1319,32 +1254,32 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension, }); - await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(swap, 'PredicateIsNotTrue'); + await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(contracts.swap, 'PredicateIsNotTrue'); }); it('`and` should pass', async function () { - const { dai, weth, swap, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); - const comparegt = swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); + const comparelt = contracts.swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); + const comparegt = contracts.swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = swap.interface.encodeFunctionData('and', [offsets, data]); + const predicate = contracts.swap.interface.encodeFunctionData('and', [offsets, data]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1354,33 +1289,33 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension, }); - const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('`and` should fail', async function () { - const { dai, weth, swap, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); - const comparegt = swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); + const comparelt = contracts.swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); + const comparegt = contracts.swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = swap.interface.encodeFunctionData('and', [offsets, data]); + const predicate = contracts.swap.interface.encodeFunctionData('and', [offsets, data]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1390,28 +1325,28 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension, }); - await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(swap, 'PredicateIsNotTrue'); + await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(contracts.swap, 'PredicateIsNotTrue'); }); it('should fail with invalid extension (empty extension)', async function () { - const { dai, weth, swap, orderLibFactory, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); + const predicate = contracts.swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1421,27 +1356,27 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, }); - await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) .to.be.revertedWithCustomError(orderLibFactory, 'MissingOrderExtension'); }); it('should fail with invalid extension (mismatched extension)', async function () { - const { dai, weth, swap, orderLibFactory, chainId, arbitraryPredicate } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ - arbitraryPredicate.address, - arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ + contracts.arbitraryPredicate.address, + contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); + const predicate = contracts.swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1451,220 +1386,208 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: order.extension + '0011223344', }); - await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) .to.be.revertedWithCustomError(orderLibFactory, 'InvalidExtensionHash'); }); it('should fail with invalid extension (unexpected extension)', async function () { - const { dai, weth, swap, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); const takerTraits = buildTakerTraits({ minReturn: 1n, extension: '0xabacabac', }); - await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) .to.be.revertedWithCustomError(orderLibFactory, 'UnexpectedOrderExtension'); }); }); describe('Expiration', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId }; - }; - it('should fill when not expired', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: (await time.latest()) + 3600 }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, fillWithMakingAmount(1), 1); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, fillWithMakingAmount(1), 1); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('should not fill when expired', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: 0xff0000n }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'OrderExpired'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'OrderExpired'); }); it('should not partially fill when expired', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: await time.latest() }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'OrderExpired'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'OrderExpired'); }); it('should not fill partially filled order after expiration', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: await time.latest() + 1800 }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); await time.increase(3600); - await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(swap, 'OrderExpired'); + await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(contracts.swap, 'OrderExpired'); }); it('should fill partially if not enough coins (taker)', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 3, 2); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [2, -2]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-2, 2]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 3, 2); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [2, -2]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-2, 2]); }); it('should fill partially if not enough coins (maker)', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 3, fillWithMakingAmount(3)); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [2, -2]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-2, 2]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 3, fillWithMakingAmount(3)); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [2, -2]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-2, 2]); }); }); describe('ETH fill', function () { - const deployContractsAndInit = async function () { - const { dai, weth, swap, chainId, usdc } = await deploySwapTokens(); - await initContracts(dai, weth, swap); - return { dai, weth, swap, chainId, usdc }; - }; - it('should fill with ETH', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 3 }); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [900, -900]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [0, 3]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 3 }); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [900, -900]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [0, 3]); await expect(fillTx).to.changeEtherBalance(addr, -3); }); it('should revert with takerAsset WETH and not enough msg.value', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 2 })) - .to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 2 })) + .to.be.revertedWithCustomError(contracts.swap, 'InvalidMsgValue'); }); it('should pass with takerAsset WETH and correct msg.value', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [900, -900]); - await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [0, 3]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [900, -900]); + await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [0, 3]); await expect(fillTx).to.changeEtherBalance(addr, -3); }); it('should pass with takerAsset WETH and correct msg.value and unwrap flag is set', async function () { - const { dai, weth, swap, chainId } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, @@ -1673,30 +1596,30 @@ describe('LimitOrderProtocol', function () { }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const fillTx = swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); - await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [900, -900]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const fillTx = contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); + await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [900, -900]); await expect(fillTx).to.changeEtherBalance(addr, -3); await expect(fillTx).to.changeEtherBalance(addr1, 3); }); it('should reverted with takerAsset non-WETH and msg.value greater than 0', async function () { - const { dai, swap, chainId, usdc } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - await usdc.mint(addr.address, '1000000'); - await usdc.approve(swap.address, '1000000'); + await tokens.usdc.mint(addr.address, '1000000'); + await tokens.usdc.approve(contracts.swap.address, '1000000'); const order = buildOrder({ - makerAsset: dai.address, - takerAsset: usdc.address, + makerAsset: tokens.dai.address, + takerAsset: tokens.usdc.address, makingAmount: 900, takingAmount: 900, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - await expect(swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(900), { value: 1 })) - .to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + await expect(contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(900), { value: 1 })) + .to.be.revertedWithCustomError(contracts.swap, 'InvalidMsgValue'); }); }); }); From 4c0c6d9cece9e0e7f809fdfa650f13062706f7bf Mon Sep 17 00:00:00 2001 From: byshape Date: Wed, 13 Dec 2023 15:41:28 +0000 Subject: [PATCH 2/5] Fixed tests after merge --- test/LimitOrderProtocol.js | 90 +++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/test/LimitOrderProtocol.js b/test/LimitOrderProtocol.js index fe883f94..4215dea1 100644 --- a/test/LimitOrderProtocol.js +++ b/test/LimitOrderProtocol.js @@ -53,11 +53,17 @@ describe('LimitOrderProtocol', function () { permits.taker.signature = { r, vs }; // Maker permit + const deadline = (await time.latest()) + time.duration.weeks(1); const permit = withTarget( weth.address, - await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'), + await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1', deadline), + ); + const permit2 = withTarget( + weth.address, + await getPermit2(addr, weth.address, chainId, swap.address, 1, false, constants.MAX_UINT48, deadline), ); permits.maker.permit = permit; + permits.maker.permit2 = permit2; permits.maker.order = buildOrder( { makerAsset: weth.address, @@ -70,10 +76,28 @@ describe('LimitOrderProtocol', function () { permit, }, ); + + permits.maker.orderPermit2 = buildOrder( + { + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: 1, + takingAmount: 1, + maker: addr.address, + makerTraits: buildMakerTraits({ usePermit2: true }), + }, + { + permit: permit2, + }, + ); + contracts.permit2Contract = await permit2Contract(); + await weth.approve(contracts.permit2Contract.address, 1); const { r: r1, _vs: vs1 } = ethers.utils.splitSignature(await signOrder(permits.maker.order, chainId, swap.address, addr)); + const { r: r2, _vs: vs2 } = ethers.utils.splitSignature(await signOrder(permits.maker.orderPermit2, chainId, swap.address, addr)); permits.maker.signature = { r: r1, vs: vs1 }; + permits.maker.signaturePermit2 = { r: r2, vs: vs2 }; - return { tokens, contracts, chainId, orderLibFactory, permits }; + return { tokens, contracts, chainId, orderLibFactory, permits, deadline }; }; describe('wip', function () { @@ -153,7 +177,7 @@ describe('LimitOrderProtocol', function () { const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); await expect(contracts.swap.fillOrder(order, r, vs, 3, 4)) - .to.be.revertedWithCustomError(swap, 'MakingAmountTooLow'); + .to.be.revertedWithCustomError(contracts.swap, 'MakingAmountTooLow'); }); it('should not fill below threshold', async function () { @@ -586,11 +610,9 @@ describe('LimitOrderProtocol', function () { }); it('skips expired permit if allowance is enough', async function () { - const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, permits, deadline } = await loadFixture(deployContractsAndInit); const { r, vs } = permits.maker.signature; - const deadline = (await time.latest()) + time.duration.weeks(1); - tokens.weth.approve(contracts.swap.address, '1'); await time.increaseTo(deadline + 1); const takerTraits = buildTakerTraits({ @@ -598,16 +620,16 @@ describe('LimitOrderProtocol', function () { makingAmount: true, extension: permits.maker.order.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('rejects expired permit when allowance is not enough', async function () { - const { contracts, permits } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, permits, deadline } = await loadFixture(deployContractsAndInit); const { r, vs } = permits.maker.signature; - const deadline = (await time.latest()) + time.duration.weeks(1); + await tokens.weth.approve(contracts.swap.address, '0'); await time.increaseTo(deadline + 1); const takerTraits = buildTakerTraits({ @@ -648,8 +670,6 @@ describe('LimitOrderProtocol', function () { const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); const { r, vs } = permits.taker.signature; - const permit2 = await permit2Contract(); - await tokens.weth.approve(permit2.address, 1); const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); const takerTraits = buildTakerTraits({ @@ -672,24 +692,20 @@ describe('LimitOrderProtocol', function () { }); it('Skips expired permit if allowance is enough', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); + const { tokens, contracts, chainId, permits, deadline } = await loadFixture(deployContractsAndInit); const { r, vs } = permits.taker.signature; - const permit2 = await permit2Contract(); - await tokens.weth.approve(permit2.address, 1); - const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); const tx = { from: addr.address, - to: permit2.address, + to: contracts.permit2Contract.address, data: ethers.utils.hexConcat([ - permit2.interface.getSighash('permit'), + contracts.permit2Contract.interface.getSighash('permit'), permit, ]), }; await addr.sendTransaction(tx); - const deadline = BigNumber.from((await time.latest()) - time.duration.weeks(1)); const permitExpired = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1, false, constants.MAX_UINT48, deadline); const takerTraits = buildTakerTraits({ @@ -697,7 +713,7 @@ describe('LimitOrderProtocol', function () { makingAmount: true, usePermit2: true, }); - const fillTx = swap.permitAndCall( + const fillTx = contracts.swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], [tokens.weth.address, permitExpired], @@ -714,8 +730,6 @@ describe('LimitOrderProtocol', function () { const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); const { r, vs } = permits.taker.signature; - const permit2 = await permit2Contract(); - await tokens.weth.approve(permit2.address, 1); const deadline = BigNumber.from((await time.latest()) - time.duration.weeks(1)); const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1, false, constants.MAX_UINT48, deadline); @@ -752,8 +766,6 @@ describe('LimitOrderProtocol', function () { }, ); - const permit2 = await permit2Contract(); - await tokens.weth.approve(permit2.address, 1); const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); @@ -782,30 +794,28 @@ describe('LimitOrderProtocol', function () { // bad permit | + | + | it('Maker permit works', async function () { const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; + const { r, vs } = permits.maker.signaturePermit2; const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.make.order.extension, + extension: permits.maker.orderPermit2.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.make.order, r, vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.orderPermit2, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('Skips expired permit if allowance is enough', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; - const permit2 = await permit2Contract(); - const deadline = (await time.latest()) + time.duration.weeks(1); + const { tokens, contracts, chainId, permits, deadline } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.maker.signaturePermit2; const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); const tx = { from: addr.address, - to: permit2.address, + to: contracts.permit2Contract.address, data: ethers.utils.hexConcat([ - permit2.interface.getSighash('permit'), + contracts.permit2Contract.interface.getSighash('permit'), permit, ]), }; @@ -816,33 +826,31 @@ describe('LimitOrderProtocol', function () { const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.order.extension, + extension: permits.maker.orderPermit2.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.orderPermit2, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); }); it('Fails with expired permit if allowance is not enough', async function () { - const { contracts, permit } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; - const deadline = (await time.latest()) + time.duration.weeks(1); + const { contracts, permits, deadline } = await loadFixture(deployContractsAndInit); + const { r, vs } = permits.maker.signaturePermit2; await time.increaseTo(deadline + 1); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.order.extension, + extension: permits.maker.orderPermit2.extension, }); await expect(contracts.swap.connect(addr1).fillOrderArgs( - permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + permits.maker.orderPermit2, r, vs, 1, takerTraits.traits, takerTraits.args, )).to.be.revertedWithCustomError(contracts.swap, 'SafeTransferFromFailed'); }); it('Fails with unexpected makerAssetSuffix', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); - const deadline = (await time.latest()) + time.duration.weeks(1); + const { tokens, contracts, chainId, deadline } = await loadFixture(deployContractsAndInit); const permit = withTarget( tokens.weth.address, await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1, false, constants.MAX_UINT48, deadline), From 816b3bc422624dcbbf844609ecb4afe7289edeae Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 15 Dec 2023 14:47:32 +0400 Subject: [PATCH 3/5] simplify --- test/LimitOrderProtocol.js | 1318 ++++++++++++++++++------------------ 1 file changed, 670 insertions(+), 648 deletions(-) diff --git a/test/LimitOrderProtocol.js b/test/LimitOrderProtocol.js index 4215dea1..b30abfde 100644 --- a/test/LimitOrderProtocol.js +++ b/test/LimitOrderProtocol.js @@ -15,7 +15,11 @@ describe('LimitOrderProtocol', function () { [addr, addr1, addr2] = await ethers.getSigners(); }); - async function initContracts (dai, weth, swap) { + async function deployContractsAndInit () { + const { dai, weth, usdc, swap, chainId } = await deploySwapTokens(); + const tokens = { dai, weth, usdc }; + const contracts = { swap }; + await dai.mint(addr1.address, ether('1000000')); await dai.mint(addr.address, ether('1000000')); await weth.deposit({ value: ether('100') }); @@ -24,13 +28,6 @@ describe('LimitOrderProtocol', function () { await dai.connect(addr1).approve(swap.address, ether('1000000')); await weth.approve(swap.address, ether('100')); await weth.connect(addr1).approve(swap.address, ether('100')); - }; - - const deployContractsAndInit = async function () { - const { dai, weth, usdc, swap, chainId } = await deploySwapTokens(); - const tokens = { dai, weth, usdc }; - const contracts = { swap }; - await initContracts(dai, weth, swap); const ETHOrders = await ethers.getContractFactory('ETHOrders'); contracts.ethOrders = await ETHOrders.deploy(weth.address, swap.address); @@ -102,159 +99,159 @@ describe('LimitOrderProtocol', function () { describe('wip', function () { it('transferFrom', async function () { - const { tokens } = await loadFixture(deployContractsAndInit); + const { tokens: { dai } } = await loadFixture(deployContractsAndInit); - await tokens.dai.connect(addr1).approve(addr.address, '2'); - await tokens.dai.transferFrom(addr1.address, addr.address, '1'); + await dai.connect(addr1).approve(addr.address, '2'); + await dai.transferFrom(addr1.address, addr.address, '1'); }); it('should not swap with bad signature', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, }); const fakeOrder = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(fakeOrder, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'BadSignature'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(fakeOrder, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'BadSignature'); }); it('should not fill above threshold', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'TakingAmountTooHigh'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'TakingAmountTooHigh'); }); it('should not fill above threshold, making amount > remaining making amount', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 3, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'TakingAmountTooHigh'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 3, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'TakingAmountTooHigh'); }); it('should not fill below threshold, making amount > remaining making amount', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 3, 4)) - .to.be.revertedWithCustomError(contracts.swap, 'MakingAmountTooLow'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 3, 4)) + .to.be.revertedWithCustomError(swap, 'MakingAmountTooLow'); }); it('should not fill below threshold', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 2, 3)) - .to.be.revertedWithCustomError(contracts.swap, 'MakingAmountTooLow'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 2, 3)) + .to.be.revertedWithCustomError(swap, 'MakingAmountTooLow'); }); it('should fill without checks with threshold == 0', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 10, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: true }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); - const swapWithoutThreshold = await contracts.swap.fillOrder(order, r, vs, 5, 0); + const swapWithoutThreshold = await swap.fillOrder(order, r, vs, 5, 0); const gasUsedWithoutThreshold = (await swapWithoutThreshold.wait()).gasUsed; await loadFixture(deployContractsAndInit); - const swapWithThreshold = await contracts.swap.fillOrder(order, r, vs, 5, 1); + const swapWithThreshold = await swap.fillOrder(order, r, vs, 5, 1); expect((await swapWithThreshold.wait()).gasUsed).to.gt(gasUsedWithoutThreshold); }); it('should fail when amount is zero', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 100, takingAmount: 1, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 0, 0)) - .to.be.revertedWithCustomError(contracts.swap, 'SwapWithZeroAmount'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 0, 0)) + .to.be.revertedWithCustomError(swap, 'SwapWithZeroAmount'); }); it('should swap fully based on signature', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 1 DAI => 1 WETH // Swap: 1 DAI => 1 WETH for (const nonce of [0, 1]) { const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); if (hre.__SOLIDITY_COVERAGE_RUNNING === undefined) { - const trace = findTrace(tracer, 'CALL', contracts.swap.address); + const trace = findTrace(tracer, 'CALL', swap.address); const opcodes = trace.children.map(item => item.opcode); expect(countAllItems(opcodes)).to.deep.equal({ STATICCALL: 1, CALL: 2, SLOAD: 1, SSTORE: 1, LOG1: 1 }); } @@ -262,117 +259,117 @@ describe('LimitOrderProtocol', function () { }); it('should swap half based on signature', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 2 DAI => 2 WETH // Swap: 1 DAI => 1 WETH const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); if (hre.__SOLIDITY_COVERAGE_RUNNING === undefined) { - const trace = findTrace(tracer, 'CALL', contracts.swap.address); + const trace = findTrace(tracer, 'CALL', swap.address); const opcodes = trace.children.map(item => item.opcode); expect(countAllItems(opcodes)).to.deep.equal({ STATICCALL: 1, CALL: 2, SLOAD: 1, SSTORE: 1, LOG1: 1 }); } }); it('should floor maker amount', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 2 DAI => 10 WETH // Swap: 9 WETH <= 1 DAI const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 10, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 9, 1); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-9, 9]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 9, 1); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-9, 9]); }); it('should fail on floor maker amount = 0', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 2 DAI => 10 WETH // Swap: 4 WETH <= 0 DAI const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 10, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 4, 0)) - .to.be.revertedWithCustomError(contracts.swap, 'SwapWithZeroAmount'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 4, 0)) + .to.be.revertedWithCustomError(swap, 'SwapWithZeroAmount'); }); it('should ceil taker amount', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [4, -4]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [4, -4]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('should unwrap weth', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('2'), takingAmount: ether('10'), maker: addr1.address, }); - await tokens.weth.connect(addr1).deposit({ value: ether('2') }); + await weth.connect(addr1).deposit({ value: ether('2') }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, ether('5'), unwrapWethTaker(ether('1'))); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [ether('-5'), ether('5')]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [ether('0'), ether('-1')]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, ether('5'), unwrapWethTaker(ether('1'))); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [ether('-5'), ether('5')]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [ether('0'), ether('-1')]); await expect(fillTx).to.changeEtherBalance(addr, ether('1')); }); it('ERC721Proxy should work', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const ERC721Proxy = await ethers.getContractFactory('ERC721Proxy'); - const erc721proxy = await ERC721Proxy.deploy(contracts.swap.address); + const erc721proxy = await ERC721Proxy.deploy(swap.address); await erc721proxy.deployed(); - await tokens.dai.connect(addr1).approve(erc721proxy.address, '10'); - await tokens.weth.approve(erc721proxy.address, '10'); + await dai.connect(addr1).approve(erc721proxy.address, '10'); + await weth.approve(erc721proxy.address, '10'); const order = buildOrder( { @@ -384,133 +381,133 @@ describe('LimitOrderProtocol', function () { maker: addr1.address, }, { - makerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [addr1.address, constants.ZERO_ADDRESS, 0, 10, tokens.dai.address]).substring(202), - takerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [constants.ZERO_ADDRESS, addr1.address, 0, 10, tokens.weth.address]).substring(202), + makerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [addr1.address, constants.ZERO_ADDRESS, 0, 10, dai.address]).substring(202), + takerAssetSuffix: '0x' + erc721proxy.interface.encodeFunctionData('func_60iHVgK', [constants.ZERO_ADDRESS, addr1.address, 0, 10, weth.address]).substring(202), }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 10n, makingAmount: true, extension: order.extension, }); - const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 10, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-10, 10]); + const fillTx = swap.fillOrderArgs(order, r, vs, 10, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-10, 10]); }); }); describe('MakerTraits', function () { it('disallow multiple fills', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ allowMultipleFills: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [4, -4]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [4, -4]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); - await expect(contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'BitInvalidatedOrder'); + await expect(swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'BitInvalidatedOrder'); }); it('need epoch manager, success', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ shouldCheckEpoch: true }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [4, -4]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [4, -4]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('need epoch manager, fail', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 4 DAI => 1 WETH const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ shouldCheckEpoch: true, nonce: 1 }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'WrongSeriesNonce'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'WrongSeriesNonce'); }); it('unwrap weth for maker', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); // Order: 10 DAI => 2 WETH // Swap: 10 DAI => 2 ETH const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ unwrapWeth: true }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(2)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalance(tokens.weth, addr, -2); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(2)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalance(weth, addr, -2); await expect(fillTx).to.changeEtherBalance(addr1, 2); }); }); describe('TakerTraits', function () { it('DAI => WETH, send WETH to address different from msg.sender when fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const otherAddress = addr2; const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1800, takingAmount: 1, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ target: otherAddress.address, }); - const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalance(tokens.dai, addr1, -1800); - await expect(fillTx).to.changeTokenBalance(tokens.weth, addr, -1); + await expect(fillTx).to.changeTokenBalance(dai, addr1, -1800); + await expect(fillTx).to.changeTokenBalance(weth, addr, -1); // Pay out happened to otherAddress, specified in taker traits - await expect(fillTx).to.changeTokenBalance(tokens.dai, otherAddress, 1800); + await expect(fillTx).to.changeTokenBalance(dai, otherAddress, 1800); }); }); @@ -522,69 +519,72 @@ describe('LimitOrderProtocol', function () { // bad permit | + | + | it('DAI => WETH, no allowance', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.taker.signature; + const { + tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + } = await loadFixture(deployContractsAndInit); - const permit = await getPermit(addr.address, addr, tokens.weth, '1', chainId, contracts.swap.address, '1'); + const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, }); - await tokens.weth.approve(contracts.swap.address, '0'); - const fillTx = contracts.swap.permitAndCall( + await weth.approve(swap.address, '0'); + const fillTx = swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permit], + [weth.address, permit], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ - permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + swap.interface.encodeFunctionData('fillOrderArgs', [ + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('skips expired permit if allowance is enough', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.taker.signature; + const { + tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + } = await loadFixture(deployContractsAndInit); const deadline = (await time.latest()) - time.duration.weeks(1); - const permit = await getPermit(addr.address, addr, tokens.weth, '1', chainId, contracts.swap.address, '1', deadline); + const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1', deadline); const takerTraits = buildTakerTraits({ threshold: 1n }); - const fillTx = contracts.swap.permitAndCall( + const fillTx = swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permit], + [weth.address, permit], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ - permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + swap.interface.encodeFunctionData('fillOrderArgs', [ + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('rejects expired permit when allowance is not enough', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.taker.signature; + const { + tokens: { weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + } = await loadFixture(deployContractsAndInit); const deadline = (await time.latest()) - time.duration.weeks(1); - const permit = await getPermit(addr.address, addr, tokens.weth, '1', chainId, contracts.swap.address, '1', deadline); + const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1', deadline); - await tokens.weth.approve(contracts.swap.address, '0'); + await weth.approve(swap.address, '0'); const takerTraits = buildTakerTraits({ threshold: 1n }); - await expect(contracts.swap.permitAndCall( + await expect(swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permit], + [weth.address, permit], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ - permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + swap.interface.encodeFunctionData('fillOrderArgs', [ + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, ]), - )).to.be.revertedWithCustomError(contracts.swap, 'TransferFromTakerToMakerFailed'); + )).to.be.revertedWithCustomError(swap, 'TransferFromTakerToMakerFailed'); }); }); @@ -595,67 +595,77 @@ describe('LimitOrderProtocol', function () { // bad permit | + | + | it('Maker permit works, no allowance', async function () { - const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; + const { + tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, + } = await loadFixture(deployContractsAndInit); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.order.extension, + extension: orderData.order.extension, }); - await tokens.weth.approve(contracts.swap.address, '0'); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + await weth.approve(swap.address, '0'); + const fillTx = swap.connect(addr1).fillOrderArgs( + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, + ); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('skips expired permit if allowance is enough', async function () { - const { tokens, contracts, permits, deadline } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; + const { + tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, deadline, + } = await loadFixture(deployContractsAndInit); await time.increaseTo(deadline + 1); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.order.extension, + extension: orderData.order.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.connect(addr1).fillOrderArgs( + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, + ); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('rejects expired permit when allowance is not enough', async function () { - const { tokens, contracts, permits, deadline } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; + const { + tokens: { weth }, contracts: { swap }, permits: { maker: orderData }, deadline, + } = await loadFixture(deployContractsAndInit); - await tokens.weth.approve(contracts.swap.address, '0'); + await weth.approve(swap.address, '0'); await time.increaseTo(deadline + 1); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.order.extension, + extension: orderData.order.extension, }); - await expect(contracts.swap.connect(addr1).fillOrderArgs( - permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args, - )).to.be.revertedWithCustomError(contracts.swap, 'TransferFromMakerToTakerFailed'); + await expect(swap.connect(addr1).fillOrderArgs( + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, + )).to.be.revertedWithCustomError(swap, 'TransferFromMakerToTakerFailed'); }); it('skips order permit flag', async function () { - const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signature; + const { + tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, + } = await loadFixture(deployContractsAndInit); - await tokens.weth.approve(contracts.swap.address, '0'); - await addr1.sendTransaction({ to: tokens.weth.address, data: '0xd505accf' + permits.maker.permit.substring(42) }); + await weth.approve(swap.address, '0'); + await addr1.sendTransaction({ to: weth.address, data: '0xd505accf' + orderData.permit.substring(42) }); const takerTraits = buildTakerTraits({ threshold: 0n, skipMakerPermit: true, - extension: permits.maker.order.extension, + extension: orderData.order.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.connect(addr1).fillOrderArgs( + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, + ); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); }); }); @@ -667,123 +677,128 @@ describe('LimitOrderProtocol', function () { // ok permit | - | + | // bad permit | + | + | it('DAI => WETH, no allowance', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.taker.signature; + const { + tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + } = await loadFixture(deployContractsAndInit); - const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); + const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, usePermit2: true, }); - await tokens.weth.approve(contracts.swap.address, '0'); - const fillTx = contracts.swap.permitAndCall( + await weth.approve(swap.address, '0'); + const fillTx = swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permit], + [weth.address, permit], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ - permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + swap.interface.encodeFunctionData('fillOrderArgs', [ + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('Skips expired permit if allowance is enough', async function () { - const { tokens, contracts, chainId, permits, deadline } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.taker.signature; + const { + tokens: { dai, weth }, contracts: { swap, permit2Contract }, chainId, permits: { taker: orderData }, deadline, + } = await loadFixture(deployContractsAndInit); - const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); + const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); const tx = { from: addr.address, - to: contracts.permit2Contract.address, + to: permit2Contract.address, data: ethers.utils.hexConcat([ - contracts.permit2Contract.interface.getSighash('permit'), + permit2Contract.interface.getSighash('permit'), permit, ]), }; await addr.sendTransaction(tx); - const permitExpired = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1, false, constants.MAX_UINT48, deadline); + const permitExpired = await getPermit2(addr, weth.address, chainId, swap.address, 1, false, constants.MAX_UINT48, deadline); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, usePermit2: true, }); - const fillTx = contracts.swap.permitAndCall( + const fillTx = swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permitExpired], + [weth.address, permitExpired], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ - permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + swap.interface.encodeFunctionData('fillOrderArgs', [ + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, ]), ); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('Fails with expired permit if allowance is not enough', async function () { - const { tokens, contracts, chainId, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.taker.signature; + const { + tokens: { weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + } = await loadFixture(deployContractsAndInit); const deadline = BigNumber.from((await time.latest()) - time.duration.weeks(1)); - const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1, false, constants.MAX_UINT48, deadline); + const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1, false, constants.MAX_UINT48, deadline); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, usePermit2: true, }); - await expect(contracts.swap.permitAndCall( + await expect(swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permit], + [weth.address, permit], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ - permits.taker.order, r, vs, 1, takerTraits.traits, takerTraits.args, + swap.interface.encodeFunctionData('fillOrderArgs', [ + orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, ]), - )).to.be.revertedWithCustomError(contracts.swap, 'SafeTransferFromFailed'); + )).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); }); it('Fails with unexpected takerAssetSuffix', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { + tokens: { weth, dai }, contracts: { swap }, chainId, + } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ }), }, { - takerAssetSuffix: tokens.weth.address, + takerAssetSuffix: weth.address, }, ); - const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); + const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, usePermit2: true, extension: order.extension, }); - await expect(contracts.swap.permitAndCall( + await expect(swap.permitAndCall( ethers.utils.solidityPack( ['address', 'bytes'], - [tokens.weth.address, permit], + [weth.address, permit], ), - contracts.swap.interface.encodeFunctionData('fillOrderArgs', [ + swap.interface.encodeFunctionData('fillOrderArgs', [ order, r, vs, 1, takerTraits.traits, takerTraits.args, ]), - )).to.be.revertedWithCustomError(contracts.swap, 'InvalidPermit2Transfer'); + )).to.be.revertedWithCustomError(swap, 'InvalidPermit2Transfer'); }); }); @@ -793,29 +808,31 @@ describe('LimitOrderProtocol', function () { // ok permit | - | + | // bad permit | + | + | it('Maker permit works', async function () { - const { tokens, contracts, permits } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signaturePermit2; + const { + tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, + } = await loadFixture(deployContractsAndInit); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.orderPermit2.extension, + extension: orderData.orderPermit2.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.orderPermit2, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.connect(addr1).fillOrderArgs(orderData.orderPermit2, orderData.signaturePermit2.r, orderData.signaturePermit2.vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('Skips expired permit if allowance is enough', async function () { - const { tokens, contracts, chainId, permits, deadline } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signaturePermit2; + const { + tokens: { dai, weth }, contracts: { swap, permit2Contract }, chainId, permits: { maker: orderData }, deadline, + } = await loadFixture(deployContractsAndInit); - const permit = await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1); + const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); const tx = { from: addr.address, - to: contracts.permit2Contract.address, + to: permit2Contract.address, data: ethers.utils.hexConcat([ - contracts.permit2Contract.interface.getSighash('permit'), + permit2Contract.interface.getSighash('permit'), permit, ]), }; @@ -826,40 +843,41 @@ describe('LimitOrderProtocol', function () { const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.orderPermit2.extension, + extension: orderData.orderPermit2.extension, }); - const fillTx = contracts.swap.connect(addr1).fillOrderArgs(permits.maker.orderPermit2, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.connect(addr1).fillOrderArgs(orderData.orderPermit2, orderData.signaturePermit2.r, orderData.signaturePermit2.vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('Fails with expired permit if allowance is not enough', async function () { - const { contracts, permits, deadline } = await loadFixture(deployContractsAndInit); - const { r, vs } = permits.maker.signaturePermit2; + const { + contracts: { swap }, permits: { maker: orderData }, deadline, + } = await loadFixture(deployContractsAndInit); await time.increaseTo(deadline + 1); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: permits.maker.orderPermit2.extension, + extension: orderData.orderPermit2.extension, }); - await expect(contracts.swap.connect(addr1).fillOrderArgs( - permits.maker.orderPermit2, r, vs, 1, takerTraits.traits, takerTraits.args, - )).to.be.revertedWithCustomError(contracts.swap, 'SafeTransferFromFailed'); + await expect(swap.connect(addr1).fillOrderArgs( + orderData.orderPermit2, orderData.signaturePermit2.r, orderData.signaturePermit2.vs, 1, takerTraits.traits, takerTraits.args, + )).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); }); it('Fails with unexpected makerAssetSuffix', async function () { - const { tokens, contracts, chainId, deadline } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId, deadline } = await loadFixture(deployContractsAndInit); const permit = withTarget( - tokens.weth.address, - await getPermit2(addr, tokens.weth.address, chainId, contracts.swap.address, 1, false, constants.MAX_UINT48, deadline), + weth.address, + await getPermit2(addr, weth.address, chainId, swap.address, 1, false, constants.MAX_UINT48, deadline), ); const order = buildOrder( { - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: 1, takingAmount: 1, maker: addr.address, @@ -867,186 +885,186 @@ describe('LimitOrderProtocol', function () { }, { permit, - makerAssetSuffix: tokens.weth.address, + makerAssetSuffix: weth.address, }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr)); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, extension: order.extension, }); - await expect(contracts.swap.connect(addr1).fillOrderArgs( + await expect(swap.connect(addr1).fillOrderArgs( order, r, vs, 1, takerTraits.traits, takerTraits.args, - )).to.be.revertedWithCustomError(contracts.swap, 'InvalidPermit2Transfer'); + )).to.be.revertedWithCustomError(swap, 'InvalidPermit2Transfer'); }); }); }); describe('Amount Calculator', function () { it('empty takingAmountData should work on full fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(10)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-10, 10]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 10, fillWithMakingAmount(10)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-10, 10]); }); it('empty takingAmountData should revert on partial fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 5, fillWithMakingAmount(5))) - .to.be.revertedWithCustomError(contracts.swap, 'PartialFillNotAllowed'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 5, fillWithMakingAmount(5))) + .to.be.revertedWithCustomError(swap, 'PartialFillNotAllowed'); }); it('empty makingAmountData should revert on partial fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 5, 5)) - .to.be.revertedWithCustomError(contracts.swap, 'PartialFillNotAllowed'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 5, 5)) + .to.be.revertedWithCustomError(swap, 'PartialFillNotAllowed'); }); it('empty makingAmountData should work on full fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ maker: addr1.address, - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 10, makerTraits: buildMakerTraits({ allowPartialFill: false }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 10, 10); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [10, -10]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-10, 10]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 10, 10); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [10, -10]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-10, 10]); }); }); describe('ETH Maker Orders', function () { it('Partial fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, ethOrders }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: contracts.ethOrders.address, + maker: ethOrders.address, receiver: addr1.address, - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: contracts.ethOrders.address, + postInteraction: ethOrders.address, }, ); - const orderHash = await contracts.swap.hashOrder(order); + const orderHash = await swap.hashOrder(order); - const deposittx = contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); + const deposittx = ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); await expect(deposittx).to.changeEtherBalance(addr1, ether('-0.3')); - await expect(deposittx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('0.3')); + await expect(deposittx).to.changeTokenBalance(weth, ethOrders, ether('0.3')); - let orderMakerBalance = await contracts.ethOrders.ordersMakersBalances(orderHash); + let orderMakerBalance = await ethOrders.ordersMakersBalances(orderHash); expect(orderMakerBalance.balance).to.equal(ether('0.3')); expect(orderMakerBalance.maker).to.equal(addr1.address); - const ethOrdersBatch = await contracts.ethOrders.ethOrdersBatch([orderHash]); + const ethOrdersBatch = await ethOrders.ethOrdersBatch([orderHash]); expect(ethOrdersBatch[0].balance).to.equal(ether('0.3')); expect(ethOrdersBatch[0].maker).to.equal(addr1.address); - const signature = await signOrder(order, chainId, contracts.swap.address, addr1); + const signature = await signOrder(order, chainId, swap.address, addr1); /// Partial fill const takerTraits1 = buildTakerTraits({ threshold: ether('0.2'), extension: order.extension, }); - const fillTx1 = contracts.swap.fillContractOrderArgs(order, signature, ether('200'), takerTraits1.traits, takerTraits1.args); - await expect(fillTx1).to.changeTokenBalances(tokens.dai, [addr, contracts.ethOrders, addr1], [ether('-200'), '0', ether('200')]); - await expect(fillTx1).to.changeTokenBalances(tokens.weth, [addr, contracts.ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); + const fillTx1 = swap.fillContractOrderArgs(order, signature, ether('200'), takerTraits1.traits, takerTraits1.args); + await expect(fillTx1).to.changeTokenBalances(dai, [addr, ethOrders, addr1], [ether('-200'), '0', ether('200')]); + await expect(fillTx1).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); /// Remaining fill const takerTraits2 = buildTakerTraits({ threshold: ether('0.1'), extension: order.extension, }); - const fillTx2 = contracts.swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits2.traits, takerTraits2.args); - await expect(fillTx2).to.changeTokenBalances(tokens.dai, [addr, contracts.ethOrders, addr1], [ether('-100'), '0', ether('100')]); - await expect(fillTx2).to.changeTokenBalances(tokens.weth, [addr, contracts.ethOrders, addr1], [ether('0.1'), ether('-0.1'), '0']); + const fillTx2 = swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits2.traits, takerTraits2.args); + await expect(fillTx2).to.changeTokenBalances(dai, [addr, ethOrders, addr1], [ether('-100'), '0', ether('100')]); + await expect(fillTx2).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.1'), ether('-0.1'), '0']); - orderMakerBalance = await contracts.ethOrders.ordersMakersBalances(orderHash); + orderMakerBalance = await ethOrders.ordersMakersBalances(orderHash); expect(orderMakerBalance.balance).to.equal(0); expect(orderMakerBalance.maker).to.equal(addr1.address); }); it('Partial fill -> cancel -> refund maker -> fail to fill', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, ethOrders }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: contracts.ethOrders.address, + maker: ethOrders.address, receiver: addr1.address, - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: contracts.ethOrders.address, + postInteraction: ethOrders.address, }, ); - const orderHash = await contracts.swap.hashOrder(order); + const orderHash = await swap.hashOrder(order); - const deposittx = contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); + const deposittx = ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); await expect(deposittx).to.changeEtherBalance(addr1, ether('-0.3')); - await expect(deposittx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('0.3')); + await expect(deposittx).to.changeTokenBalance(weth, ethOrders, ether('0.3')); - const signature = await signOrder(order, chainId, contracts.swap.address, addr1); + const signature = await signOrder(order, chainId, swap.address, addr1); /// Partial fill const fillTakerTraits = buildTakerTraits({ threshold: ether('0.2'), extension: order.extension, }); - const fillTx = contracts.swap.fillContractOrderArgs(order, signature, ether('200'), fillTakerTraits.traits, fillTakerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, contracts.ethOrders, addr1], [ether('-200'), '0', ether('200')]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, contracts.ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); + const fillTx = swap.fillContractOrderArgs(order, signature, ether('200'), fillTakerTraits.traits, fillTakerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, ethOrders, addr1], [ether('-200'), '0', ether('200')]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']); /// Cancel order - const canceltx = contracts.ethOrders.connect(addr1).cancelOrder(order.makerTraits, orderHash); - await expect(canceltx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('-0.1')); + const canceltx = ethOrders.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await expect(canceltx).to.changeTokenBalance(weth, ethOrders, ether('-0.1')); await expect(canceltx).to.changeEtherBalance(addr1, ether('0.1')); /// Remaining fill failure @@ -1054,109 +1072,109 @@ describe('LimitOrderProtocol', function () { threshold: ether('0.1'), extension: order.extension, }); - await expect(contracts.swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(contracts.swap, 'InvalidatedOrder'); + await expect(swap.fillContractOrderArgs(order, signature, ether('100'), takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(swap, 'InvalidatedOrder'); }); it('Invalid order (missing post-interaction)', async function () { - const { tokens, contracts } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { ethOrders } } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - maker: contracts.ethOrders.address, + maker: ethOrders.address, receiver: addr1.address, - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }); - await expect(contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') })) - .to.be.revertedWithCustomError(contracts.ethOrders, 'InvalidOrder'); + await expect(ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') })) + .to.be.revertedWithCustomError(ethOrders, 'InvalidOrder'); }); it('Invalid extension (empty extension)', async function () { - const { tokens, contracts, orderLibFactory } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { ethOrders }, orderLibFactory } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: contracts.ethOrders.address, + maker: ethOrders.address, receiver: addr1.address, - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: contracts.ethOrders.address, + postInteraction: ethOrders.address, }, ); - await expect(contracts.ethOrders.connect(addr1).ethOrderDeposit(order, [], { value: ether('0.3') })) + await expect(ethOrders.connect(addr1).ethOrderDeposit(order, [], { value: ether('0.3') })) .to.be.revertedWithCustomError(orderLibFactory, 'MissingOrderExtension'); }); it('Invalid extension (mismatched extension)', async function () { - const { tokens, contracts, orderLibFactory } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { ethOrders }, orderLibFactory } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: contracts.ethOrders.address, + maker: ethOrders.address, receiver: addr1.address, - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: contracts.ethOrders.address, + postInteraction: ethOrders.address, }, ); - await expect(contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension.slice(0, -6), { value: ether('0.3') })) + await expect(ethOrders.connect(addr1).ethOrderDeposit(order, order.extension.slice(0, -6), { value: ether('0.3') })) .to.be.revertedWithCustomError(orderLibFactory, 'InvalidExtensionHash'); }); it('Invalid signature', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { ethOrders, swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - maker: contracts.ethOrders.address, + maker: ethOrders.address, receiver: addr1.address, - makerAsset: tokens.weth.address, - takerAsset: tokens.dai.address, + makerAsset: weth.address, + takerAsset: dai.address, makingAmount: ether('0.3'), takingAmount: ether('300'), }, { - postInteraction: contracts.ethOrders.address, + postInteraction: ethOrders.address, }, ); - const orderHash = await contracts.swap.hashOrder(order); + const orderHash = await swap.hashOrder(order); - const deposittx = contracts.ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); + const deposittx = ethOrders.connect(addr1).ethOrderDeposit(order, order.extension, { value: ether('0.3') }); await expect(deposittx).to.changeEtherBalance(addr1, ether('-0.3')); - await expect(deposittx).to.changeTokenBalance(tokens.weth, contracts.ethOrders, ether('0.3')); + await expect(deposittx).to.changeTokenBalance(weth, ethOrders, ether('0.3')); - let orderMakerBalance = await contracts.ethOrders.ordersMakersBalances(orderHash); + let orderMakerBalance = await ethOrders.ordersMakersBalances(orderHash); expect(orderMakerBalance.balance).to.equal(ether('0.3')); expect(orderMakerBalance.maker).to.equal(addr1.address); - const ethOrdersBatch = await contracts.ethOrders.ethOrdersBatch([orderHash]); + const ethOrdersBatch = await ethOrders.ethOrdersBatch([orderHash]); expect(ethOrdersBatch[0].balance).to.equal(ether('0.3')); expect(ethOrdersBatch[0].maker).to.equal(addr1.address); - const signature = await signOrder(order, chainId, contracts.swap.address, addr); + const signature = await signOrder(order, chainId, swap.address, addr); const takerTraits1 = buildTakerTraits({ threshold: ether('0.2'), extension: order.extension, }); await expect( - contracts.swap.fillContractOrderArgs(order, signature, ether('200'), takerTraits1.traits, takerTraits1.args), - ).to.be.revertedWithCustomError(contracts.swap, 'BadSignature'); + swap.fillContractOrderArgs(order, signature, ether('200'), takerTraits1.traits, takerTraits1.args), + ).to.be.revertedWithCustomError(swap, 'BadSignature'); - orderMakerBalance = await contracts.ethOrders.ordersMakersBalances(orderHash); + orderMakerBalance = await ethOrders.ordersMakersBalances(orderHash); expect(orderMakerBalance.balance).to.equal(ether('0.3')); expect(orderMakerBalance.maker).to.equal(addr1.address); }); @@ -1177,44 +1195,44 @@ describe('LimitOrderProtocol', function () { }; it('should revert for new order', async function () { - const { contracts, chainId, order } = await loadFixture(orderCancelationInit); - const data = buildOrderData(chainId, contracts.swap.address, order); + const { contracts: { swap }, chainId, order } = await loadFixture(orderCancelationInit); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await expect(contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.be.revertedWithCustomError(contracts.swap, 'RemainingInvalidatedOrder'); + await expect(swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.be.revertedWithCustomError(swap, 'RemainingInvalidatedOrder'); }); it('should return correct remaining for partially filled order', async function () { - const { contracts, chainId, order } = await loadFixture(orderCancelationInit); - const signature = await signOrder(order, chainId, contracts.swap.address, addr1); + const { contracts: { swap }, chainId, order } = await loadFixture(orderCancelationInit); + const signature = await signOrder(order, chainId, swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, contracts.swap.address, order); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('1'); + expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('1'); }); it('should return zero remaining for filled order', async function () { - const { contracts, chainId, order } = await loadFixture(orderCancelationInit); - const signature = await signOrder(order, chainId, contracts.swap.address, addr1); + const { contracts: { swap }, chainId, order } = await loadFixture(orderCancelationInit); + const signature = await signOrder(order, chainId, swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, contracts.swap.address, order); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2)); + await swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2)); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); + expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); }); it('should return zero remaining for cancelled order', async function () { - const { contracts, chainId, order } = await loadFixture(orderCancelationInit); - const data = buildOrderData(chainId, contracts.swap.address, order); + const { contracts: { swap }, chainId, order } = await loadFixture(orderCancelationInit); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); + expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); }); }); @@ -1247,75 +1265,75 @@ describe('LimitOrderProtocol', function () { // TODO: it could be canceled with another makerTraits, 1n << ALLOW_MUTIPLE_FILLS_FLAG (254n) for example it('should cancel own order', async function () { - const { contracts, chainId, order } = await loadFixture(orderCancelationInit); - const data = buildOrderData(chainId, contracts.swap.address, order); + const { contracts: { swap }, chainId, order } = await loadFixture(orderCancelationInit); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0'); }); it('should cancel own order with massInvalidate', async function () { - const { tokens, contracts, chainId } = await loadFixture(orderCancelationInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const orderNonce = 0; const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }), }); - const data = buildOrderData(chainId, contracts.swap.address, order); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - const invalidator = await contracts.swap.bitInvalidatorForOrder(addr1.address, orderNonce); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + const invalidator = await swap.bitInvalidatorForOrder(addr1.address, orderNonce); expect(invalidator).to.equal('1'); }); it('should cancel own order with massInvalidate, huge nonce', async function () { - const { tokens, contracts, chainId } = await loadFixture(orderCancelationInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const orderNonce = 1023; const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }), }); - const data = buildOrderData(chainId, contracts.swap.address, order); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - const invalidator = await contracts.swap.bitInvalidatorForOrder(addr1.address, orderNonce); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + const invalidator = await swap.bitInvalidatorForOrder(addr1.address, orderNonce); expect(invalidator).to.equal(1n << 255n); }); it('should cancel any hash', async function () { - const { contracts, order } = await loadFixture(orderCancelationInit); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, '0x0000000000000000000000000000000000000000000000000000000000000001'); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, '0x0000000000000000000000000000000000000000000000000000000000000001')).to.equal('0'); + const { contracts: { swap }, order } = await loadFixture(orderCancelationInit); + await swap.connect(addr1).cancelOrder(order.makerTraits, '0x0000000000000000000000000000000000000000000000000000000000000001'); + expect(await swap.remainingInvalidatorForOrder(addr1.address, '0x0000000000000000000000000000000000000000000000000000000000000001')).to.equal('0'); }); it('can simulate the failure of bitsInvalidateForOrder', async function () { - const { contracts, order } = await loadFixture(orderCancelationInit); + const { contracts: { swap }, order } = await loadFixture(orderCancelationInit); - const calldata = contracts.swap.interface.encodeFunctionData('bitsInvalidateForOrder', [ + const calldata = swap.interface.encodeFunctionData('bitsInvalidateForOrder', [ order.makerTraits, 0, ]); - const cancelationSimulate = contracts.swap.simulate(contracts.swap.address, calldata); + const cancelationSimulate = swap.simulate(swap.address, calldata); await expect(cancelationSimulate) - .to.be.revertedWithCustomError(contracts.swap, 'SimulationResults') - .withArgs(false, contracts.swap.interface.getSighash('OrderIsNotSuitableForMassInvalidation')); + .to.be.revertedWithCustomError(swap, 'SimulationResults') + .withArgs(false, swap.interface.getSighash('OrderIsNotSuitableForMassInvalidation')); }); it('should cancel several orders by hash', async function () { - const { contracts, order } = await loadFixture(orderCancelationInit); + const { contracts: { swap }, order } = await loadFixture(orderCancelationInit); const firstOrder = order; const secondOrder = order; @@ -1323,170 +1341,170 @@ describe('LimitOrderProtocol', function () { const firstOrderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000001'; const secondOrderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000002'; - await contracts.swap.connect(addr1).cancelOrders( + await swap.connect(addr1).cancelOrders( [firstOrder.makerTraits, secondOrder.makerTraits], [firstOrderFakeHash, secondOrderFakeHash], ); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, firstOrderFakeHash)).to.equal('0'); - expect(await contracts.swap.remainingInvalidatorForOrder(addr1.address, secondOrderFakeHash)).to.equal('0'); + expect(await swap.remainingInvalidatorForOrder(addr1.address, firstOrderFakeHash)).to.equal('0'); + expect(await swap.remainingInvalidatorForOrder(addr1.address, secondOrderFakeHash)).to.equal('0'); }); it('should revert when cancel several orders by hash and mismathed number of traits', async function () { - const { contracts, order } = await loadFixture(orderCancelationInit); + const { contracts: { swap }, order } = await loadFixture(orderCancelationInit); const firstOrder = order; const firstOrderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000001'; const secondOrderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000002'; - await expect(contracts.swap.connect(addr1).cancelOrders( + await expect(swap.connect(addr1).cancelOrders( [firstOrder.makerTraits], [firstOrderFakeHash, secondOrderFakeHash], - )).to.be.revertedWithCustomError(contracts.swap, 'MismatchArraysLengths'); + )).to.be.revertedWithCustomError(swap, 'MismatchArraysLengths'); }); it('rawRemainingInvalidatorForOrder returns method works', async function () { - const { contracts, order } = await loadFixture(orderCancelationInit); + const { contracts: { swap }, order } = await loadFixture(orderCancelationInit); const orderFakeHash = '0x0000000000000000000000000000000000000000000000000000000000000001'; - expect(await contracts.swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal('0'); + expect(await swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal('0'); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderFakeHash); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderFakeHash); const minusOne = '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - expect(await contracts.swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal(minusOne); + expect(await swap.rawRemainingInvalidatorForOrder(addr1.address, orderFakeHash)).to.equal(minusOne); }); it('should not fill cancelled order', async function () { - const { contracts, chainId, order } = await loadFixture(orderCancelationInit); - const signature = await signOrder(order, chainId, contracts.swap.address, addr1); + const { contracts: { swap }, chainId, order } = await loadFixture(orderCancelationInit); + const signature = await signOrder(order, chainId, swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, contracts.swap.address, order); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'InvalidatedOrder'); + await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'InvalidatedOrder'); }); it('should not fill cancelled order, massInvalidate', async function () { - const { tokens, contracts, chainId } = await loadFixture(orderCancelationInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(orderCancelationInit); const orderNonce = 0; const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }), }); - const signature = await signOrder(order, chainId, contracts.swap.address, addr1); + const signature = await signOrder(order, chainId, swap.address, addr1); const { r, _vs: vs } = ethers.utils.splitSignature(signature); - const data = buildOrderData(chainId, contracts.swap.address, order); + const data = buildOrderData(chainId, swap.address, order); const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value); - await contracts.swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); + await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash); - await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'BitInvalidatedOrder'); + await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'BitInvalidatedOrder'); }); it('epoch change, order should fail', async function () { - const { contracts, chainId, order } = await loadFixture(orderWithEpochInit); + const { contracts: { swap }, chainId, order } = await loadFixture(orderWithEpochInit); - await contracts.swap.connect(addr1).increaseEpoch(1); + await swap.connect(addr1).increaseEpoch(1); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2))) - .to.be.revertedWithCustomError(contracts.swap, 'WrongSeriesNonce'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 2, fillWithMakingAmount(2))) + .to.be.revertedWithCustomError(swap, 'WrongSeriesNonce'); }); it('epoch change should not affect other addresses', async function () { - const { tokens, contracts, chainId, order } = await loadFixture(orderWithEpochInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId, order } = await loadFixture(orderWithEpochInit); - await contracts.swap.connect(addr2).increaseEpoch(1); + await swap.connect(addr2).increaseEpoch(1); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('epoch change, partially filled order should fail', async function () { - const { tokens, contracts, chainId, order } = await loadFixture(orderWithEpochInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId, order } = await loadFixture(orderWithEpochInit); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); - await contracts.swap.connect(addr1).increaseEpoch(1); + await swap.connect(addr1).increaseEpoch(1); - await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'WrongSeriesNonce'); + await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'WrongSeriesNonce'); }); it('advance nonce', async function () { - const { contracts } = await loadFixture(deployContractsAndInit); - await contracts.swap.increaseEpoch(0); - expect(await contracts.swap.epoch(addr.address, 0)).to.equal('1'); + const { contracts: { swap } } = await loadFixture(deployContractsAndInit); + await swap.increaseEpoch(0); + expect(await swap.epoch(addr.address, 0)).to.equal('1'); }); }); describe('Private Orders', function () { it('should fill with correct taker', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ allowedSender: addr.address }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('should not fill with incorrect taker', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ allowedSender: addr1.address }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'PrivateOrder'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'PrivateOrder'); }); }); describe('Predicate', function () { it('arbitrary call predicate should pass', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = contracts.swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); + const predicate = swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1496,29 +1514,29 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension, }); - const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('arbitrary call predicate should fail', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = contracts.swap.interface.encodeFunctionData('gt', [10, arbitraryCall]); + const predicate = swap.interface.encodeFunctionData('gt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1528,32 +1546,32 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension, }); - await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(contracts.swap, 'PredicateIsNotTrue'); + await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(swap, 'PredicateIsNotTrue'); }); it('`or` should pass', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = contracts.swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); - const comparegt = contracts.swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); + const comparelt = swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); + const comparegt = swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = contracts.swap.interface.encodeFunctionData('or', [offsets, data]); + const predicate = swap.interface.encodeFunctionData('or', [offsets, data]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1563,33 +1581,33 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension, }); - const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('`or` should fail', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = contracts.swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); - const comparegt = contracts.swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); + const comparelt = swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); + const comparegt = swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = contracts.swap.interface.encodeFunctionData('or', [offsets, data]); + const predicate = swap.interface.encodeFunctionData('or', [offsets, data]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1599,32 +1617,32 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension, }); - await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(contracts.swap, 'PredicateIsNotTrue'); + await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(swap, 'PredicateIsNotTrue'); }); it('`and` should pass', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = contracts.swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); - const comparegt = contracts.swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); + const comparelt = swap.interface.encodeFunctionData('lt', [15, arbitraryCallPredicate]); + const comparegt = swap.interface.encodeFunctionData('gt', [5, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = contracts.swap.interface.encodeFunctionData('and', [offsets, data]); + const predicate = swap.interface.encodeFunctionData('and', [offsets, data]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1634,33 +1652,33 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension, }); - const fillTx = contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const fillTx = swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('`and` should fail', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId } = await loadFixture(deployContractsAndInit); - const arbitraryCallPredicate = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), + const arbitraryCallPredicate = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [10]), ]); - const comparelt = contracts.swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); - const comparegt = contracts.swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); + const comparelt = swap.interface.encodeFunctionData('lt', [5, arbitraryCallPredicate]); + const comparegt = swap.interface.encodeFunctionData('gt', [15, arbitraryCallPredicate]); const { offsets, data } = joinStaticCalls([comparelt, comparegt]); - const predicate = contracts.swap.interface.encodeFunctionData('and', [offsets, data]); + const predicate = swap.interface.encodeFunctionData('and', [offsets, data]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1670,28 +1688,30 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension, }); - await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) - .to.be.revertedWithCustomError(contracts.swap, 'PredicateIsNotTrue'); + await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + .to.be.revertedWithCustomError(swap, 'PredicateIsNotTrue'); }); it('should fail with invalid extension (empty extension)', async function () { - const { tokens, contracts, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); + const { + tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId, orderLibFactory, + } = await loadFixture(deployContractsAndInit); - const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = contracts.swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); + const predicate = swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1701,27 +1721,29 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, }); - await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) .to.be.revertedWithCustomError(orderLibFactory, 'MissingOrderExtension'); }); it('should fail with invalid extension (mismatched extension)', async function () { - const { tokens, contracts, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); + const { + tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId, orderLibFactory + } = await loadFixture(deployContractsAndInit); - const arbitraryCall = contracts.swap.interface.encodeFunctionData('arbitraryStaticCall', [ - contracts.arbitraryPredicate.address, - contracts.arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), + const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ + arbitraryPredicate.address, + arbitraryPredicate.interface.encodeFunctionData('copyArg', [1]), ]); - const predicate = contracts.swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); + const predicate = swap.interface.encodeFunctionData('lt', [10, arbitraryCall]); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, @@ -1731,208 +1753,208 @@ describe('LimitOrderProtocol', function () { }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: order.extension + '0011223344', }); - await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) .to.be.revertedWithCustomError(orderLibFactory, 'InvalidExtensionHash'); }); it('should fail with invalid extension (unexpected extension)', async function () { - const { tokens, contracts, orderLibFactory, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId, orderLibFactory } = await loadFixture(deployContractsAndInit); const order = buildOrder( { - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, }, ); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); const takerTraits = buildTakerTraits({ threshold: 1n, extension: '0xabacabac', }); - await expect(contracts.swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) + await expect(swap.fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)) .to.be.revertedWithCustomError(orderLibFactory, 'UnexpectedOrderExtension'); }); }); describe('Expiration', function () { it('should fill when not expired', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: (await time.latest()) + 3600 }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, fillWithMakingAmount(1), 1); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, fillWithMakingAmount(1), 1); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('should not fill when expired', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 1, takingAmount: 1, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: 0xff0000n }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'OrderExpired'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'OrderExpired'); }); it('should not partially fill when expired', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: await time.latest() }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'OrderExpired'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 4, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'OrderExpired'); }); it('should not fill partially filled order after expiration', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 10, takingAmount: 2, maker: addr1.address, makerTraits: buildMakerTraits({ expiry: await time.latest() + 1800 }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [1, -1]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-1, 1]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); await time.increase(3600); - await expect(contracts.swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) - .to.be.revertedWithCustomError(contracts.swap, 'OrderExpired'); + await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1))) + .to.be.revertedWithCustomError(swap, 'OrderExpired'); }); it('should fill partially if not enough coins (taker)', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 3, 2); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [2, -2]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-2, 2]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 3, 2); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [2, -2]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-2, 2]); }); it('should fill partially if not enough coins (maker)', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 2, takingAmount: 2, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 3, fillWithMakingAmount(3)); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [2, -2]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [-2, 2]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 3, fillWithMakingAmount(3)); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [2, -2]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-2, 2]); }); }); describe('ETH fill', function () { it('should fill with ETH', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 3 }); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [900, -900]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [0, 3]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 3 }); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [900, -900]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [0, 3]); await expect(fillTx).to.changeEtherBalance(addr, -3); }); it('should revert with takerAsset WETH and not enough msg.value', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 2 })) - .to.be.revertedWithCustomError(contracts.swap, 'InvalidMsgValue'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 2 })) + .to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); }); it('should pass with takerAsset WETH and correct msg.value', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [900, -900]); - await expect(fillTx).to.changeTokenBalances(tokens.weth, [addr, addr1], [0, 3]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [900, -900]); + await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [0, 3]); await expect(fillTx).to.changeEtherBalance(addr, -3); }); it('should pass with takerAsset WETH and correct msg.value and unwrap flag is set', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, @@ -1941,63 +1963,63 @@ describe('LimitOrderProtocol', function () { }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - const fillTx = contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); - await expect(fillTx).to.changeTokenBalances(tokens.dai, [addr, addr1], [900, -900]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + const fillTx = swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }); + await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [900, -900]); await expect(fillTx).to.changeEtherBalance(addr, -3); await expect(fillTx).to.changeEtherBalance(addr1, 3); }); it('should revert with takerAsset WETH, unwrap flag is set and receiver unable to receive ETH', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, makerTraits: buildMakerTraits({ unwrapWeth: true, }), - receiver: contracts.swap.address, + receiver: swap.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); await expect( - contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }, - )).to.be.revertedWithCustomError(contracts.swap, 'ETHTransferFailed'); + swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }, + )).to.be.revertedWithCustomError(swap, 'ETHTransferFailed'); }); it('should be reverted with takerAsset non-WETH and msg.value greater than 0', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, usdc }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); - await tokens.usdc.mint(addr.address, '1000000'); - await tokens.usdc.approve(contracts.swap.address, '1000000'); + await usdc.mint(addr.address, '1000000'); + await usdc.approve(swap.address, '1000000'); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.usdc.address, + makerAsset: dai.address, + takerAsset: usdc.address, makingAmount: 900, takingAmount: 900, maker: addr1.address, }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); - await expect(contracts.swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(900), { value: 1 })) - .to.be.revertedWithCustomError(contracts.swap, 'InvalidMsgValue'); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); + await expect(swap.fillOrder(order, r, vs, 900, fillWithMakingAmount(900), { value: 1 })) + .to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); }); it('should revert with takerAsset WETH, unwrap flag is set and taker unable to receive excessive ETH', async function () { - const { tokens, contracts, chainId } = await loadFixture(deployContractsAndInit); + const { tokens: { dai, weth }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const TakerContract = await ethers.getContractFactory('TakerContract'); - const taker = await TakerContract.deploy(contracts.swap.address); + const taker = await TakerContract.deploy(swap.address); await taker.deployed(); const order = buildOrder({ - makerAsset: tokens.dai.address, - takerAsset: tokens.weth.address, + makerAsset: dai.address, + takerAsset: weth.address, makingAmount: 900, takingAmount: 3, maker: addr1.address, @@ -2006,10 +2028,10 @@ describe('LimitOrderProtocol', function () { }), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, contracts.swap.address, addr1)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, addr1)); await expect( taker.fillOrder(order, r, vs, 900, fillWithMakingAmount(3), { value: 4 }, - )).to.be.revertedWithCustomError(contracts.swap, 'ETHTransferFailed'); + )).to.be.revertedWithCustomError(swap, 'ETHTransferFailed'); }); }); }); From 469c68212d6edd58d8b82e0703c2d327f3a4f1b5 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 15 Dec 2023 14:55:36 +0400 Subject: [PATCH 4/5] simplify --- test/LimitOrderProtocol.js | 96 ++++++++++++++------------------------ 1 file changed, 36 insertions(+), 60 deletions(-) diff --git a/test/LimitOrderProtocol.js b/test/LimitOrderProtocol.js index b30abfde..aab9bc3f 100644 --- a/test/LimitOrderProtocol.js +++ b/test/LimitOrderProtocol.js @@ -520,7 +520,7 @@ describe('LimitOrderProtocol', function () { it('DAI => WETH, no allowance', async function () { const { - tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: { order, signature: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'); @@ -535,9 +535,7 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ]), + swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -545,7 +543,7 @@ describe('LimitOrderProtocol', function () { it('skips expired permit if allowance is enough', async function () { const { - tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: { order, signature: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const deadline = (await time.latest()) - time.duration.weeks(1); @@ -558,9 +556,7 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ]), + swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -568,7 +564,7 @@ describe('LimitOrderProtocol', function () { it('rejects expired permit when allowance is not enough', async function () { const { - tokens: { weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + tokens: { weth }, contracts: { swap }, chainId, permits: { taker: { order, signature: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const deadline = (await time.latest()) - time.duration.weeks(1); @@ -581,9 +577,7 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ]), + swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), )).to.be.revertedWithCustomError(swap, 'TransferFromTakerToMakerFailed'); }); }); @@ -596,25 +590,23 @@ describe('LimitOrderProtocol', function () { it('Maker permit works, no allowance', async function () { const { - tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, + tokens: { dai, weth }, contracts: { swap }, permits: { maker: { order, signature: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: orderData.order.extension, + extension: order.extension, }); await weth.approve(swap.address, '0'); - const fillTx = swap.connect(addr1).fillOrderArgs( - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ); + const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('skips expired permit if allowance is enough', async function () { const { - tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, deadline, + tokens: { dai, weth }, contracts: { swap }, permits: { maker: { order, signature: { r, vs } } }, deadline, } = await loadFixture(deployContractsAndInit); await time.increaseTo(deadline + 1); @@ -622,18 +614,16 @@ describe('LimitOrderProtocol', function () { const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: orderData.order.extension, + extension: order.extension, }); - const fillTx = swap.connect(addr1).fillOrderArgs( - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ); + const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('rejects expired permit when allowance is not enough', async function () { const { - tokens: { weth }, contracts: { swap }, permits: { maker: orderData }, deadline, + tokens: { weth }, contracts: { swap }, permits: { maker: { order, signature: { r, vs } } }, deadline, } = await loadFixture(deployContractsAndInit); await weth.approve(swap.address, '0'); @@ -642,28 +632,24 @@ describe('LimitOrderProtocol', function () { const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: orderData.order.extension, + extension: order.extension, }); - await expect(swap.connect(addr1).fillOrderArgs( - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - )).to.be.revertedWithCustomError(swap, 'TransferFromMakerToTakerFailed'); + await expect(swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)).to.be.revertedWithCustomError(swap, 'TransferFromMakerToTakerFailed'); }); it('skips order permit flag', async function () { const { - tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, + tokens: { dai, weth }, contracts: { swap }, permits: { maker: { order, signature: { r, vs }, permit } }, } = await loadFixture(deployContractsAndInit); await weth.approve(swap.address, '0'); - await addr1.sendTransaction({ to: weth.address, data: '0xd505accf' + orderData.permit.substring(42) }); + await addr1.sendTransaction({ to: weth.address, data: '0xd505accf' + permit.substring(42) }); const takerTraits = buildTakerTraits({ threshold: 0n, skipMakerPermit: true, - extension: orderData.order.extension, + extension: order.extension, }); - const fillTx = swap.connect(addr1).fillOrderArgs( - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ); + const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); @@ -678,7 +664,7 @@ describe('LimitOrderProtocol', function () { // bad permit | + | + | it('DAI => WETH, no allowance', async function () { const { - tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + tokens: { dai, weth }, contracts: { swap }, chainId, permits: { taker: { order, signature: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); @@ -694,9 +680,7 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ]), + swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -704,7 +688,7 @@ describe('LimitOrderProtocol', function () { it('Skips expired permit if allowance is enough', async function () { const { - tokens: { dai, weth }, contracts: { swap, permit2Contract }, chainId, permits: { taker: orderData }, deadline, + tokens: { dai, weth }, contracts: { swap, permit2Contract }, chainId, permits: { taker: { order, signature: { r, vs } } }, deadline, } = await loadFixture(deployContractsAndInit); const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); @@ -730,9 +714,7 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permitExpired], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ]), + swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -740,7 +722,7 @@ describe('LimitOrderProtocol', function () { it('Fails with expired permit if allowance is not enough', async function () { const { - tokens: { weth }, contracts: { swap }, chainId, permits: { taker: orderData }, + tokens: { weth }, contracts: { swap }, chainId, permits: { taker: { order, signature: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const deadline = BigNumber.from((await time.latest()) - time.duration.weeks(1)); @@ -756,16 +738,12 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [ - orderData.order, orderData.signature.r, orderData.signature.vs, 1, takerTraits.traits, takerTraits.args, - ]), + swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), )).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); }); it('Fails with unexpected takerAssetSuffix', async function () { - const { - tokens: { weth, dai }, contracts: { swap }, chainId, - } = await loadFixture(deployContractsAndInit); + const { tokens: { weth, dai }, contracts: { swap }, chainId } = await loadFixture(deployContractsAndInit); const order = buildOrder( { @@ -809,22 +787,22 @@ describe('LimitOrderProtocol', function () { // bad permit | + | + | it('Maker permit works', async function () { const { - tokens: { dai, weth }, contracts: { swap }, permits: { maker: orderData }, + tokens: { dai, weth }, contracts: { swap }, permits: { maker: { orderPermit2: order, signaturePermit2: { r, vs } } }, } = await loadFixture(deployContractsAndInit); const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: orderData.orderPermit2.extension, + extension: order.extension, }); - const fillTx = swap.connect(addr1).fillOrderArgs(orderData.orderPermit2, orderData.signaturePermit2.r, orderData.signaturePermit2.vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('Skips expired permit if allowance is enough', async function () { const { - tokens: { dai, weth }, contracts: { swap, permit2Contract }, chainId, permits: { maker: orderData }, deadline, + tokens: { dai, weth }, contracts: { swap, permit2Contract }, chainId, permits: { maker: { orderPermit2: order, signaturePermit2: { r, vs } } }, deadline, } = await loadFixture(deployContractsAndInit); const permit = await getPermit2(addr, weth.address, chainId, swap.address, 1); @@ -843,16 +821,16 @@ describe('LimitOrderProtocol', function () { const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: orderData.orderPermit2.extension, + extension: order.extension, }); - const fillTx = swap.connect(addr1).fillOrderArgs(orderData.orderPermit2, orderData.signaturePermit2.r, orderData.signaturePermit2.vs, 1, takerTraits.traits, takerTraits.args); + const fillTx = swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); }); it('Fails with expired permit if allowance is not enough', async function () { const { - contracts: { swap }, permits: { maker: orderData }, deadline, + contracts: { swap }, permits: { maker: { orderPermit2: order, signaturePermit2: { r, vs } } }, deadline, } = await loadFixture(deployContractsAndInit); await time.increaseTo(deadline + 1); @@ -860,11 +838,9 @@ describe('LimitOrderProtocol', function () { const takerTraits = buildTakerTraits({ threshold: 1n, makingAmount: true, - extension: orderData.orderPermit2.extension, + extension: order.extension, }); - await expect(swap.connect(addr1).fillOrderArgs( - orderData.orderPermit2, orderData.signaturePermit2.r, orderData.signaturePermit2.vs, 1, takerTraits.traits, takerTraits.args, - )).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); + await expect(swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); }); it('Fails with unexpected makerAssetSuffix', async function () { @@ -1731,7 +1707,7 @@ describe('LimitOrderProtocol', function () { it('should fail with invalid extension (mismatched extension)', async function () { const { - tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId, orderLibFactory + tokens: { dai, weth }, contracts: { swap, arbitraryPredicate }, chainId, orderLibFactory, } = await loadFixture(deployContractsAndInit); const arbitraryCall = swap.interface.encodeFunctionData('arbitraryStaticCall', [ From a85519f646dc73545307b77dc65f25ae0399130a Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 15 Dec 2023 15:00:31 +0400 Subject: [PATCH 5/5] style --- test/LimitOrderProtocol.js | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/test/LimitOrderProtocol.js b/test/LimitOrderProtocol.js index aab9bc3f..f0236dc0 100644 --- a/test/LimitOrderProtocol.js +++ b/test/LimitOrderProtocol.js @@ -535,7 +535,9 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), + swap.interface.encodeFunctionData('fillOrderArgs', [ + order, r, vs, 1, takerTraits.traits, takerTraits.args, + ]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -556,7 +558,9 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), + swap.interface.encodeFunctionData('fillOrderArgs', [ + order, r, vs, 1, takerTraits.traits, takerTraits.args, + ]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -577,7 +581,9 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), + swap.interface.encodeFunctionData('fillOrderArgs', [ + order, r, vs, 1, takerTraits.traits, takerTraits.args, + ]), )).to.be.revertedWithCustomError(swap, 'TransferFromTakerToMakerFailed'); }); }); @@ -634,7 +640,9 @@ describe('LimitOrderProtocol', function () { makingAmount: true, extension: order.extension, }); - await expect(swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)).to.be.revertedWithCustomError(swap, 'TransferFromMakerToTakerFailed'); + await expect(swap.connect(addr1).fillOrderArgs( + order, r, vs, 1, takerTraits.traits, takerTraits.args, + )).to.be.revertedWithCustomError(swap, 'TransferFromMakerToTakerFailed'); }); it('skips order permit flag', async function () { @@ -680,7 +688,9 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), + swap.interface.encodeFunctionData('fillOrderArgs', [ + order, r, vs, 1, takerTraits.traits, takerTraits.args, + ]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -714,7 +724,9 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permitExpired], ), - swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), + swap.interface.encodeFunctionData('fillOrderArgs', [ + order, r, vs, 1, takerTraits.traits, takerTraits.args, + ]), ); await expect(fillTx).to.changeTokenBalances(dai, [addr, addr1], [1, -1]); await expect(fillTx).to.changeTokenBalances(weth, [addr, addr1], [-1, 1]); @@ -738,7 +750,9 @@ describe('LimitOrderProtocol', function () { ['address', 'bytes'], [weth.address, permit], ), - swap.interface.encodeFunctionData('fillOrderArgs', [order, r, vs, 1, takerTraits.traits, takerTraits.args]), + swap.interface.encodeFunctionData('fillOrderArgs', [ + order, r, vs, 1, takerTraits.traits, takerTraits.args, + ]), )).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); }); @@ -840,7 +854,9 @@ describe('LimitOrderProtocol', function () { makingAmount: true, extension: order.extension, }); - await expect(swap.connect(addr1).fillOrderArgs(order, r, vs, 1, takerTraits.traits, takerTraits.args)).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); + await expect(swap.connect(addr1).fillOrderArgs( + order, r, vs, 1, takerTraits.traits, takerTraits.args, + )).to.be.revertedWithCustomError(swap, 'SafeTransferFromFailed'); }); it('Fails with unexpected makerAssetSuffix', async function () {