From 70863cca085c060d55932e5e173fc2023bda9df5 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 23 Aug 2018 10:31:06 -0700 Subject: Ran prettier and linter --- packages/contracts/test/exchange/match_orders.ts | 44 +- .../contracts/test/utils/match_order_tester.ts | 487 +++++++++++++-------- packages/contracts/test/utils/types.ts | 10 +- 3 files changed, 317 insertions(+), 224 deletions(-) (limited to 'packages') diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts index eb2644ba6..7e9776d52 100644 --- a/packages/contracts/test/exchange/match_orders.ts +++ b/packages/contracts/test/exchange/match_orders.ts @@ -3,7 +3,6 @@ import { assetDataUtils } from '@0xproject/order-utils'; import { RevertReason } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as chai from 'chai'; import * as _ from 'lodash'; import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; @@ -14,25 +13,15 @@ import { ExchangeContract } from '../../generated_contract_wrappers/exchange'; import { ReentrantERC20TokenContract } from '../../generated_contract_wrappers/reentrant_erc20_token'; import { artifacts } from '../utils/artifacts'; import { expectTransactionFailedAsync } from '../utils/assertions'; -import { chaiSetup } from '../utils/chai_setup'; import { constants } from '../utils/constants'; import { ERC20Wrapper } from '../utils/erc20_wrapper'; import { ERC721Wrapper } from '../utils/erc721_wrapper'; import { ExchangeWrapper } from '../utils/exchange_wrapper'; import { MatchOrderTester } from '../utils/match_order_tester'; import { OrderFactory } from '../utils/order_factory'; -import { - ERC20BalancesByOwner, - ERC721TokenIdsByOwner, - OrderInfo, - TransferAmountsByMatchOrders as TransferAmounts, - OrderStatus, -} from '../utils/types'; +import { ERC20BalancesByOwner, ERC721TokenIdsByOwner } from '../utils/types'; import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper'; -chaiSetup.configure(); - -const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); describe.only('matchOrders', () => { @@ -470,7 +459,7 @@ describe.only('matchOrders', () => { takerAddress, erc20BalancesByOwner, erc721TokenIdsByOwner, - expectedTransferAmounts + expectedTransferAmounts, ); // Construct second right order // Note: This order needs makerAssetAmount=90/takerAssetAmount=[anything <= 45] to fully fill the right order. @@ -480,7 +469,6 @@ describe.only('matchOrders', () => { makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18), }); - // Match signedOrderLeft with signedOrderRight2 const leftTakerAssetFilledAmount = signedOrderRight.makerAssetAmount; const rightTakerAssetFilledAmount = new BigNumber(0); @@ -549,7 +537,7 @@ describe.only('matchOrders', () => { takerAddress, erc20BalancesByOwner, erc721TokenIdsByOwner, - expectedTransferAmounts + expectedTransferAmounts, ); // Create second left order @@ -592,32 +580,6 @@ describe.only('matchOrders', () => { ); }); - /* - // Match signedOrderLeft with signedOrderRight - const expectedTransferAmounts = { - // Left Maker - amountSoldByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 18), - amountBoughtByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 18), - feePaidByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 16), // 10% - // Right Maker - amountSoldByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 18), - amountBoughtByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 18), - feePaidByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 16), // 100% - // Taker - amountReceivedByTaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 18), - feePaidByTakerLeft: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 16), // 100% - feePaidByTakerRight: Web3Wrapper.toBaseUnitAmount(new BigNumber(), 16), // 50% - }; - await matchOrderTester.matchOrdersAndVerifyBalancesAsync( - signedOrderLeft, - signedOrderRight, - takerAddress, - erc20BalancesByOwner, - erc721TokenIdsByOwner, - expectedTransferAmounts - ); - - */ it('should transfer the correct amounts if fee recipient is the same across both matched orders', async () => { const feeRecipientAddress = feeRecipientAddressLeft; const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ diff --git a/packages/contracts/test/utils/match_order_tester.ts b/packages/contracts/test/utils/match_order_tester.ts index 00816e7d4..300073eb0 100644 --- a/packages/contracts/test/utils/match_order_tester.ts +++ b/packages/contracts/test/utils/match_order_tester.ts @@ -4,12 +4,19 @@ import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; +import { TransactionReceiptWithDecodedLogs } from '../../../../node_modules/ethereum-types'; + import { chaiSetup } from './chai_setup'; import { ERC20Wrapper } from './erc20_wrapper'; import { ERC721Wrapper } from './erc721_wrapper'; import { ExchangeWrapper } from './exchange_wrapper'; -import { ERC20BalancesByOwner, ERC721TokenIdsByOwner, TransferAmountsByMatchOrders as TransferAmounts, OrderInfo, OrderStatus} from './types'; -import { TransactionReceiptWithDecodedLogs } from '../../../../node_modules/ethereum-types'; +import { + ERC20BalancesByOwner, + ERC721TokenIdsByOwner, + OrderInfo, + OrderStatus, + TransferAmountsByMatchOrders as TransferAmounts, +} from './types'; chaiSetup.configure(); const expect = chai.expect; @@ -19,110 +26,117 @@ export class MatchOrderTester { private readonly _erc20Wrapper: ERC20Wrapper; private readonly _erc721Wrapper: ERC721Wrapper; private readonly _feeTokenAddress: string; - - private async _verifyBalancesAsync( + /// @dev Calculates expected transfer amounts between order makers, fee recipients, and + /// the taker when two orders are matched. + /// @param signedOrderLeft First matched order. + /// @param signedOrderRight Second matched order. + /// @param orderTakerAssetFilledAmountLeft How much left order has been filled, prior to matching orders. + /// @param orderTakerAssetFilledAmountRight How much the right order has been filled, prior to matching orders. + /// @return TransferAmounts A struct containing the expected transfer amounts. + private static async _verifyLogsAsync( signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder, - initialERC20BalancesByOwner: ERC20BalancesByOwner, - initialERC721TokenIdsByOwner: ERC721TokenIdsByOwner, - finalERC20BalancesByOwner: ERC20BalancesByOwner, - finalERC721TokenIdsByOwner: ERC721TokenIdsByOwner, + transactionReceipt: TransactionReceiptWithDecodedLogs, + takerAddress: string, expectedTransferAmounts: TransferAmounts, - takerAddress: string - ) - { - let expectedERC20BalancesByOwner: ERC20BalancesByOwner; - let expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner; - [expectedERC20BalancesByOwner, expectedERC721TokenIdsByOwner] = this._calculateExpectedBalances( - signedOrderLeft, - signedOrderRight, - takerAddress, - initialERC20BalancesByOwner, - initialERC721TokenIdsByOwner, - expectedTransferAmounts, - ); - // Verify balances of makers, taker, and fee recipients - await this._verifyMakerTakerAndFeeRecipientBalancesAsync( - signedOrderLeft, - signedOrderRight, - expectedERC20BalancesByOwner, - finalERC20BalancesByOwner, - expectedERC721TokenIdsByOwner, - finalERC721TokenIdsByOwner, - takerAddress + ): Promise { + // Parse logs + expect(transactionReceipt.logs.length, 'Checking number of logs').to.be.equal(2); + // First log is for left fill + const leftLog = (transactionReceipt.logs[0] as any) as { + args: { + makerAddress: string; + takerAddress: string; + makerAssetFilledAmount: string; + takerAssetFilledAmount: string; + makerFeePaid: string; + takerFeePaid: string; + }; + }; + expect(leftLog.args.makerAddress, 'Checking logged maker address of left order').to.be.equal( + signedOrderLeft.makerAddress, ); - // Verify balances for all known accounts - await this._verifyAllKnownBalancesAsync( - expectedERC20BalancesByOwner, - finalERC20BalancesByOwner, - expectedERC721TokenIdsByOwner, - finalERC721TokenIdsByOwner, + expect(leftLog.args.takerAddress, 'Checking logged taker address of right order').to.be.equal(takerAddress); + const amountBoughtByLeftMaker = new BigNumber(leftLog.args.takerAssetFilledAmount); + const amountSoldByLeftMaker = new BigNumber(leftLog.args.makerAssetFilledAmount); + const feePaidByLeftMaker = new BigNumber(leftLog.args.makerFeePaid); + const feePaidByTakerLeft = new BigNumber(leftLog.args.takerFeePaid); + // Second log is for right fill + const rightLog = (transactionReceipt.logs[1] as any) as { + args: { + makerAddress: string; + takerAddress: string; + makerAssetFilledAmount: string; + takerAssetFilledAmount: string; + makerFeePaid: string; + takerFeePaid: string; + }; + }; + expect(rightLog.args.makerAddress, 'Checking logged maker address of right order').to.be.equal( + signedOrderRight.makerAddress, ); + expect(rightLog.args.takerAddress, 'Checking loggerd taker address of right order').to.be.equal(takerAddress); + const amountBoughtByRightMaker = new BigNumber(rightLog.args.takerAssetFilledAmount); + const amountSoldByRightMaker = new BigNumber(rightLog.args.makerAssetFilledAmount); + const feePaidByRightMaker = new BigNumber(rightLog.args.makerFeePaid); + const feePaidByTakerRight = new BigNumber(rightLog.args.takerFeePaid); + // Derive amount received by taker + const amountReceivedByTaker = amountSoldByLeftMaker.sub(amountBoughtByRightMaker); + // Verify log values - left order + expect( + expectedTransferAmounts.amountBoughtByLeftMaker, + 'Checking logged amount bought by left maker', + ).to.be.bignumber.equal(amountBoughtByLeftMaker); + expect( + expectedTransferAmounts.amountSoldByLeftMaker, + 'Checking logged amount sold by left maker', + ).to.be.bignumber.equal(amountSoldByLeftMaker); + expect( + expectedTransferAmounts.feePaidByLeftMaker, + 'Checking logged fee paid by left maker', + ).to.be.bignumber.equal(feePaidByLeftMaker); + expect( + expectedTransferAmounts.feePaidByTakerLeft, + 'Checking logged fee paid on left order by taker', + ).to.be.bignumber.equal(feePaidByTakerLeft); + // Verify log values - right order + expect( + expectedTransferAmounts.amountBoughtByRightMaker, + 'Checking logged amount bought by right maker', + ).to.be.bignumber.equal(amountBoughtByRightMaker); + expect( + expectedTransferAmounts.amountSoldByRightMaker, + 'Checking logged amount sold by right maker', + ).to.be.bignumber.equal(amountSoldByRightMaker); + expect( + expectedTransferAmounts.feePaidByRightMaker, + 'Checking logged fee paid by right maker', + ).to.be.bignumber.equal(feePaidByRightMaker); + expect( + expectedTransferAmounts.feePaidByTakerRight, + 'Checking logged fee paid on right order by taker', + ).to.be.bignumber.equal(feePaidByTakerRight); + // Verify derived amount received by taker + expect( + expectedTransferAmounts.amountReceivedByTaker, + 'Checking logged amount received by taker', + ).to.be.bignumber.equal(amountReceivedByTaker); } - - private async _verifyMakerTakerAndFeeRecipientBalancesAsync( - signedOrderLeft: SignedOrder, - signedOrderRight: SignedOrder, - expectedERC20BalancesByOwner: ERC20BalancesByOwner, - realERC20BalancesByOwner: ERC20BalancesByOwner, - expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner, - realERC721TokenIdsByOwner: ERC721TokenIdsByOwner, - takerAddress: string - ) { - // Individual balance comparisons - const makerAssetProxyIdLeft = assetDataUtils.decodeAssetProxyId(signedOrderLeft.makerAssetData); - const makerERC20AssetDataLeft = makerAssetProxyIdLeft == AssetProxyId.ERC20 ? assetDataUtils.decodeERC20AssetData(signedOrderLeft.makerAssetData) : assetDataUtils.decodeERC721AssetData(signedOrderLeft.makerAssetData); - const makerAssetAddressLeft = makerERC20AssetDataLeft.tokenAddress; - const makerAssetProxyIdRight = assetDataUtils.decodeAssetProxyId(signedOrderRight.makerAssetData); - const makerERC20AssetDataRight = makerAssetProxyIdRight == AssetProxyId.ERC20 ? assetDataUtils.decodeERC20AssetData(signedOrderRight.makerAssetData) : assetDataUtils.decodeERC721AssetData(signedOrderRight.makerAssetData); - const makerAssetAddressRight = makerERC20AssetDataRight.tokenAddress; - // describe('asdad', () => { - if(makerAssetProxyIdLeft == AssetProxyId.ERC20) { - expect(realERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft], "Checking left maker egress ERC20 account balance").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft]); - expect(realERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft], "Checking right maker ingress ERC20 account balance").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft]); - expect(realERC20BalancesByOwner[takerAddress][makerAssetAddressLeft], "Checking taker ingress ERC20 account balance").to.be.bignumber.equal(expectedERC20BalancesByOwner[takerAddress][makerAssetAddressLeft]); - } else if(makerAssetProxyIdLeft == AssetProxyId.ERC721) { - expect(realERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft].sort(), "Checking left maker egress ERC721 account holdings").to.be.deep.equal(expectedERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft].sort()); - expect(realERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft].sort(), "Checking right maker ERC721 account holdings").to.be.deep.equal(expectedERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft].sort()); - expect(realERC721TokenIdsByOwner[takerAddress][makerAssetAddressLeft].sort(), "Checking taker ingress ERC721 account holdings").to.be.deep.equal(expectedERC721TokenIdsByOwner[takerAddress][makerAssetAddressLeft].sort()); - } else { - throw new Error(`Unhandled Asset Proxy ID: ${makerAssetProxyIdLeft}`); - } - if(makerAssetProxyIdRight == AssetProxyId.ERC20) { - expect(realERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight], "Checking left maker ingress ERC20 account balance").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight]); - expect(realERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressRight], "Checking right maker egress ERC20 account balance").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressRight]); - } else if(makerAssetProxyIdRight == AssetProxyId.ERC721) { - expect(realERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight].sort(), "Checking left maker ingress ERC721 account holdings").to.be.deep.equal(expectedERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight].sort()); - expect(realERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressRight], "Checking right maker agress ERC721 account holdings").to.be.deep.equal(expectedERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressRight]); - } else { - throw new Error(`Unhandled Asset Proxy ID: ${makerAssetProxyIdRight}`); - } - // Paid fees - expect(realERC20BalancesByOwner[signedOrderLeft.makerAddress][this._feeTokenAddress], "Checking left maker egress ERC20 account fees").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][this._feeTokenAddress]); - expect(realERC20BalancesByOwner[signedOrderRight.makerAddress][this._feeTokenAddress], "Checking right maker egress ERC20 account fees").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][this._feeTokenAddress]); - expect(realERC20BalancesByOwner[takerAddress][this._feeTokenAddress], "Checking taker egress ERC20 account fees").to.be.bignumber.equal(expectedERC20BalancesByOwner[takerAddress][this._feeTokenAddress]); - // Received fees - expect(realERC20BalancesByOwner[signedOrderLeft.feeRecipientAddress][this._feeTokenAddress], "Checking left fee recipient ingress ERC20 account fees").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.feeRecipientAddress][this._feeTokenAddress]); - expect(realERC20BalancesByOwner[signedOrderRight.feeRecipientAddress][this._feeTokenAddress], "Checking right fee receipient ingress ERC20 account fees").to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.feeRecipientAddress][this._feeTokenAddress]); - } - /// @dev Compares a pair of ERC20 balances and a pair of ERC721 token owners. /// @param expectedNewERC20BalancesByOwner Expected ERC20 balances. /// @param realERC20BalancesByOwner Actual ERC20 balances. /// @param expectedNewERC721TokenIdsByOwner Expected ERC721 token owners. /// @param realERC721TokenIdsByOwner Actual ERC20 token owners. /// @return True only if ERC20 balances match and ERC721 token owners match. - private async _verifyAllKnownBalancesAsync( + private static async _verifyAllKnownBalancesAsync( expectedNewERC20BalancesByOwner: ERC20BalancesByOwner, realERC20BalancesByOwner: ERC20BalancesByOwner, expectedNewERC721TokenIdsByOwner: ERC721TokenIdsByOwner, realERC721TokenIdsByOwner: ERC721TokenIdsByOwner, - ) { - + ): Promise { // ERC20 Balances - const erc20BalancesMatch = _.isEqual(expectedNewERC20BalancesByOwner, realERC20BalancesByOwner); - expect(erc20BalancesMatch, "Checking all known ERC20 account balances").to.be.true(); - + const areERC20BalancesEqual = _.isEqual(expectedNewERC20BalancesByOwner, realERC20BalancesByOwner); + expect(areERC20BalancesEqual, 'Checking all known ERC20 account balances').to.be.true(); // ERC721 Token Ids const sortedExpectedNewERC721TokenIdsByOwner = _.mapValues( expectedNewERC721TokenIdsByOwner, @@ -137,38 +151,12 @@ export class MatchOrderTester { _.sortBy(tokenIds); }); }); - const erc721TokenIdsMatch = _.isEqual( + const areERC721TokenIdsEqual = _.isEqual( sortedExpectedNewERC721TokenIdsByOwner, sortedNewERC721TokenIdsByOwner, ); - expect(erc721TokenIdsMatch, "Checking all known ERC721 account balances").to.be.true(); + expect(areERC721TokenIdsEqual, 'Checking all known ERC721 account balances').to.be.true(); } - - private async _verifyInitialOrderStates( - signedOrderLeft: SignedOrder, - signedOrderRight: SignedOrder, - initialTakerAssetFilledAmountLeft?: BigNumber, - initialTakerAssetFilledAmountRight?: BigNumber, - ): Promise<[BigNumber, BigNumber]> { - // Verify Left order preconditions - const orderTakerAssetFilledAmountLeft = await this._exchangeWrapper.getTakerAssetFilledAmountAsync( - orderHashUtils.getOrderHashHex(signedOrderLeft), - ); - const expectedOrderFilledAmountLeft = initialTakerAssetFilledAmountLeft - ? initialTakerAssetFilledAmountLeft - : new BigNumber(0); - expect(expectedOrderFilledAmountLeft).to.be.bignumber.equal(orderTakerAssetFilledAmountLeft); - // Verify Right order preconditions - const orderTakerAssetFilledAmountRight = await this._exchangeWrapper.getTakerAssetFilledAmountAsync( - orderHashUtils.getOrderHashHex(signedOrderRight), - ); - const expectedOrderFilledAmountRight = initialTakerAssetFilledAmountRight - ? initialTakerAssetFilledAmountRight - : new BigNumber(0); - expect(expectedOrderFilledAmountRight).to.be.bignumber.equal(orderTakerAssetFilledAmountRight); - return [orderTakerAssetFilledAmountLeft, orderTakerAssetFilledAmountRight]; - } - /// @dev Constructs new MatchOrderTester. /// @param exchangeWrapper Used to call to the Exchange. /// @param erc20Wrapper Used to fetch ERC20 balances. @@ -208,23 +196,27 @@ export class MatchOrderTester { // Verify initial order states let orderTakerAssetFilledAmountLeft: BigNumber; let orderTakerAssetFilledAmountRight: BigNumber; - [orderTakerAssetFilledAmountLeft, orderTakerAssetFilledAmountRight] = await this._verifyInitialOrderStates( + [orderTakerAssetFilledAmountLeft, orderTakerAssetFilledAmountRight] = await this._verifyInitialOrderStatesAsync( signedOrderLeft, signedOrderRight, initialTakerAssetFilledAmountLeft, - initialTakerAssetFilledAmountRight + initialTakerAssetFilledAmountRight, ); // Match left & right orders - const transactionReceipt = await this._exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress); + const transactionReceipt = await this._exchangeWrapper.matchOrdersAsync( + signedOrderLeft, + signedOrderRight, + takerAddress, + ); const newERC20BalancesByOwner = await this._erc20Wrapper.getBalancesAsync(); const newERC721TokenIdsByOwner = await this._erc721Wrapper.getBalancesAsync(); // Verify logs - await this._verifyLogsAsync( + await MatchOrderTester._verifyLogsAsync( signedOrderLeft, signedOrderRight, transactionReceipt, takerAddress, - expectedTransferAmounts + expectedTransferAmounts, ); // Verify exchange state await this._verifyExchangeStateAsync( @@ -234,7 +226,7 @@ export class MatchOrderTester { orderTakerAssetFilledAmountRight, expectedTransferAmounts, initialTakerAssetFilledAmountLeft, - initialTakerAssetFilledAmountRight + initialTakerAssetFilledAmountRight, ); // Verify balances of makers, taker, and fee recipients await this._verifyBalancesAsync( @@ -245,57 +237,35 @@ export class MatchOrderTester { newERC20BalancesByOwner, newERC721TokenIdsByOwner, expectedTransferAmounts, - takerAddress + takerAddress, ); return [newERC20BalancesByOwner, newERC721TokenIdsByOwner]; } - /// @dev Calculates expected transfer amounts between order makers, fee recipients, and - /// the taker when two orders are matched. - /// @param signedOrderLeft First matched order. - /// @param signedOrderRight Second matched order. - /// @param orderTakerAssetFilledAmountLeft How much left order has been filled, prior to matching orders. - /// @param orderTakerAssetFilledAmountRight How much the right order has been filled, prior to matching orders. - /// @return TransferAmounts A struct containing the expected transfer amounts. - private async _verifyLogsAsync( + private async _verifyInitialOrderStatesAsync( signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder, - transactionReceipt: TransactionReceiptWithDecodedLogs, - takerAddress: string, - expectedTransferAmounts: TransferAmounts - ) { - // Parse logs - expect(transactionReceipt.logs.length, "Checking number of logs").to.be.equal(2); - // First log is for left fill - const leftLog = ((transactionReceipt.logs[0] as any) as {args: { makerAddress: string, takerAddress: string, makerAssetFilledAmount: string, takerAssetFilledAmount: string, makerFeePaid: string, takerFeePaid: string}}); - expect(leftLog.args.makerAddress, "Checking logged maker address of left order").to.be.equal(signedOrderLeft.makerAddress); - expect(leftLog.args.takerAddress, "Checking logged taker address of right order").to.be.equal(takerAddress); - const amountBoughtByLeftMaker = new BigNumber(leftLog.args.takerAssetFilledAmount); - const amountSoldByLeftMaker = new BigNumber(leftLog.args.makerAssetFilledAmount); - const feePaidByLeftMaker = new BigNumber(leftLog.args.makerFeePaid); - const feePaidByTakerLeft = new BigNumber(leftLog.args.takerFeePaid); - // Second log is for right fill - const rightLog = ((transactionReceipt.logs[1] as any) as {args: { makerAddress: string, takerAddress: string, makerAssetFilledAmount: string, takerAssetFilledAmount: string, makerFeePaid: string, takerFeePaid: string}}); - expect(rightLog.args.makerAddress, "Checking logged maker address of right order").to.be.equal(signedOrderRight.makerAddress); - expect(rightLog.args.takerAddress, "Checking loggerd taker address of right order").to.be.equal(takerAddress); - const amountBoughtByRightMaker = new BigNumber(rightLog.args.takerAssetFilledAmount); - const amountSoldByRightMaker = new BigNumber(rightLog.args.makerAssetFilledAmount); - const feePaidByRightMaker = new BigNumber(rightLog.args.makerFeePaid); - const feePaidByTakerRight = new BigNumber(rightLog.args.takerFeePaid); - // Derive amount received by taker - const amountReceivedByTaker = amountSoldByLeftMaker.sub(amountBoughtByRightMaker); - // Verify log values - left order - expect(expectedTransferAmounts.amountBoughtByLeftMaker, "Checking logged amount bought by left maker").to.be.bignumber.equal(amountBoughtByLeftMaker); - expect(expectedTransferAmounts.amountSoldByLeftMaker, "Checking logged amount sold by left maker").to.be.bignumber.equal(amountSoldByLeftMaker); - expect(expectedTransferAmounts.feePaidByLeftMaker, "Checking logged fee paid by left maker").to.be.bignumber.equal(feePaidByLeftMaker); - expect(expectedTransferAmounts.feePaidByTakerLeft, "Checking logged fee paid on left order by taker").to.be.bignumber.equal(feePaidByTakerLeft); - // Verify log values - right order - expect(expectedTransferAmounts.amountBoughtByRightMaker, "Checking logged amount bought by right maker").to.be.bignumber.equal(amountBoughtByRightMaker); - expect(expectedTransferAmounts.amountSoldByRightMaker, "Checking logged amount sold by right maker").to.be.bignumber.equal(amountSoldByRightMaker); - expect(expectedTransferAmounts.feePaidByRightMaker, "Checking logged fee paid by right maker").to.be.bignumber.equal(feePaidByRightMaker); - expect(expectedTransferAmounts.feePaidByTakerRight, "Checking logged fee paid on right order by taker").to.be.bignumber.equal(feePaidByTakerRight); - // Verify derived amount received by taker - expect(expectedTransferAmounts.amountReceivedByTaker, "Checking logged amount received by taker").to.be.bignumber.equal(amountReceivedByTaker); + initialTakerAssetFilledAmountLeft?: BigNumber, + initialTakerAssetFilledAmountRight?: BigNumber, + ): Promise<[BigNumber, BigNumber]> { + // Verify Left order preconditions + const orderTakerAssetFilledAmountLeft = await this._exchangeWrapper.getTakerAssetFilledAmountAsync( + orderHashUtils.getOrderHashHex(signedOrderLeft), + ); + const expectedOrderFilledAmountLeft = initialTakerAssetFilledAmountLeft + ? initialTakerAssetFilledAmountLeft + : new BigNumber(0); + expect(expectedOrderFilledAmountLeft).to.be.bignumber.equal(orderTakerAssetFilledAmountLeft); + // Verify Right order preconditions + const orderTakerAssetFilledAmountRight = await this._exchangeWrapper.getTakerAssetFilledAmountAsync( + orderHashUtils.getOrderHashHex(signedOrderRight), + ); + const expectedOrderFilledAmountRight = initialTakerAssetFilledAmountRight + ? initialTakerAssetFilledAmountRight + : new BigNumber(0); + expect(expectedOrderFilledAmountRight).to.be.bignumber.equal(orderTakerAssetFilledAmountRight); + return [orderTakerAssetFilledAmountLeft, orderTakerAssetFilledAmountRight]; } + /// @dev Calculates expected transfer amounts between order makers, fee recipients, and /// the taker when two orders are matched. /// @param signedOrderLeft First matched order. @@ -310,34 +280,193 @@ export class MatchOrderTester { orderTakerAssetFilledAmountRight: BigNumber, expectedTransferAmounts: TransferAmounts, initialTakerAssetFilledAmountLeft?: BigNumber, - initialTakerAssetFilledAmountRight?: BigNumber - ) { + initialTakerAssetFilledAmountRight?: BigNumber, + ): Promise { // Verify state for left order: amount bought by left maker let amountBoughtByLeftMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync( orderHashUtils.getOrderHashHex(signedOrderLeft), ); amountBoughtByLeftMaker = amountBoughtByLeftMaker.minus(orderTakerAssetFilledAmountLeft); - expect(expectedTransferAmounts.amountBoughtByLeftMaker, "Checking exchange state for left order").to.be.bignumber.equal(amountBoughtByLeftMaker); + expect( + expectedTransferAmounts.amountBoughtByLeftMaker, + 'Checking exchange state for left order', + ).to.be.bignumber.equal(amountBoughtByLeftMaker); // Verify state for right order: amount bought by right maker let amountBoughtByRightMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync( orderHashUtils.getOrderHashHex(signedOrderRight), ); amountBoughtByRightMaker = amountBoughtByRightMaker.minus(orderTakerAssetFilledAmountRight); - expect(expectedTransferAmounts.amountBoughtByRightMaker, "Checking exchange state for right order").to.be.bignumber.equal(amountBoughtByRightMaker); + expect( + expectedTransferAmounts.amountBoughtByRightMaker, + 'Checking exchange state for right order', + ).to.be.bignumber.equal(amountBoughtByRightMaker); // Verify left order status const maxAmountBoughtByLeftMaker = initialTakerAssetFilledAmountLeft ? signedOrderLeft.takerAssetAmount.sub(initialTakerAssetFilledAmountLeft) : signedOrderLeft.takerAssetAmount; const leftOrderInfo: OrderInfo = await this._exchangeWrapper.getOrderInfoAsync(signedOrderLeft); - const leftExpectedStatus = (expectedTransferAmounts.amountBoughtByLeftMaker.equals(maxAmountBoughtByLeftMaker)) ? OrderStatus.FULLY_FILLED : OrderStatus.FILLABLE; - expect(leftOrderInfo.orderStatus as OrderStatus, "Checking exchange status for left order").to.be.equal(leftExpectedStatus); + const leftExpectedStatus = expectedTransferAmounts.amountBoughtByLeftMaker.equals(maxAmountBoughtByLeftMaker) + ? OrderStatus.FULLY_FILLED + : OrderStatus.FILLABLE; + expect(leftOrderInfo.orderStatus as OrderStatus, 'Checking exchange status for left order').to.be.equal( + leftExpectedStatus, + ); // Verify right order status const maxAmountBoughtByRightMaker = initialTakerAssetFilledAmountRight ? signedOrderRight.takerAssetAmount.sub(initialTakerAssetFilledAmountRight) : signedOrderRight.takerAssetAmount; const rightOrderInfo: OrderInfo = await this._exchangeWrapper.getOrderInfoAsync(signedOrderRight); - const rightExpectedStatus = (expectedTransferAmounts.amountBoughtByRightMaker.equals(maxAmountBoughtByRightMaker)) ? OrderStatus.FULLY_FILLED : OrderStatus.FILLABLE; - expect(rightOrderInfo.orderStatus as OrderStatus, "Checking exchange status for right order").to.be.equal(rightExpectedStatus); + const rightExpectedStatus = expectedTransferAmounts.amountBoughtByRightMaker.equals(maxAmountBoughtByRightMaker) + ? OrderStatus.FULLY_FILLED + : OrderStatus.FILLABLE; + expect(rightOrderInfo.orderStatus as OrderStatus, 'Checking exchange status for right order').to.be.equal( + rightExpectedStatus, + ); + } + private async _verifyBalancesAsync( + signedOrderLeft: SignedOrder, + signedOrderRight: SignedOrder, + initialERC20BalancesByOwner: ERC20BalancesByOwner, + initialERC721TokenIdsByOwner: ERC721TokenIdsByOwner, + finalERC20BalancesByOwner: ERC20BalancesByOwner, + finalERC721TokenIdsByOwner: ERC721TokenIdsByOwner, + expectedTransferAmounts: TransferAmounts, + takerAddress: string, + ): Promise { + let expectedERC20BalancesByOwner: ERC20BalancesByOwner; + let expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner; + [expectedERC20BalancesByOwner, expectedERC721TokenIdsByOwner] = this._calculateExpectedBalances( + signedOrderLeft, + signedOrderRight, + takerAddress, + initialERC20BalancesByOwner, + initialERC721TokenIdsByOwner, + expectedTransferAmounts, + ); + // Verify balances of makers, taker, and fee recipients + await this._verifyMakerTakerAndFeeRecipientBalancesAsync( + signedOrderLeft, + signedOrderRight, + expectedERC20BalancesByOwner, + finalERC20BalancesByOwner, + expectedERC721TokenIdsByOwner, + finalERC721TokenIdsByOwner, + takerAddress, + ); + // Verify balances for all known accounts + await MatchOrderTester._verifyAllKnownBalancesAsync( + expectedERC20BalancesByOwner, + finalERC20BalancesByOwner, + expectedERC721TokenIdsByOwner, + finalERC721TokenIdsByOwner, + ); + } + private async _verifyMakerTakerAndFeeRecipientBalancesAsync( + signedOrderLeft: SignedOrder, + signedOrderRight: SignedOrder, + expectedERC20BalancesByOwner: ERC20BalancesByOwner, + realERC20BalancesByOwner: ERC20BalancesByOwner, + expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner, + realERC721TokenIdsByOwner: ERC721TokenIdsByOwner, + takerAddress: string, + ): Promise { + // Individual balance comparisons + const makerAssetProxyIdLeft = assetDataUtils.decodeAssetProxyId(signedOrderLeft.makerAssetData); + const makerERC20AssetDataLeft = + makerAssetProxyIdLeft === AssetProxyId.ERC20 + ? assetDataUtils.decodeERC20AssetData(signedOrderLeft.makerAssetData) + : assetDataUtils.decodeERC721AssetData(signedOrderLeft.makerAssetData); + const makerAssetAddressLeft = makerERC20AssetDataLeft.tokenAddress; + const makerAssetProxyIdRight = assetDataUtils.decodeAssetProxyId(signedOrderRight.makerAssetData); + const makerERC20AssetDataRight = + makerAssetProxyIdRight === AssetProxyId.ERC20 + ? assetDataUtils.decodeERC20AssetData(signedOrderRight.makerAssetData) + : assetDataUtils.decodeERC721AssetData(signedOrderRight.makerAssetData); + const makerAssetAddressRight = makerERC20AssetDataRight.tokenAddress; + if (makerAssetProxyIdLeft === AssetProxyId.ERC20) { + expect( + realERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft], + 'Checking left maker egress ERC20 account balance', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft]); + expect( + realERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft], + 'Checking right maker ingress ERC20 account balance', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft]); + expect( + realERC20BalancesByOwner[takerAddress][makerAssetAddressLeft], + 'Checking taker ingress ERC20 account balance', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[takerAddress][makerAssetAddressLeft]); + } else if (makerAssetProxyIdLeft === AssetProxyId.ERC721) { + expect( + realERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft].sort(), + 'Checking left maker egress ERC721 account holdings', + ).to.be.deep.equal( + expectedERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft].sort(), + ); + expect( + realERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft].sort(), + 'Checking right maker ERC721 account holdings', + ).to.be.deep.equal( + expectedERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft].sort(), + ); + expect( + realERC721TokenIdsByOwner[takerAddress][makerAssetAddressLeft].sort(), + 'Checking taker ingress ERC721 account holdings', + ).to.be.deep.equal(expectedERC721TokenIdsByOwner[takerAddress][makerAssetAddressLeft].sort()); + } else { + throw new Error(`Unhandled Asset Proxy ID: ${makerAssetProxyIdLeft}`); + } + if (makerAssetProxyIdRight === AssetProxyId.ERC20) { + expect( + realERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight], + 'Checking left maker ingress ERC20 account balance', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight]); + expect( + realERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressRight], + 'Checking right maker egress ERC20 account balance', + ).to.be.bignumber.equal( + expectedERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressRight], + ); + } else if (makerAssetProxyIdRight === AssetProxyId.ERC721) { + expect( + realERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight].sort(), + 'Checking left maker ingress ERC721 account holdings', + ).to.be.deep.equal( + expectedERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight].sort(), + ); + expect( + realERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressRight], + 'Checking right maker agress ERC721 account holdings', + ).to.be.deep.equal(expectedERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressRight]); + } else { + throw new Error(`Unhandled Asset Proxy ID: ${makerAssetProxyIdRight}`); + } + // Paid fees + expect( + realERC20BalancesByOwner[signedOrderLeft.makerAddress][this._feeTokenAddress], + 'Checking left maker egress ERC20 account fees', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][this._feeTokenAddress]); + expect( + realERC20BalancesByOwner[signedOrderRight.makerAddress][this._feeTokenAddress], + 'Checking right maker egress ERC20 account fees', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][this._feeTokenAddress]); + expect( + realERC20BalancesByOwner[takerAddress][this._feeTokenAddress], + 'Checking taker egress ERC20 account fees', + ).to.be.bignumber.equal(expectedERC20BalancesByOwner[takerAddress][this._feeTokenAddress]); + // Received fees + expect( + realERC20BalancesByOwner[signedOrderLeft.feeRecipientAddress][this._feeTokenAddress], + 'Checking left fee recipient ingress ERC20 account fees', + ).to.be.bignumber.equal( + expectedERC20BalancesByOwner[signedOrderLeft.feeRecipientAddress][this._feeTokenAddress], + ); + expect( + realERC20BalancesByOwner[signedOrderRight.feeRecipientAddress][this._feeTokenAddress], + 'Checking right fee receipient ingress ERC20 account fees', + ).to.be.bignumber.equal( + expectedERC20BalancesByOwner[signedOrderRight.feeRecipientAddress][this._feeTokenAddress], + ); } /// @dev Calculates the expected balances of order makers, fee recipients, and the taker, /// as a result of matching two orders. @@ -438,7 +567,9 @@ export class MatchOrderTester { // Taker Fees expectedNewERC20BalancesByOwner[takerAddress][this._feeTokenAddress] = expectedNewERC20BalancesByOwner[ takerAddress - ][this._feeTokenAddress].minus(expectedTransferAmounts.feePaidByTakerLeft.add(expectedTransferAmounts.feePaidByTakerRight)); + ][this._feeTokenAddress].minus( + expectedTransferAmounts.feePaidByTakerLeft.add(expectedTransferAmounts.feePaidByTakerRight), + ); // Left Fee Recipient Fees expectedNewERC20BalancesByOwner[feeRecipientAddressLeft][ this._feeTokenAddress @@ -454,4 +585,4 @@ export class MatchOrderTester { return [expectedNewERC20BalancesByOwner, expectedNewERC721TokenIdsByOwner]; } -} +} // tslint:disable-line:max-file-line-count diff --git a/packages/contracts/test/utils/types.ts b/packages/contracts/test/utils/types.ts index 481ee87d6..172622777 100644 --- a/packages/contracts/test/utils/types.ts +++ b/packages/contracts/test/utils/types.ts @@ -117,21 +117,21 @@ export interface TransferAmountsByMatchOrders { // Left Maker amountBoughtByLeftMaker: BigNumber; amountSoldByLeftMaker: BigNumber; - amountReceivedByLeftMaker: BigNumber; + // amountReceivedByLeftMaker: BigNumber; feePaidByLeftMaker: BigNumber; // Right Maker amountBoughtByRightMaker: BigNumber; amountSoldByRightMaker: BigNumber; - amountReceivedByRightMaker: BigNumber; + // amountReceivedByRightMaker: BigNumber; feePaidByRightMaker: BigNumber; // Taker amountReceivedByTaker: BigNumber; feePaidByTakerLeft: BigNumber; feePaidByTakerRight: BigNumber; - totalFeePaidByTaker: BigNumber; + // totalFeePaidByTaker: BigNumber; // Fee Recipients - feeReceivedLeft: BigNumber; - feeReceivedRight: BigNumber; + // feeReceivedLeft: BigNumber; + // feeReceivedRight: BigNumber; } export interface OrderInfo { -- cgit v1.2.3