diff options
Diffstat (limited to 'packages/contract-wrappers/test/exchange_wrapper_test.ts')
-rw-r--r-- | packages/contract-wrappers/test/exchange_wrapper_test.ts | 1338 |
1 files changed, 314 insertions, 1024 deletions
diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts index c945b4c70..b2c716008 100644 --- a/packages/contract-wrappers/test/exchange_wrapper_test.ts +++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts @@ -1,57 +1,91 @@ import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils'; import { FillScenarios } from '@0xproject/fill-scenarios'; -import { getOrderHashHex } from '@0xproject/order-utils'; -import { BlockParamLiteral, DoneCallback, OrderState } from '@0xproject/types'; +import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils'; +import { DoneCallback, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; +import { BlockParamLiteral } from 'ethereum-types'; import 'mocha'; import { - BlockRange, ContractWrappers, DecodedLogEvent, - ExchangeContractErrs, + ExchangeCancelEventArgs, ExchangeEvents, - LogCancelContractEventArgs, - LogFillContractEventArgs, - OrderCancellationRequest, - OrderFillRequest, - SignedOrder, - Token, + ExchangeFillEventArgs, + OrderStatus, } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { TokenUtils } from './utils/token_utils'; +import { tokenUtils } from './utils/token_utils'; import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777'; - describe('ExchangeWrapper', () => { let contractWrappers: ContractWrappers; - let tokenUtils: TokenUtils; - let tokens: Token[]; let userAddresses: string[]; let zrxTokenAddress: string; let fillScenarios: FillScenarios; let exchangeContractAddress: string; + let makerTokenAddress: string; + let takerTokenAddress: string; + let coinbase: string; + let makerAddress: string; + let anotherMakerAddress: string; + let takerAddress: string; + let makerAssetData: string; + let takerAssetData: string; + let feeRecipient: string; + let txHash: string; + const fillableAmount = new BigNumber(5); + const takerTokenFillAmount = new BigNumber(5); + let signedOrder: SignedOrder; + let anotherSignedOrder: SignedOrder; const config = { networkId: constants.TESTRPC_NETWORK_ID, + blockPollingIntervalMs: 0, }; before(async () => { + await blockchainLifecycle.startAsync(); contractWrappers = new ContractWrappers(provider, config); exchangeContractAddress = contractWrappers.exchange.getContractAddress(); + const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - tokenUtils = new TokenUtils(tokens); - zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address; - fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress); - await fillScenarios.initTokenBalancesAsync(); + zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); + fillScenarios = new FillScenarios( + provider, + userAddresses, + zrxTokenAddress, + exchangeContractAddress, + erc20ProxyAddress, + ); + [coinbase, makerAddress, takerAddress, feeRecipient, anotherMakerAddress] = userAddresses; + [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); + [makerAssetData, takerAssetData] = [ + assetProxyUtils.encodeERC20AssetData(makerTokenAddress), + assetProxyUtils.encodeERC20AssetData(takerTokenAddress), + ]; + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -59,903 +93,279 @@ describe('ExchangeWrapper', () => { afterEach(async () => { await blockchainLifecycle.revertAsync(); }); - describe('fillOrKill order(s)', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - let feeRecipient: string; - const takerTokenFillAmount = new BigNumber(5); - before(async () => { - [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - describe('#batchFillOrKillAsync', () => { - it('successfully batch fillOrKill', async () => { - const fillableAmount = new BigNumber(5); - const partialFillTakerAmount = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + describe('fill order(s)', () => { + describe('#fillOrderAsync', () => { + it('should fill a valid order', async () => { + txHash = await contractWrappers.exchange.fillOrderAsync( + signedOrder, + takerTokenFillAmount, takerAddress, - fillableAmount, ); - const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + }); + }); + describe('#fillOrderNoThrowAsync', () => { + it('should fill a valid order', async () => { + txHash = await contractWrappers.exchange.fillOrderNoThrowAsync( + signedOrder, + takerTokenFillAmount, takerAddress, - fillableAmount, ); - const orderFillRequests = [ - { - signedOrder, - takerTokenFillAmount: partialFillTakerAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount: partialFillTakerAmount, - }, - ]; - await contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress); - }); - describe('order transaction options', () => { - let signedOrder: SignedOrder; - let orderFillRequests: OrderFillRequest[]; - const fillableAmount = new BigNumber(5); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - orderFillRequests = [ - { - signedOrder, - takerTokenFillAmount: new BigNumber(0), - }, - ]; - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); }); }); describe('#fillOrKillOrderAsync', () => { - let signedOrder: SignedOrder; - const fillableAmount = new BigNumber(5); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + it('should fill or kill a valid order', async () => { + txHash = await contractWrappers.exchange.fillOrKillOrderAsync( + signedOrder, + takerTokenFillAmount, takerAddress, - fillableAmount, ); - }); - describe('successful fills', () => { - it('should fill a valid order', async () => { - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount); - await contractWrappers.exchange.fillOrKillOrderAsync( - signedOrder, - takerTokenFillAmount, - takerAddress, - ); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - }); - it('should partially fill a valid order', async () => { - const partialFillAmount = new BigNumber(3); - await contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - }); - }); - describe('order transaction options', () => { - const emptyFillableAmount = new BigNumber(0); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); - }); - describe('fill order(s)', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - let feeRecipient: string; - const fillableAmount = new BigNumber(5); - const takerTokenFillAmount = new BigNumber(5); - const shouldThrowOnInsufficientBalanceOrAllowance = true; - before(async () => { - [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - describe('#fillOrderAsync', () => { - describe('successful fills', () => { - it('should fill a valid order', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(0); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount); - const txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - takerTokenFillAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(takerTokenFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount)); - }); - it('should partially fill the valid order', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - const partialFillAmount = new BigNumber(3); - const txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - partialFillAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress), - ).to.be.bignumber.equal(partialFillAmount); - expect( - await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress), - ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount)); - }); - it('should fill the valid orders with fees', async () => { - const makerFee = new BigNumber(1); - const takerFee = new BigNumber(2); - const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( - makerTokenAddress, - takerTokenAddress, - makerFee, - takerFee, - makerAddress, - takerAddress, - fillableAmount, - feeRecipient, - ); - const txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - takerTokenFillAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - expect( - await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient), - ).to.be.bignumber.equal(makerFee.plus(takerFee)); - }); - }); - describe('order transaction options', () => { - let signedOrder: SignedOrder; - const emptyFillTakerAmount = new BigNumber(0); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - emptyFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - emptyFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: true, - }, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - emptyFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: false, - }, - ), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + describe('#batchFillOrdersAsync', () => { + it('should fill a batch of valid orders', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount]; + txHash = await contractWrappers.exchange.batchFillOrdersAsync( + signedOrders, + takerAssetFillAmounts, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); - describe('negative fill amount', async () => { - let signedOrder: SignedOrder; - const negativeFillTakerAmount = new BigNumber(-100); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - }); - it('should not allow the exchange wrapper to fill if amount is negative', async () => { - return expect( - contractWrappers.exchange.fillOrderAsync( - signedOrder, - negativeFillTakerAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejected(); - }); + }); + describe('#marketBuyOrdersAsync', () => { + it('should maker buy', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const makerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketBuyOrdersAsync( + signedOrders, + makerAssetFillAmount, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); - describe('#batchFillOrdersAsync', () => { - let signedOrder: SignedOrder; - let signedOrderHashHex: string; - let anotherSignedOrder: SignedOrder; - let anotherOrderHashHex: string; - let orderFillBatch: OrderFillRequest[]; - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + describe('#marketBuyOrdersNoThrowAsync', () => { + it('should no throw maker buy', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const makerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketBuyOrdersNoThrowAsync( + signedOrders, + makerAssetFillAmount, takerAddress, - fillableAmount, ); - signedOrderHashHex = getOrderHashHex(signedOrder); - anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + }); + }); + describe('#marketSellOrdersAsync', () => { + it('should maker sell', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketSellOrdersAsync( + signedOrders, + takerAssetFillAmount, takerAddress, - fillableAmount, ); - anotherOrderHashHex = getOrderHashHex(anotherSignedOrder); - }); - describe('successful batch fills', () => { - beforeEach(() => { - orderFillBatch = [ - { - signedOrder, - takerTokenFillAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount, - }, - ]; - }); - it('should throw if a batch is empty', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - [], - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - }); - it('should successfully fill multiple orders', async () => { - const txHash = await contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount); - expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); - describe('order transaction options', () => { - beforeEach(async () => { - const emptyFillTakerAmount = new BigNumber(0); - orderFillBatch = [ - { - signedOrder, - takerTokenFillAmount: emptyFillTakerAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount: emptyFillTakerAmount, - }, - ]; - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: true, - }, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: false, - }, - ), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - }); - describe('negative batch fill amount', async () => { - beforeEach(async () => { - const negativeFillTakerAmount = new BigNumber(-100); - orderFillBatch = [ - { - signedOrder, - takerTokenFillAmount, - }, - { - signedOrder: anotherSignedOrder, - takerTokenFillAmount: negativeFillTakerAmount, - }, - ]; - }); - it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => { - return expect( - contractWrappers.exchange.batchFillOrdersAsync( - orderFillBatch, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejected(); - }); + }); + describe('#marketSellOrdersNoThrowAsync', () => { + it('should no throw maker sell', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmount = takerTokenFillAmount; + txHash = await contractWrappers.exchange.marketSellOrdersNoThrowAsync( + signedOrders, + takerAssetFillAmount, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + }); + }); + describe('#batchFillOrdersNoThrowAsync', () => { + it('should fill a batch of valid orders', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount]; + txHash = await contractWrappers.exchange.batchFillOrdersNoThrowAsync( + signedOrders, + takerAssetFillAmounts, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + let orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + orderInfo = await contractWrappers.exchange.getOrderInfoAsync(anotherSignedOrder); + expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED); + }); + }); + describe('#batchFillOrKillOrdersAsync', () => { + it('should fill or kill a batch of valid orders', async () => { + const signedOrders = [signedOrder, anotherSignedOrder]; + const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount]; + txHash = await contractWrappers.exchange.batchFillOrKillOrdersAsync( + signedOrders, + takerAssetFillAmounts, + takerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); - describe('#fillOrdersUpTo', () => { - let signedOrder: SignedOrder; - let signedOrderHashHex: string; - let anotherSignedOrder: SignedOrder; - let anotherOrderHashHex: string; - let signedOrders: SignedOrder[]; - const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1); - beforeEach(async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, + describe('#matchOrdersAsync', () => { + it('should match two valid ordersr', async () => { + const matchingSignedOrder = await fillScenarios.createFillableSignedOrderAsync( + takerAssetData, + makerAssetData, makerAddress, takerAddress, fillableAmount, ); - signedOrderHashHex = getOrderHashHex(signedOrder); - anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, + txHash = await contractWrappers.exchange.matchOrdersAsync( + signedOrder, + matchingSignedOrder, takerAddress, - fillableAmount, ); - anotherOrderHashHex = getOrderHashHex(anotherSignedOrder); - signedOrders = [signedOrder, anotherSignedOrder]; - }); - describe('successful batch fills', () => { - it('should throw if a batch is empty', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - [], - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); - }); - it('should successfully fill up to specified amount when all orders are fully funded', async () => { - const txHash = await contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(filledAmount).to.be.bignumber.equal(fillableAmount); - const remainingFillAmount = fillableAmount.minus(1); - expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount); - }); - it('should successfully fill up to specified amount and leave the rest of the orders untouched', async () => { - const txHash = await contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const zeroAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(anotherOrderHashHex); - expect(filledAmount).to.be.bignumber.equal(fillableAmount); - expect(zeroAmount).to.be.bignumber.equal(0); - }); - it('should successfully fill up to specified amount even if filling all orders would fail', async () => { - const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9, - // but won't have 10 to fully fill all orders in a batch. - await contractWrappers.token.transferAsync( - makerTokenAddress, - makerAddress, - coinbase, - missingBalance, - ); - const txHash = await contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex); - const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(filledAmount).to.be.bignumber.equal(fillableAmount); - const remainingFillAmount = fillableAmount.minus(1); - expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount); - }); - }); - describe('failed batch fills', () => { - it("should fail validation if user doesn't have enough balance without fill up to", async () => { - const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8 - await contractWrappers.token.transferAsync( - makerTokenAddress, - makerAddress, - coinbase, - missingBalance, - ); - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - fillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance); - }); - }); - describe('order transaction options', () => { - const emptyFillUpToAmount = new BigNumber(0); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - emptyFillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - emptyFillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: true, - }, - ), - ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.fillOrdersUpToAsync( - signedOrders, - emptyFillUpToAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - { - shouldValidate: false, - }, - ), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero); - }); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); }); describe('cancel order(s)', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let makerAddress: string; - let takerAddress: string; - const fillableAmount = new BigNumber(5); - let signedOrder: SignedOrder; - let orderHashHex: string; - const cancelAmount = new BigNumber(3); - beforeEach(async () => { - [coinbase, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - orderHashHex = getOrderHashHex(signedOrder); - }); describe('#cancelOrderAsync', () => { - describe('successful cancels', () => { - it('should cancel an order', async () => { - const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex); - expect(cancelledAmount).to.be.bignumber.equal(cancelAmount); - }); - }); - describe('order transaction options', () => { - const emptyCancelTakerTokenAmount = new BigNumber(0); - it('should validate when orderTransactionOptions are not present', async () => { - return expect( - contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); + it('should cancel a valid order', async () => { + txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); }); describe('#batchCancelOrdersAsync', () => { - let anotherSignedOrder: SignedOrder; - let anotherOrderHashHex: string; - let cancelBatch: OrderCancellationRequest[]; - beforeEach(async () => { - anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, + it('should cancel a batch of valid orders', async () => { + const orders = [signedOrder, anotherSignedOrder]; + txHash = await contractWrappers.exchange.batchCancelOrdersAsync(orders); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + }); + }); + describe('#cancelOrdersUpTo/getOrderEpochAsync', () => { + it('should cancel orders up to target order epoch', async () => { + const targetOrderEpoch = new BigNumber(42); + txHash = await contractWrappers.exchange.cancelOrdersUpToAsync(targetOrderEpoch, makerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const orderEpoch = await contractWrappers.exchange.getOrderEpochAsync( makerAddress, - takerAddress, - fillableAmount, + constants.NULL_ADDRESS, ); - anotherOrderHashHex = getOrderHashHex(anotherSignedOrder); - cancelBatch = [ - { - order: signedOrder, - takerTokenCancelAmount: cancelAmount, - }, - { - order: anotherSignedOrder, - takerTokenCancelAmount: cancelAmount, - }, - ]; - }); - describe('failed batch cancels', () => { - it('should throw when orders have different makers', async () => { - const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - takerAddress, - takerAddress, - fillableAmount, - ); - return expect( - contractWrappers.exchange.batchCancelOrdersAsync([ - cancelBatch[0], - { - order: signedOrderWithDifferentMaker, - takerTokenCancelAmount: cancelAmount, - }, - ]), - ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed); - }); - }); - describe('successful batch cancels', () => { - it('should cancel a batch of orders', async () => { - await contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch); - const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex); - const anotherCancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync( - anotherOrderHashHex, - ); - expect(cancelledAmount).to.be.bignumber.equal(cancelAmount); - expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount); - }); - }); - describe('order transaction options', () => { - beforeEach(async () => { - const emptyTakerTokenCancelAmount = new BigNumber(0); - cancelBatch = [ - { - order: signedOrder, - takerTokenCancelAmount: emptyTakerTokenCancelAmount, - }, - { - order: anotherSignedOrder, - takerTokenCancelAmount: emptyTakerTokenCancelAmount, - }, - ]; - }); - it('should validate when orderTransactionOptions are not present', async () => { - return expect(contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith( - ExchangeContractErrs.OrderCancelAmountZero, - ); - }); - it('should validate when orderTransactionOptions specify to validate', async () => { - return expect( - contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, { - shouldValidate: true, - }), - ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); - it('should not validate when orderTransactionOptions specify not to validate', async () => { - return expect( - contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, { - shouldValidate: false, - }), - ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero); - }); + expect(orderEpoch).to.be.bignumber.equal(targetOrderEpoch.plus(1)); }); }); }); - describe('tests that require partially filled order', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let takerAddress: string; - let fillableAmount: BigNumber; - let partialFillAmount: BigNumber; - let signedOrder: SignedOrder; - let orderHash: string; - before(() => { - takerAddress = userAddresses[1]; - tokenUtils = new TokenUtils(tokens); - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; + describe('#getZRXAssetData', () => { + it('should get the asset data', async () => { + const ZRX_ASSET_DATA = await contractWrappers.exchange.getZRXAssetDataAsync(); + const ASSET_DATA_HEX_LENGTH = 74; + expect(ZRX_ASSET_DATA).to.have.length(ASSET_DATA_HEX_LENGTH); }); - beforeEach(async () => { - fillableAmount = new BigNumber(5); - partialFillAmount = new BigNumber(2); - signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - takerAddress, - fillableAmount, - partialFillAmount, + }); + describe('#getOrderInfoAsync', () => { + it('should get the order info', async () => { + const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder); + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + expect(orderInfo.orderHash).to.be.equal(orderHash); + }); + }); + describe('#isValidSignature', () => { + it('should check if the signature is valid', async () => { + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + let isValid = await contractWrappers.exchange.isValidSignatureAsync( + orderHash, + signedOrder.makerAddress, + signedOrder.signature, + ); + expect(isValid).to.be.true(); + isValid = await contractWrappers.exchange.isValidSignatureAsync( + orderHash, + signedOrder.takerAddress, + signedOrder.signature, ); - orderHash = getOrderHashHex(signedOrder); + expect(isValid).to.be.false(); }); - describe('#getUnavailableTakerAmountAsync', () => { - it('should throw if passed an invalid orderHash', async () => { - const invalidOrderHashHex = '0x123'; - return expect( - contractWrappers.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex), - ).to.be.rejected(); - }); - it('should return zero if passed a valid but non-existent orderHash', async () => { - const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync( - NON_EXISTENT_ORDER_HASH, - ); - expect(unavailableValueT).to.be.bignumber.equal(0); - }); - it('should return the unavailableValueT for a valid and partially filled orderHash', async () => { - const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(orderHash); - expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount); - }); + }); + describe('#isAllowedValidatorAsync', () => { + it('should check if the validator is alllowed', async () => { + const signerAddress = makerAddress; + const validatorAddress = constants.NULL_ADDRESS; + const isAllowed = await contractWrappers.exchange.isAllowedValidatorAsync(signerAddress, validatorAddress); + expect(isAllowed).to.be.false(); }); - describe('#getFilledTakerAmountAsync', () => { - it('should throw if passed an invalid orderHash', async () => { - const invalidOrderHashHex = '0x123'; - return expect( - contractWrappers.exchange.getFilledTakerAmountAsync(invalidOrderHashHex), - ).to.be.rejected(); - }); - it('should return zero if passed a valid but non-existent orderHash', async () => { - const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH); - expect(filledValueT).to.be.bignumber.equal(0); - }); - it('should return the filledValueT for a valid and partially filled orderHash', async () => { - const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(orderHash); - expect(filledValueT).to.be.bignumber.equal(partialFillAmount); - }); + }); + describe('#setSignatureValidatorApproval', () => { + it('should set signature validator approval', async () => { + const validatorAddress = constants.NULL_ADDRESS; + const isApproved = true; + const senderAddress = makerAddress; + txHash = await contractWrappers.exchange.setSignatureValidatorApprovalAsync( + validatorAddress, + isApproved, + senderAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); }); - describe('#getCancelledTakerAmountAsync', () => { - it('should throw if passed an invalid orderHash', async () => { - const invalidOrderHashHex = '0x123'; - return expect( - contractWrappers.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex), - ).to.be.rejected(); - }); - it('should return zero if passed a valid but non-existent orderHash', async () => { - const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync( - NON_EXISTENT_ORDER_HASH, - ); - expect(cancelledValueT).to.be.bignumber.equal(0); - }); - it('should return the cancelledValueT for a valid and partially filled orderHash', async () => { - const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash); - expect(cancelledValueT).to.be.bignumber.equal(0); - }); - it('should return the cancelledValueT for a valid and cancelled orderHash', async () => { - const cancelAmount = fillableAmount.minus(partialFillAmount); - await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount); - const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash); - expect(cancelledValueT).to.be.bignumber.equal(cancelAmount); - }); + }); + describe('#isTransactionExecutedAsync', () => { + it('should check if the transaction is executed', async () => { + const transactionHash = '0x0000000000000000000000000000000000000000000000000000000000000000'; + const isExecuted = await contractWrappers.exchange.isTransactionExecutedAsync(transactionHash); + expect(isExecuted).to.be.false(); + }); + }); + describe('#getAssetProxyBySignatureAsync', () => { + it('should fill or kill a valid order', async () => { + const erc20ProxyId = await contractWrappers.erc20Proxy.getProxyIdAsync(); + const erc20ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc20ProxyId); + const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); + expect(erc20ProxyAddressById).to.be.equal(erc20ProxyAddress); + const erc721ProxyId = await contractWrappers.erc721Proxy.getProxyIdAsync(); + const erc721ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc721ProxyId); + const erc721ProxyAddress = contractWrappers.erc721Proxy.getContractAddress(); + expect(erc721ProxyAddressById).to.be.equal(erc721ProxyAddress); + }); + }); + describe('#preSignAsync/isPreSignedAsync', () => { + it('should preSign the hash', async () => { + const senderAddress = takerAddress; + const hash = orderHashUtils.getOrderHashHex(signedOrder); + const signerAddress = signedOrder.makerAddress; + let isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress); + expect(isPreSigned).to.be.false(); + txHash = await contractWrappers.exchange.preSignAsync( + hash, + signerAddress, + signedOrder.signature, + senderAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress); + expect(isPreSigned).to.be.true(); + }); + }); + describe('#getVersionAsync', () => { + it('should return version the hash', async () => { + const version = await contractWrappers.exchange.getVersionAsync(); + const VERSION = '2.0.1-alpha'; + expect(version).to.be.equal(VERSION); }); }); describe('#subscribe', () => { const indexFilterValues = {}; - const shouldThrowOnInsufficientBalanceOrAllowance = true; - let makerTokenAddress: string; - let takerTokenAddress: string; - let coinbase: string; - let takerAddress: string; - let makerAddress: string; - let fillableAmount: BigNumber; - let signedOrder: SignedOrder; const takerTokenFillAmountInBaseUnits = new BigNumber(1); - const cancelTakerAmountInBaseUnits = new BigNumber(1); - before(() => { - [coinbase, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); beforeEach(async () => { - fillableAmount = new BigNumber(5); signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, + makerAssetData, + takerAssetData, makerAddress, takerAddress, fillableAmount, @@ -969,18 +379,17 @@ describe('ExchangeWrapper', () => { // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then // wrap the rest of the test in an async block // Source: https://github.com/mochajs/mocha/issues/2407 - it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => { + it('Should receive the Fill event when an order is filled', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); + (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback); + contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback); await contractWrappers.exchange.fillOrderAsync( signedOrder, takerTokenFillAmountInBaseUnits, - shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); })().catch(done); @@ -988,35 +397,34 @@ describe('ExchangeWrapper', () => { it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => { (async () => { const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel); + (logEvent: DecodedLogEvent<ExchangeCancelEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.Cancel); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback); - await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits); + contractWrappers.exchange.subscribe(ExchangeEvents.Cancel, indexFilterValues, callback); + await contractWrappers.exchange.cancelOrderAsync(signedOrder); })().catch(done); }); it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled); + contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callbackNeverToBeCalled); contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); + (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill); }, ); - contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback); + contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback); await contractWrappers.exchange.fillOrderAsync( signedOrder, takerTokenFillAmountInBaseUnits, - shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); })().catch(done); @@ -1024,12 +432,12 @@ describe('ExchangeWrapper', () => { it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + (_logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => { done(new Error('Expected this subscription to have been cancelled')); }, ); const subscriptionToken = contractWrappers.exchange.subscribe( - ExchangeEvents.LogFill, + ExchangeEvents.Fill, indexFilterValues, callbackNeverToBeCalled, ); @@ -1037,102 +445,36 @@ describe('ExchangeWrapper', () => { await contractWrappers.exchange.fillOrderAsync( signedOrder, takerTokenFillAmountInBaseUnits, - shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, ); done(); })().catch(done); }); }); - describe('#getOrderHashHexUsingContractCallAsync', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let makerAddress: string; - let takerAddress: string; - const fillableAmount = new BigNumber(5); - before(async () => { - [, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - it("get's the same hash as the local function", async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - const orderHash = getOrderHashHex(signedOrder); - const orderHashFromContract = await (contractWrappers.exchange as any)._getOrderHashHexUsingContractCallAsync( - signedOrder, - ); - expect(orderHash).to.equal(orderHashFromContract); - }); - }); describe('#getZRXTokenAddressAsync', () => { it('gets the same token as is in token registry', () => { - const zrxAddress = contractWrappers.exchange.getZRXTokenAddress(); - const zrxToken = tokenUtils.getProtocolTokenOrThrow(); - expect(zrxAddress).to.equal(zrxToken.address); + const zrxAddressFromExchangeWrapper = contractWrappers.exchange.getZRXTokenAddress(); + const zrxAddress = tokenUtils.getProtocolTokenAddress(); + expect(zrxAddressFromExchangeWrapper).to.equal(zrxAddress); }); }); describe('#getLogsAsync', () => { - let makerTokenAddress: string; - let takerTokenAddress: string; - let makerAddress: string; - let takerAddress: string; - const fillableAmount = new BigNumber(5); - const shouldThrowOnInsufficientBalanceOrAllowance = true; - const blockRange: BlockRange = { + const blockRange = { fromBlock: 0, toBlock: BlockParamLiteral.Latest, }; - let txHash: string; - before(async () => { - [, makerAddress, takerAddress] = userAddresses; - const [makerToken, takerToken] = tokenUtils.getDummyTokens(); - makerTokenAddress = makerToken.address; - takerTokenAddress = takerToken.address; - }); - it('should get logs with decoded args emitted by LogFill', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const eventName = ExchangeEvents.LogFill; + it('should get logs with decoded args emitted by Fill', async () => { + txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress); + const eventName = ExchangeEvents.Fill; const indexFilterValues = {}; const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues); expect(logs).to.have.length(1); expect(logs[0].event).to.be.equal(eventName); }); it('should only get the logs with the correct event name', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - const differentEventName = ExchangeEvents.LogCancel; + txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const differentEventName = ExchangeEvents.Cancel; const indexFilterValues = {}; const logs = await contractWrappers.exchange.getLogsAsync( differentEventName, @@ -1142,86 +484,34 @@ describe('ExchangeWrapper', () => { expect(logs).to.have.length(0); }); it('should only get the logs with the correct indexed fields', async () => { - const signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - makerAddress, - takerAddress, - fillableAmount, - ); - txHash = await contractWrappers.exchange.fillOrderAsync( - signedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - takerAddress, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); - - const differentMakerAddress = userAddresses[2]; - const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerTokenAddress, - takerTokenAddress, - differentMakerAddress, + txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + const signedOrderWithAnotherMakerAddress = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + anotherMakerAddress, takerAddress, fillableAmount, ); txHash = await contractWrappers.exchange.fillOrderAsync( - anotherSignedOrder, - fillableAmount, - shouldThrowOnInsufficientBalanceOrAllowance, + signedOrderWithAnotherMakerAddress, + takerTokenFillAmount, takerAddress, ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash); + await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - const eventName = ExchangeEvents.LogFill; + const eventName = ExchangeEvents.Fill; const indexFilterValues = { - maker: differentMakerAddress, + makerAddress: anotherMakerAddress, }; - const logs = await contractWrappers.exchange.getLogsAsync<LogFillContractEventArgs>( + const logs = await contractWrappers.exchange.getLogsAsync<ExchangeFillEventArgs>( eventName, blockRange, indexFilterValues, ); expect(logs).to.have.length(1); const args = logs[0].args; - expect(args.maker).to.be.equal(differentMakerAddress); - }); - }); - describe('#getOrderStateAsync', () => { - let maker: string; - let taker: string; - let makerToken: Token; - let takerToken: Token; - let signedOrder: SignedOrder; - let orderState: OrderState; - const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), constants.ZRX_DECIMALS); - before(async () => { - [, maker, taker] = userAddresses; - tokens = await contractWrappers.tokenRegistry.getTokensAsync(); - [makerToken, takerToken] = tokenUtils.getDummyTokens(); - }); - it('should report orderStateValid when order is fillable', async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerToken.address, - takerToken.address, - maker, - taker, - fillableAmount, - ); - orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder); - expect(orderState.isValid).to.be.true(); - }); - it('should report orderStateInvalid when maker allowance set to 0', async () => { - signedOrder = await fillScenarios.createFillableSignedOrderAsync( - makerToken.address, - takerToken.address, - maker, - taker, - fillableAmount, - ); - await contractWrappers.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0)); - orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder); - expect(orderState.isValid).to.be.false(); + expect(args.makerAddress).to.be.equal(anotherMakerAddress); }); }); }); // tslint:disable:max-file-line-count |