Apply prettier config
This commit is contained in:
		@@ -1,16 +1,16 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
import * as Sinon from 'sinon';
 | 
			
		||||
 | 
			
		||||
import {ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx} from '../src';
 | 
			
		||||
import { ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx } from '../src';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
@@ -41,11 +41,11 @@ describe('ZeroEx library', () => {
 | 
			
		||||
 | 
			
		||||
            // Check that all nested web3 wrapper instances return the updated provider
 | 
			
		||||
            const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
 | 
			
		||||
            expect((nestedWeb3WrapperProvider).zeroExTestId).to.be.a('number');
 | 
			
		||||
            expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
 | 
			
		||||
            const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
 | 
			
		||||
            expect((exchangeWeb3WrapperProvider).zeroExTestId).to.be.a('number');
 | 
			
		||||
            expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
 | 
			
		||||
            const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
 | 
			
		||||
            expect((tokenRegistryWeb3WrapperProvider).zeroExTestId).to.be.a('number');
 | 
			
		||||
            expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#isValidSignature', () => {
 | 
			
		||||
@@ -58,22 +58,25 @@ describe('ZeroEx library', () => {
 | 
			
		||||
            s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
 | 
			
		||||
        };
 | 
			
		||||
        const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
 | 
			
		||||
        it('should return false if the data doesn\'t pertain to the signature & address', async () => {
 | 
			
		||||
        it("should return false if the data doesn't pertain to the signature & address", async () => {
 | 
			
		||||
            expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
 | 
			
		||||
            return expect(
 | 
			
		||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
 | 
			
		||||
            ).to.become(false);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return false if the address doesn\'t pertain to the signature & data', async () => {
 | 
			
		||||
        it("should return false if the address doesn't pertain to the signature & data", async () => {
 | 
			
		||||
            const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
 | 
			
		||||
            expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
 | 
			
		||||
            return expect(
 | 
			
		||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature,
 | 
			
		||||
                                                                                validUnrelatedAddress),
 | 
			
		||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
 | 
			
		||||
                    dataHex,
 | 
			
		||||
                    signature,
 | 
			
		||||
                    validUnrelatedAddress,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.become(false);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return false if the signature doesn\'t pertain to the dataHex & address', async () => {
 | 
			
		||||
            const wrongSignature = _.assign({}, signature, {v: 28});
 | 
			
		||||
        it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
 | 
			
		||||
            const wrongSignature = _.assign({}, signature, { v: 28 });
 | 
			
		||||
            expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
 | 
			
		||||
            return expect(
 | 
			
		||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
 | 
			
		||||
@@ -117,8 +120,9 @@ describe('ZeroEx library', () => {
 | 
			
		||||
        it('should throw if invalid baseUnit amount supplied as argument', () => {
 | 
			
		||||
            const invalidBaseUnitAmount = new BigNumber(1000000000.4);
 | 
			
		||||
            const decimals = 6;
 | 
			
		||||
            expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals))
 | 
			
		||||
                .to.throw('amount should be in baseUnits (no decimals), found value: 1000000000.4');
 | 
			
		||||
            expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
 | 
			
		||||
                'amount should be in baseUnits (no decimals), found value: 1000000000.4',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('Should return the expected unit amount for the decimals passed in', () => {
 | 
			
		||||
            const baseUnitAmount = new BigNumber(1000000000);
 | 
			
		||||
@@ -139,8 +143,9 @@ describe('ZeroEx library', () => {
 | 
			
		||||
        it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
 | 
			
		||||
            const unitAmount = new BigNumber(0.823091);
 | 
			
		||||
            const decimals = 5;
 | 
			
		||||
            expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals))
 | 
			
		||||
                .to.throw('Invalid unit amount: 0.823091 - Too many decimal places');
 | 
			
		||||
            expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
 | 
			
		||||
                'Invalid unit amount: 0.823091 - Too many decimal places',
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#getOrderHashHex', () => {
 | 
			
		||||
@@ -167,10 +172,11 @@ describe('ZeroEx library', () => {
 | 
			
		||||
        it('throws a readable error message if taker format is invalid', async () => {
 | 
			
		||||
            const orderWithInvalidtakerFormat = {
 | 
			
		||||
                ...order,
 | 
			
		||||
                taker: null as any as string,
 | 
			
		||||
                taker: (null as any) as string,
 | 
			
		||||
            };
 | 
			
		||||
            // tslint:disable-next-line:max-line-length
 | 
			
		||||
            const expectedErrorMessage = 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
 | 
			
		||||
            const expectedErrorMessage =
 | 
			
		||||
                'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
 | 
			
		||||
            expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -199,15 +205,15 @@ describe('ZeroEx library', () => {
 | 
			
		||||
        it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
 | 
			
		||||
            const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
 | 
			
		||||
            // tslint:disable-next-line: max-line-length
 | 
			
		||||
            const signature = '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
 | 
			
		||||
            const signature =
 | 
			
		||||
                '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
 | 
			
		||||
            const expectedECSignature = {
 | 
			
		||||
                v: 27,
 | 
			
		||||
                r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
 | 
			
		||||
                s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
 | 
			
		||||
            };
 | 
			
		||||
            stubs = [
 | 
			
		||||
                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync')
 | 
			
		||||
                    .returns(Promise.resolve(signature)),
 | 
			
		||||
                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
 | 
			
		||||
                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
@@ -217,15 +223,15 @@ describe('ZeroEx library', () => {
 | 
			
		||||
        it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
 | 
			
		||||
            const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
 | 
			
		||||
            // tslint:disable-next-line: max-line-length
 | 
			
		||||
            const signature = '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
 | 
			
		||||
            const signature =
 | 
			
		||||
                '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
 | 
			
		||||
            const expectedECSignature = {
 | 
			
		||||
                v: 27,
 | 
			
		||||
                r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
 | 
			
		||||
                s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
 | 
			
		||||
            };
 | 
			
		||||
            stubs = [
 | 
			
		||||
                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync')
 | 
			
		||||
                    .returns(Promise.resolve(signature)),
 | 
			
		||||
                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
 | 
			
		||||
                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
@@ -271,8 +277,9 @@ describe('ZeroEx library', () => {
 | 
			
		||||
                networkId: constants.TESTRPC_NETWORK_ID,
 | 
			
		||||
            };
 | 
			
		||||
            const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
 | 
			
		||||
            expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress())
 | 
			
		||||
                .to.be.equal(ZeroEx.NULL_ADDRESS);
 | 
			
		||||
            expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
 | 
			
		||||
                ZeroEx.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
import * as fs from 'fs';
 | 
			
		||||
import HDWalletProvider = require('truffle-hdwallet-provider');
 | 
			
		||||
 | 
			
		||||
import {ZeroEx} from '../src';
 | 
			
		||||
import { ZeroEx } from '../src';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
 | 
			
		||||
import {ZeroEx} from '../src';
 | 
			
		||||
import {assert} from '../src/utils/assert';
 | 
			
		||||
import { ZeroEx } from '../src';
 | 
			
		||||
import { assert } from '../src/utils/assert';
 | 
			
		||||
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
 | 
			
		||||
@@ -19,22 +19,25 @@ describe('Assertion library', () => {
 | 
			
		||||
        it('throws when address is invalid', async () => {
 | 
			
		||||
            const address = '0xdeadbeef';
 | 
			
		||||
            const varName = 'address';
 | 
			
		||||
            return expect(assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper))
 | 
			
		||||
                .to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
 | 
			
		||||
            return expect(
 | 
			
		||||
                assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
 | 
			
		||||
            ).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
 | 
			
		||||
        });
 | 
			
		||||
        it('throws when address is unavailable', async () => {
 | 
			
		||||
            const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
 | 
			
		||||
            const varName = 'address';
 | 
			
		||||
            return expect(assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper))
 | 
			
		||||
                .to.be.rejectedWith(
 | 
			
		||||
                    `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
 | 
			
		||||
                );
 | 
			
		||||
            return expect(
 | 
			
		||||
                assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
 | 
			
		||||
            ).to.be.rejectedWith(
 | 
			
		||||
                `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('doesn\'t throw if address is available', async () => {
 | 
			
		||||
        it("doesn't throw if address is available", async () => {
 | 
			
		||||
            const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
 | 
			
		||||
            const varName = 'address';
 | 
			
		||||
            return expect(assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper))
 | 
			
		||||
                .to.become(undefined);
 | 
			
		||||
            return expect(
 | 
			
		||||
                assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
 | 
			
		||||
            ).to.become(undefined);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
@@ -17,13 +17,13 @@ import {
 | 
			
		||||
    ZeroEx,
 | 
			
		||||
    ZeroExError,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {artifacts} from '../src/artifacts';
 | 
			
		||||
import {DoneCallback} from '../src/types';
 | 
			
		||||
import { artifacts } from '../src/artifacts';
 | 
			
		||||
import { DoneCallback } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -167,10 +167,12 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
 | 
			
		||||
                zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
 | 
			
		||||
                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.token.transferAsync(
 | 
			
		||||
                    etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    addressWithETH,
 | 
			
		||||
                    addressWithoutFunds,
 | 
			
		||||
                    transferAmount,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -186,10 +188,12 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                    expect(args._value).to.be.bignumber.equal(allowanceAmount);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.token.setAllowanceAsync(
 | 
			
		||||
                    etherTokenAddress, addressWithETH, addressWithoutFunds, allowanceAmount,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    addressWithETH,
 | 
			
		||||
                    addressWithoutFunds,
 | 
			
		||||
                    allowanceAmount,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -204,11 +208,8 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                    expect(args._value).to.be.bignumber.equal(depositAmount);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(
 | 
			
		||||
                    etherTokenAddress, depositAmount, addressWithETH,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
 | 
			
		||||
@@ -222,14 +223,14 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                    expect(args._value).to.be.bignumber.equal(depositAmount);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(
 | 
			
		||||
                    etherTokenAddress, depositAmount, addressWithETH,
 | 
			
		||||
                );
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
 | 
			
		||||
                zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Withdrawal, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.etherToken.withdrawAsync(
 | 
			
		||||
                    etherTokenAddress, withdrawalAmount, addressWithETH,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    EtherTokenEvents.Withdrawal,
 | 
			
		||||
                    indexFilterValues,
 | 
			
		||||
                    callback,
 | 
			
		||||
                );
 | 
			
		||||
                await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
 | 
			
		||||
@@ -238,7 +239,10 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been cancelled'));
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    EtherTokenEvents.Transfer,
 | 
			
		||||
                    indexFilterValues,
 | 
			
		||||
                    callbackNeverToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
 | 
			
		||||
                    done();
 | 
			
		||||
@@ -247,10 +251,16 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
 | 
			
		||||
                zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackToBeCalled,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    EtherTokenEvents.Transfer,
 | 
			
		||||
                    indexFilterValues,
 | 
			
		||||
                    callbackToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                await zeroEx.token.transferAsync(
 | 
			
		||||
                    etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    addressWithETH,
 | 
			
		||||
                    addressWithoutFunds,
 | 
			
		||||
                    transferAmount,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -261,10 +271,17 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                };
 | 
			
		||||
                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
 | 
			
		||||
                const subscriptionToken = zeroEx.etherToken.subscribe(
 | 
			
		||||
                    etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    EtherTokenEvents.Transfer,
 | 
			
		||||
                    indexFilterValues,
 | 
			
		||||
                    callbackNeverToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.etherToken.unsubscribe(subscriptionToken);
 | 
			
		||||
                await zeroEx.token.transferAsync(
 | 
			
		||||
                    etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
 | 
			
		||||
                    etherTokenAddress,
 | 
			
		||||
                    addressWithETH,
 | 
			
		||||
                    addressWithoutFunds,
 | 
			
		||||
                    transferAmount,
 | 
			
		||||
                );
 | 
			
		||||
                done();
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
@@ -291,7 +308,10 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
            const eventName = EtherTokenEvents.Approval;
 | 
			
		||||
            const indexFilterValues = {};
 | 
			
		||||
            const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
 | 
			
		||||
                etherTokenAddress, eventName, blockRange, indexFilterValues,
 | 
			
		||||
                etherTokenAddress,
 | 
			
		||||
                eventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(1);
 | 
			
		||||
            const args = logs[0].args;
 | 
			
		||||
@@ -305,7 +325,10 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
            const eventName = EtherTokenEvents.Deposit;
 | 
			
		||||
            const indexFilterValues = {};
 | 
			
		||||
            const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
 | 
			
		||||
                etherTokenAddress, eventName, blockRange, indexFilterValues,
 | 
			
		||||
                etherTokenAddress,
 | 
			
		||||
                eventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(1);
 | 
			
		||||
            const args = logs[0].args;
 | 
			
		||||
@@ -319,7 +342,10 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
            const differentEventName = EtherTokenEvents.Transfer;
 | 
			
		||||
            const indexFilterValues = {};
 | 
			
		||||
            const logs = await zeroEx.etherToken.getLogsAsync(
 | 
			
		||||
                etherTokenAddress, differentEventName, blockRange, indexFilterValues,
 | 
			
		||||
                etherTokenAddress,
 | 
			
		||||
                differentEventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(0);
 | 
			
		||||
        });
 | 
			
		||||
@@ -333,7 +359,10 @@ describe('EtherTokenWrapper', () => {
 | 
			
		||||
                _owner: addressWithETH,
 | 
			
		||||
            };
 | 
			
		||||
            const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
 | 
			
		||||
                etherTokenAddress, eventName, blockRange, indexFilterValues,
 | 
			
		||||
                etherTokenAddress,
 | 
			
		||||
                eventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(1);
 | 
			
		||||
            const args = logs[0].args;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,16 @@
 | 
			
		||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
import * as Sinon from 'sinon';
 | 
			
		||||
import * as Web3 from 'web3';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
    LogEvent,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {EventWatcher} from '../src/order_watcher/event_watcher';
 | 
			
		||||
import {DoneCallback} from '../src/types';
 | 
			
		||||
import { LogEvent } from '../src';
 | 
			
		||||
import { EventWatcher } from '../src/order_watcher/event_watcher';
 | 
			
		||||
import { DoneCallback } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -38,7 +36,7 @@ describe('EventWatcher', () => {
 | 
			
		||||
        blockNumber: null,
 | 
			
		||||
        data: '',
 | 
			
		||||
        logIndex: null,
 | 
			
		||||
        topics: [ '0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567' ],
 | 
			
		||||
        topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
 | 
			
		||||
        transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
 | 
			
		||||
        transactionIndex: 0,
 | 
			
		||||
    };
 | 
			
		||||
@@ -48,7 +46,7 @@ describe('EventWatcher', () => {
 | 
			
		||||
        blockNumber: null,
 | 
			
		||||
        data: '',
 | 
			
		||||
        logIndex: null,
 | 
			
		||||
        topics: [ '0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567' ],
 | 
			
		||||
        topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
 | 
			
		||||
        transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
 | 
			
		||||
        transactionIndex: 0,
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
 | 
			
		||||
import {ExchangeContractErrs, Token, ZeroEx} from '../src';
 | 
			
		||||
import {BlockParamLiteral, TradeSide, TransferType} from '../src/types';
 | 
			
		||||
import {ExchangeTransferSimulator} from '../src/utils/exchange_transfer_simulator';
 | 
			
		||||
import { ExchangeContractErrs, Token, ZeroEx } from '../src';
 | 
			
		||||
import { BlockParamLiteral, TradeSide, TransferType } from '../src/types';
 | 
			
		||||
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -45,17 +45,31 @@ describe('ExchangeTransferSimulator', () => {
 | 
			
		||||
        beforeEach(() => {
 | 
			
		||||
            exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
 | 
			
		||||
        });
 | 
			
		||||
        it('throws if the user doesn\'t have enough allowance', async () => {
 | 
			
		||||
            return expect(exchangeTransferSimulator.transferFromAsync(
 | 
			
		||||
                exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
 | 
			
		||||
        it("throws if the user doesn't have enough allowance", async () => {
 | 
			
		||||
            return expect(
 | 
			
		||||
                exchangeTransferSimulator.transferFromAsync(
 | 
			
		||||
                    exampleTokenAddress,
 | 
			
		||||
                    sender,
 | 
			
		||||
                    recipient,
 | 
			
		||||
                    transferAmount,
 | 
			
		||||
                    TradeSide.Taker,
 | 
			
		||||
                    TransferType.Trade,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
 | 
			
		||||
        });
 | 
			
		||||
        it('throws if the user doesn\'t have enough balance', async () => {
 | 
			
		||||
        it("throws if the user doesn't have enough balance", async () => {
 | 
			
		||||
            txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
            return expect(exchangeTransferSimulator.transferFromAsync(
 | 
			
		||||
                exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Maker, TransferType.Trade,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
 | 
			
		||||
            return expect(
 | 
			
		||||
                exchangeTransferSimulator.transferFromAsync(
 | 
			
		||||
                    exampleTokenAddress,
 | 
			
		||||
                    sender,
 | 
			
		||||
                    recipient,
 | 
			
		||||
                    transferAmount,
 | 
			
		||||
                    TradeSide.Maker,
 | 
			
		||||
                    TransferType.Trade,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
 | 
			
		||||
        });
 | 
			
		||||
        it('updates balances and proxyAllowance after transfer', async () => {
 | 
			
		||||
            txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
 | 
			
		||||
@@ -63,7 +77,12 @@ describe('ExchangeTransferSimulator', () => {
 | 
			
		||||
            txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
            await exchangeTransferSimulator.transferFromAsync(
 | 
			
		||||
                exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
 | 
			
		||||
                exampleTokenAddress,
 | 
			
		||||
                sender,
 | 
			
		||||
                recipient,
 | 
			
		||||
                transferAmount,
 | 
			
		||||
                TradeSide.Taker,
 | 
			
		||||
                TransferType.Trade,
 | 
			
		||||
            );
 | 
			
		||||
            const store = (exchangeTransferSimulator as any)._store;
 | 
			
		||||
            const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
 | 
			
		||||
@@ -73,13 +92,18 @@ describe('ExchangeTransferSimulator', () => {
 | 
			
		||||
            expect(recipientBalance).to.be.bignumber.equal(transferAmount);
 | 
			
		||||
            expect(senderProxyAllowance).to.be.bignumber.equal(0);
 | 
			
		||||
        });
 | 
			
		||||
        it('doesn\'t update proxyAllowance after transfer if unlimited', async () => {
 | 
			
		||||
        it("doesn't update proxyAllowance after transfer if unlimited", async () => {
 | 
			
		||||
            txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
            await exchangeTransferSimulator.transferFromAsync(
 | 
			
		||||
                exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
 | 
			
		||||
                exampleTokenAddress,
 | 
			
		||||
                sender,
 | 
			
		||||
                recipient,
 | 
			
		||||
                transferAmount,
 | 
			
		||||
                TradeSide.Taker,
 | 
			
		||||
                TransferType.Trade,
 | 
			
		||||
            );
 | 
			
		||||
            const store = (exchangeTransferSimulator as any)._store;
 | 
			
		||||
            const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
@@ -17,13 +17,13 @@ import {
 | 
			
		||||
    Token,
 | 
			
		||||
    ZeroEx,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {BlockParamLiteral, DoneCallback} from '../src/types';
 | 
			
		||||
import { BlockParamLiteral, DoneCallback } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {FillScenarios} from './utils/fill_scenarios';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { FillScenarios } from './utils/fill_scenarios';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -80,10 +80,18 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                const fillableAmount = new BigNumber(5);
 | 
			
		||||
                const partialFillTakerAmount = new BigNumber(2);
 | 
			
		||||
                const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const orderFillRequests = [
 | 
			
		||||
                    {
 | 
			
		||||
@@ -103,7 +111,11 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                const fillableAmount = new BigNumber(5);
 | 
			
		||||
                beforeEach(async () => {
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                        makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    orderFillRequests = [
 | 
			
		||||
                        {
 | 
			
		||||
@@ -113,18 +125,23 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                    ];
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions are not present', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress))
 | 
			
		||||
                        .to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
 | 
			
		||||
                        shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
 | 
			
		||||
                            shouldValidate: true,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should not validate when orderTransactionOptions specify not to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
 | 
			
		||||
                        shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -133,57 +150,78 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            const fillableAmount = new BigNumber(5);
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
            describe('successful fills', () => {
 | 
			
		||||
                it('should fill a valid order', async () => {
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(0);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(0);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        0,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        0,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(takerTokenFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(takerTokenFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount.minus(takerTokenFillAmount),
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        takerTokenFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        takerTokenFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.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 zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(partialFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(partialFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount.minus(partialFillAmount),
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        partialFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        partialFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.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(zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress))
 | 
			
		||||
                        .to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
 | 
			
		||||
                        shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.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(zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
 | 
			
		||||
                        shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -209,57 +247,96 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            describe('successful fills', () => {
 | 
			
		||||
                it('should fill a valid order', async () => {
 | 
			
		||||
                    const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                        makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        0,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        0,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(0);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(0);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount);
 | 
			
		||||
                    const txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, takerTokenFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
 | 
			
		||||
                        signedOrder,
 | 
			
		||||
                        takerTokenFillAmount,
 | 
			
		||||
                        shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                    );
 | 
			
		||||
                    await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(takerTokenFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(takerTokenFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount.minus(takerTokenFillAmount),
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        takerTokenFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        takerTokenFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.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,
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    const partialFillAmount = new BigNumber(3);
 | 
			
		||||
                    const txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, partialFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
 | 
			
		||||
                        signedOrder,
 | 
			
		||||
                        partialFillAmount,
 | 
			
		||||
                        shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                    );
 | 
			
		||||
                    await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(partialFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(partialFillAmount);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
 | 
			
		||||
                        .to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        fillableAmount.minus(partialFillAmount),
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        partialFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
 | 
			
		||||
                        partialFillAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(await zeroEx.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,
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        makerFee,
 | 
			
		||||
                        takerFee,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                    );
 | 
			
		||||
                    const txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, takerTokenFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
 | 
			
		||||
                        signedOrder,
 | 
			
		||||
                        takerTokenFillAmount,
 | 
			
		||||
                        shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                    );
 | 
			
		||||
                    await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient))
 | 
			
		||||
                        .to.be.bignumber.equal(makerFee.plus(takerFee));
 | 
			
		||||
                    expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
 | 
			
		||||
                        makerFee.plus(takerFee),
 | 
			
		||||
                    );
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
            describe('order transaction options', () => {
 | 
			
		||||
@@ -267,25 +344,48 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                const emptyFillTakerAmount = new BigNumber(0);
 | 
			
		||||
                beforeEach(async () => {
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                        makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions are not present', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, emptyFillTakerAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                    )).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                            signedOrder,
 | 
			
		||||
                            emptyFillTakerAmount,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, emptyFillTakerAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
 | 
			
		||||
                            shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.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(zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, emptyFillTakerAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                            signedOrder,
 | 
			
		||||
                            emptyFillTakerAmount,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                            {
 | 
			
		||||
                                shouldValidate: false,
 | 
			
		||||
                            },
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -297,11 +397,19 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            let orderFillBatch: OrderFillRequest[];
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
 | 
			
		||||
            });
 | 
			
		||||
@@ -319,13 +427,20 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                    ];
 | 
			
		||||
                });
 | 
			
		||||
                it('should throw if a batch is empty', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                        [], shouldThrowOnInsufficientBalanceOrAllowance, takerAddress),
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                            [],
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
 | 
			
		||||
                });
 | 
			
		||||
                it('should successfully fill multiple orders', async () => {
 | 
			
		||||
                    const txHash = await zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                        orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
 | 
			
		||||
                        orderFillBatch,
 | 
			
		||||
                        shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                    );
 | 
			
		||||
                    await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
 | 
			
		||||
                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
 | 
			
		||||
@@ -348,21 +463,37 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                    ];
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions are not present', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                        orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress),
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                            orderFillBatch,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                        orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
 | 
			
		||||
                            shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.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(zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                        orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchFillOrdersAsync(
 | 
			
		||||
                            orderFillBatch,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                            {
 | 
			
		||||
                                shouldValidate: false,
 | 
			
		||||
                            },
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -375,24 +506,40 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
 | 
			
		||||
                signedOrders = [signedOrder, anotherSignedOrder];
 | 
			
		||||
            });
 | 
			
		||||
            describe('successful batch fills', () => {
 | 
			
		||||
                it('should throw if a batch is empty', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                        [], fillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress),
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                            [],
 | 
			
		||||
                            fillUpToAmount,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
 | 
			
		||||
                });
 | 
			
		||||
                it('should successfully fill up to specified amount', async () => {
 | 
			
		||||
                    const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                        signedOrders, fillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                        signedOrders,
 | 
			
		||||
                        fillUpToAmount,
 | 
			
		||||
                        shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                    );
 | 
			
		||||
                    await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
 | 
			
		||||
@@ -405,21 +552,40 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            describe('order transaction options', () => {
 | 
			
		||||
                const emptyFillUpToAmount = new BigNumber(0);
 | 
			
		||||
                it('should validate when orderTransactionOptions are not present', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                        signedOrders, emptyFillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                    )).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                            signedOrders,
 | 
			
		||||
                            emptyFillUpToAmount,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                        signedOrders, emptyFillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
 | 
			
		||||
                            shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.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(zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                        signedOrders, emptyFillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.fillOrdersUpToAsync(
 | 
			
		||||
                            signedOrders,
 | 
			
		||||
                            emptyFillUpToAmount,
 | 
			
		||||
                            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                            takerAddress,
 | 
			
		||||
                            {
 | 
			
		||||
                                shouldValidate: false,
 | 
			
		||||
                            },
 | 
			
		||||
                        ),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -440,7 +606,11 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            makerTokenAddress = makerToken.address;
 | 
			
		||||
            takerTokenAddress = takerToken.address;
 | 
			
		||||
            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
        });
 | 
			
		||||
@@ -456,18 +626,23 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            describe('order transaction options', () => {
 | 
			
		||||
                const emptyCancelTakerTokenAmount = new BigNumber(0);
 | 
			
		||||
                it('should validate when orderTransactionOptions are not present', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount))
 | 
			
		||||
                        .to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
 | 
			
		||||
                        shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
 | 
			
		||||
                            shouldValidate: true,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should not validate when orderTransactionOptions specify not to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
 | 
			
		||||
                        shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -477,7 +652,11 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            let cancelBatch: OrderCancellationRequest[];
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                    makerTokenAddress,
 | 
			
		||||
                    takerTokenAddress,
 | 
			
		||||
                    makerAddress,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
 | 
			
		||||
                cancelBatch = [
 | 
			
		||||
@@ -494,15 +673,21 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            describe('failed batch cancels', () => {
 | 
			
		||||
                it('should throw when orders have different makers', async () => {
 | 
			
		||||
                    const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                        makerTokenAddress, takerTokenAddress, takerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    return expect(zeroEx.exchange.batchCancelOrdersAsync([
 | 
			
		||||
                        cancelBatch[0],
 | 
			
		||||
                        {
 | 
			
		||||
                            order: signedOrderWithDifferentMaker,
 | 
			
		||||
                            takerTokenCancelAmount: cancelAmount,
 | 
			
		||||
                        },
 | 
			
		||||
                    ])).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchCancelOrdersAsync([
 | 
			
		||||
                            cancelBatch[0],
 | 
			
		||||
                            {
 | 
			
		||||
                                order: signedOrderWithDifferentMaker,
 | 
			
		||||
                                takerTokenCancelAmount: cancelAmount,
 | 
			
		||||
                            },
 | 
			
		||||
                        ]),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
            describe('successful batch cancels', () => {
 | 
			
		||||
@@ -531,18 +716,23 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                    ];
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions are not present', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch))
 | 
			
		||||
                        .to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                    return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
 | 
			
		||||
                        ExchangeContractErrs.OrderCancelAmountZero,
 | 
			
		||||
                    );
 | 
			
		||||
                });
 | 
			
		||||
                it('should validate when orderTransactionOptions specify to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
 | 
			
		||||
                        shouldValidate: true,
 | 
			
		||||
                    })).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
 | 
			
		||||
                            shouldValidate: true,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
                it('should not validate when orderTransactionOptions specify not to validate', async () => {
 | 
			
		||||
                    return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
 | 
			
		||||
                        shouldValidate: false,
 | 
			
		||||
                    })).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                    return expect(
 | 
			
		||||
                        zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
 | 
			
		||||
                            shouldValidate: false,
 | 
			
		||||
                        }),
 | 
			
		||||
                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
@@ -566,7 +756,11 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            fillableAmount = new BigNumber(5);
 | 
			
		||||
            partialFillAmount = new BigNumber(2);
 | 
			
		||||
            signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, takerAddress, fillableAmount, partialFillAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                partialFillAmount,
 | 
			
		||||
            );
 | 
			
		||||
            orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
        });
 | 
			
		||||
@@ -590,8 +784,7 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
 | 
			
		||||
            });
 | 
			
		||||
            it('should return zero if passed a valid but non-existent orderHash', async () => {
 | 
			
		||||
                const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH,
 | 
			
		||||
                );
 | 
			
		||||
                const filledValueT = await zeroEx.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 () => {
 | 
			
		||||
@@ -641,7 +834,11 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
        beforeEach(async () => {
 | 
			
		||||
            fillableAmount = new BigNumber(5);
 | 
			
		||||
            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        afterEach(async () => {
 | 
			
		||||
@@ -654,42 +851,35 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
        // Source: https://github.com/mochajs/mocha/issues/2407
 | 
			
		||||
        it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
 | 
			
		||||
                const callback = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
 | 
			
		||||
                    expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.exchange.subscribe(
 | 
			
		||||
                    ExchangeEvents.LogFill, indexFilterValues, callback,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                    signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    takerTokenFillAmountInBaseUnits,
 | 
			
		||||
                    shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
 | 
			
		||||
                const callback = (err: Error, logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
 | 
			
		||||
                    expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.exchange.subscribe(
 | 
			
		||||
                    ExchangeEvents.LogCancel, indexFilterValues, callback,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
 | 
			
		||||
                const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been cancelled'));
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.exchange.subscribe(
 | 
			
		||||
                    ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
 | 
			
		||||
 | 
			
		||||
                const newProvider = web3Factory.getRpcProvider();
 | 
			
		||||
                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 | 
			
		||||
@@ -698,11 +888,11 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                    expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.exchange.subscribe(
 | 
			
		||||
                    ExchangeEvents.LogFill, indexFilterValues, callback,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                    signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    takerTokenFillAmountInBaseUnits,
 | 
			
		||||
                    shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
@@ -713,11 +903,15 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been cancelled'));
 | 
			
		||||
                };
 | 
			
		||||
                const subscriptionToken = zeroEx.exchange.subscribe(
 | 
			
		||||
                    ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled,
 | 
			
		||||
                    ExchangeEvents.LogFill,
 | 
			
		||||
                    indexFilterValues,
 | 
			
		||||
                    callbackNeverToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.exchange.unsubscribe(subscriptionToken);
 | 
			
		||||
                await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                    signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    takerTokenFillAmountInBaseUnits,
 | 
			
		||||
                    shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                );
 | 
			
		||||
                done();
 | 
			
		||||
@@ -736,13 +930,18 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
            makerTokenAddress = makerToken.address;
 | 
			
		||||
            takerTokenAddress = takerToken.address;
 | 
			
		||||
        });
 | 
			
		||||
        it('get\'s the same hash as the local function', async () => {
 | 
			
		||||
        it("get's the same hash as the local function", async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
            const orderHashFromContract = await (zeroEx.exchange as any)
 | 
			
		||||
                ._getOrderHashHexUsingContractCallAsync(signedOrder);
 | 
			
		||||
            const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
            );
 | 
			
		||||
            expect(orderHash).to.equal(orderHashFromContract);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -773,10 +972,17 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
        });
 | 
			
		||||
        it('should get logs with decoded args emitted by LogFill', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
            const eventName = ExchangeEvents.LogFill;
 | 
			
		||||
@@ -787,10 +993,17 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
        });
 | 
			
		||||
        it('should only get the logs with the correct event name', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
            const differentEventName = ExchangeEvents.LogCancel;
 | 
			
		||||
@@ -800,19 +1013,33 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
        });
 | 
			
		||||
        it('should only get the logs with the correct indexed fields', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
 | 
			
		||||
            const differentMakerAddress = userAddresses[2];
 | 
			
		||||
            const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, differentMakerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                differentMakerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            txHash = await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                anotherSignedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
                anotherSignedOrder,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.awaitTransactionMinedAsync(txHash);
 | 
			
		||||
 | 
			
		||||
@@ -821,7 +1048,9 @@ describe('ExchangeWrapper', () => {
 | 
			
		||||
                maker: differentMakerAddress,
 | 
			
		||||
            };
 | 
			
		||||
            const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
 | 
			
		||||
                eventName, blockRange, indexFilterValues,
 | 
			
		||||
                eventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(1);
 | 
			
		||||
            const args = logs[0].args;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
@@ -6,18 +6,18 @@ import 'mocha';
 | 
			
		||||
import * as Sinon from 'sinon';
 | 
			
		||||
import * as Web3 from 'web3';
 | 
			
		||||
 | 
			
		||||
import {ZeroEx} from '../src/0x';
 | 
			
		||||
import {ExpirationWatcher} from '../src/order_watcher/expiration_watcher';
 | 
			
		||||
import {DoneCallback, Token} from '../src/types';
 | 
			
		||||
import {constants} from '../src/utils/constants';
 | 
			
		||||
import {utils} from '../src/utils/utils';
 | 
			
		||||
import { ZeroEx } from '../src/0x';
 | 
			
		||||
import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher';
 | 
			
		||||
import { DoneCallback, Token } from '../src/types';
 | 
			
		||||
import { constants } from '../src/utils/constants';
 | 
			
		||||
import { utils } from '../src/utils/utils';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants as testConstants} from './utils/constants';
 | 
			
		||||
import {FillScenarios} from './utils/fill_scenarios';
 | 
			
		||||
import {reportCallbackErrors} from './utils/report_callback_errors';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants as testConstants } from './utils/constants';
 | 
			
		||||
import { FillScenarios } from './utils/fill_scenarios';
 | 
			
		||||
import { reportCallbackErrors } from './utils/report_callback_errors';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -62,7 +62,7 @@ describe('ExpirationWatcher', () => {
 | 
			
		||||
    });
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
        await blockchainLifecycle.startAsync();
 | 
			
		||||
        const sinonTimerConfig = {shouldAdvanceTime: true} as any;
 | 
			
		||||
        const sinonTimerConfig = { shouldAdvanceTime: true } as any;
 | 
			
		||||
        // This constructor has incorrect types
 | 
			
		||||
        timer = Sinon.useFakeTimers(sinonTimerConfig);
 | 
			
		||||
        currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
 | 
			
		||||
@@ -78,7 +78,11 @@ describe('ExpirationWatcher', () => {
 | 
			
		||||
            const orderLifetimeSec = 60;
 | 
			
		||||
            const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                expirationUnixTimestampSec,
 | 
			
		||||
            );
 | 
			
		||||
            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
@@ -92,12 +96,16 @@ describe('ExpirationWatcher', () => {
 | 
			
		||||
            timer.tick(orderLifetimeSec * 1000);
 | 
			
		||||
        })().catch(done);
 | 
			
		||||
    });
 | 
			
		||||
    it('doesn\'t emit events before order expires', (done: DoneCallback) => {
 | 
			
		||||
    it("doesn't emit events before order expires", (done: DoneCallback) => {
 | 
			
		||||
        (async () => {
 | 
			
		||||
            const orderLifetimeSec = 60;
 | 
			
		||||
            const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                expirationUnixTimestampSec,
 | 
			
		||||
            );
 | 
			
		||||
            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
@@ -118,11 +126,19 @@ describe('ExpirationWatcher', () => {
 | 
			
		||||
            const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
 | 
			
		||||
            const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
 | 
			
		||||
            const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                order1ExpirationUnixTimestampSec,
 | 
			
		||||
            );
 | 
			
		||||
            const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                order2ExpirationUnixTimestampSec,
 | 
			
		||||
            );
 | 
			
		||||
            const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
@@ -15,14 +15,14 @@ import {
 | 
			
		||||
    ZeroEx,
 | 
			
		||||
    ZeroExError,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {DoneCallback} from '../src/types';
 | 
			
		||||
import { DoneCallback } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {FillScenarios} from './utils/fill_scenarios';
 | 
			
		||||
import {reportCallbackErrors} from './utils/report_callback_errors';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { FillScenarios } from './utils/fill_scenarios';
 | 
			
		||||
import { reportCallbackErrors } from './utils/report_callback_errors';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
const TIMEOUT_MS = 150;
 | 
			
		||||
 | 
			
		||||
@@ -71,7 +71,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
    describe('#removeOrder', async () => {
 | 
			
		||||
        it('should successfully remove existing order', async () => {
 | 
			
		||||
            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                makerToken.address,
 | 
			
		||||
                takerToken.address,
 | 
			
		||||
                maker,
 | 
			
		||||
                taker,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
            zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
@@ -89,10 +93,18 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
        });
 | 
			
		||||
        it('should no-op when removing a non-existing order', async () => {
 | 
			
		||||
            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                makerToken.address,
 | 
			
		||||
                takerToken.address,
 | 
			
		||||
                maker,
 | 
			
		||||
                taker,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
            const nonExistentOrderHash = `0x${orderHash.substr(2).split('').reverse().join('')}`;
 | 
			
		||||
            const nonExistentOrderHash = `0x${orderHash
 | 
			
		||||
                .substr(2)
 | 
			
		||||
                .split('')
 | 
			
		||||
                .reverse()
 | 
			
		||||
                .join('')}`;
 | 
			
		||||
            zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -102,8 +114,7 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
        });
 | 
			
		||||
        it('should fail when trying to subscribe twice', async () => {
 | 
			
		||||
            zeroEx.orderStateWatcher.subscribe(_.noop);
 | 
			
		||||
            expect(() => zeroEx.orderStateWatcher.subscribe(_.noop))
 | 
			
		||||
                .to.throw(ZeroExError.SubscriptionAlreadyPresent);
 | 
			
		||||
            expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('tests with cleanup', async () => {
 | 
			
		||||
@@ -115,7 +126,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
        it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
@@ -133,7 +148,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
        it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
                const callback = reportCallbackErrors(done)((orderState: OrderState) => {
 | 
			
		||||
@@ -152,7 +171,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
        it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
@@ -172,7 +195,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
        it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
@@ -188,14 +215,21 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
 | 
			
		||||
                const shouldThrowOnInsufficientBalanceOrAllowance = true;
 | 
			
		||||
                await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                    signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, taker,
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                    shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    taker,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
 | 
			
		||||
@@ -211,16 +245,21 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                    const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
 | 
			
		||||
                    const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
 | 
			
		||||
                    expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                        remainingFillable);
 | 
			
		||||
                        remainingFillable,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                        remainingFillable);
 | 
			
		||||
                        remainingFillable,
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
                zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
                const shouldThrowOnInsufficientBalanceOrAllowance = true;
 | 
			
		||||
                await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                    signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker,
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    fillAmountInBaseUnits,
 | 
			
		||||
                    shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                    taker,
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -229,8 +268,15 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
 | 
			
		||||
                const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, makerFee, takerFee, maker, taker, fillableAmount,
 | 
			
		||||
                    taker);
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    makerFee,
 | 
			
		||||
                    takerFee,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                    taker,
 | 
			
		||||
                );
 | 
			
		||||
                const callback = reportCallbackErrors(done)((orderState: OrderState) => {
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
@@ -245,7 +291,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                    const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
 | 
			
		||||
                    const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
 | 
			
		||||
                    signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
                        makerToken.address, takerToken.address, maker, taker, makerFillableAmount,
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        takerToken.address,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        taker,
 | 
			
		||||
                        makerFillableAmount,
 | 
			
		||||
                        takerFillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                    const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
 | 
			
		||||
@@ -257,22 +307,31 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                        expect(validOrderState.orderHash).to.be.equal(orderHash);
 | 
			
		||||
                        const orderRelevantState = validOrderState.orderRelevantState;
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals));
 | 
			
		||||
                            ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
 | 
			
		||||
                        );
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals));
 | 
			
		||||
                            ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
 | 
			
		||||
                        );
 | 
			
		||||
                        done();
 | 
			
		||||
                    });
 | 
			
		||||
                    zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
                    const shouldThrowOnInsufficientBalanceOrAllowance = true;
 | 
			
		||||
                    await zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
                        signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker,
 | 
			
		||||
                        signedOrder,
 | 
			
		||||
                        fillAmountInBaseUnits,
 | 
			
		||||
                        shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
                        taker,
 | 
			
		||||
                    );
 | 
			
		||||
                })().catch(done);
 | 
			
		||||
            });
 | 
			
		||||
            it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
 | 
			
		||||
                (async () => {
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                        makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        takerToken.address,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        taker,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
 | 
			
		||||
@@ -282,9 +341,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                        const validOrderState = orderState as OrderStateValid;
 | 
			
		||||
                        const orderRelevantState = validOrderState.orderRelevantState;
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            changedMakerApprovalAmount);
 | 
			
		||||
                            changedMakerApprovalAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            changedMakerApprovalAmount);
 | 
			
		||||
                            changedMakerApprovalAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        done();
 | 
			
		||||
                    });
 | 
			
		||||
                    zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
@@ -294,7 +355,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
            it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
 | 
			
		||||
                (async () => {
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                        makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        takerToken.address,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        taker,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
 | 
			
		||||
@@ -308,14 +373,15 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                        const validOrderState = orderState as OrderStateValid;
 | 
			
		||||
                        const orderRelevantState = validOrderState.orderRelevantState;
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            remainingAmount);
 | 
			
		||||
                            remainingAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            remainingAmount);
 | 
			
		||||
                            remainingAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        done();
 | 
			
		||||
                    });
 | 
			
		||||
                    zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
                    await zeroEx.token.transferAsync(
 | 
			
		||||
                        makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
 | 
			
		||||
                    await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
 | 
			
		||||
                })().catch(done);
 | 
			
		||||
            });
 | 
			
		||||
            it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
 | 
			
		||||
@@ -324,8 +390,15 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
 | 
			
		||||
                    const feeRecipient = taker;
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                        makerToken.address, takerToken.address, makerFee, takerFee, maker,
 | 
			
		||||
                        taker, fillableAmount, feeRecipient);
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        takerToken.address,
 | 
			
		||||
                        makerFee,
 | 
			
		||||
                        takerFee,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        taker,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
 | 
			
		||||
                    const transferTokenAmount = makerFee.sub(remainingTokenAmount);
 | 
			
		||||
@@ -336,7 +409,8 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                        const validOrderState = orderState as OrderStateValid;
 | 
			
		||||
                        const orderRelevantState = validOrderState.orderRelevantState;
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            remainingTokenAmount);
 | 
			
		||||
                            remainingTokenAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        done();
 | 
			
		||||
                    });
 | 
			
		||||
                    zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
@@ -349,8 +423,15 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
 | 
			
		||||
                    const feeRecipient = taker;
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                        makerToken.address, takerToken.address, makerFee, takerFee, maker,
 | 
			
		||||
                        taker, fillableAmount, feeRecipient);
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        takerToken.address,
 | 
			
		||||
                        makerFee,
 | 
			
		||||
                        takerFee,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        taker,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
 | 
			
		||||
 | 
			
		||||
@@ -362,13 +443,18 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                        const validOrderState = orderState as OrderStateValid;
 | 
			
		||||
                        const orderRelevantState = validOrderState.orderRelevantState;
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            remainingFeeAmount);
 | 
			
		||||
                            remainingFeeAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        done();
 | 
			
		||||
                    });
 | 
			
		||||
                    zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
                    await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
 | 
			
		||||
                    await zeroEx.token.transferAsync(
 | 
			
		||||
                        makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferTokenAmount);
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        ZeroEx.NULL_ADDRESS,
 | 
			
		||||
                        transferTokenAmount,
 | 
			
		||||
                    );
 | 
			
		||||
                })().catch(done);
 | 
			
		||||
            });
 | 
			
		||||
            it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
 | 
			
		||||
@@ -377,8 +463,15 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
 | 
			
		||||
                    const feeRecipient = taker;
 | 
			
		||||
                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                        makerToken.address, takerToken.address, makerFee, takerFee, maker,
 | 
			
		||||
                        taker, fillableAmount, feeRecipient);
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        takerToken.address,
 | 
			
		||||
                        makerFee,
 | 
			
		||||
                        takerFee,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        taker,
 | 
			
		||||
                        fillableAmount,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
 | 
			
		||||
@@ -386,19 +479,27 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                        const validOrderState = orderState as OrderStateValid;
 | 
			
		||||
                        const orderRelevantState = validOrderState.orderRelevantState;
 | 
			
		||||
                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
 | 
			
		||||
                            fillableAmount);
 | 
			
		||||
                            fillableAmount,
 | 
			
		||||
                        );
 | 
			
		||||
                        done();
 | 
			
		||||
                    });
 | 
			
		||||
                    zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
                    await zeroEx.token.setProxyAllowanceAsync(
 | 
			
		||||
                        makerToken.address, maker, ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals));
 | 
			
		||||
                        makerToken.address,
 | 
			
		||||
                        maker,
 | 
			
		||||
                        ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
 | 
			
		||||
                    );
 | 
			
		||||
                })().catch(done);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
@@ -419,7 +520,11 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const remainingFillableAmountInBaseUnits = new BigNumber(100);
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
 | 
			
		||||
                zeroEx.orderStateWatcher.addOrder(signedOrder);
 | 
			
		||||
@@ -433,14 +538,19 @@ describe('OrderStateWatcher', () => {
 | 
			
		||||
                });
 | 
			
		||||
                zeroEx.orderStateWatcher.subscribe(callback);
 | 
			
		||||
                await zeroEx.exchange.cancelOrderAsync(
 | 
			
		||||
                    signedOrder, fillableAmount.minus(remainingFillableAmountInBaseUnits),
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    fillableAmount.minus(remainingFillableAmountInBaseUnits),
 | 
			
		||||
                );
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                    makerToken.address, takerToken.address, maker, taker, fillableAmount,
 | 
			
		||||
                    makerToken.address,
 | 
			
		||||
                    takerToken.address,
 | 
			
		||||
                    maker,
 | 
			
		||||
                    taker,
 | 
			
		||||
                    fillableAmount,
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                const cancelAmountInBaseUnits = new BigNumber(2);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,19 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as Sinon from 'sinon';
 | 
			
		||||
import * as Web3 from 'web3';
 | 
			
		||||
 | 
			
		||||
import {ExchangeContractErrs, SignedOrder, Token, ZeroEx, ZeroExError} from '../src';
 | 
			
		||||
import {BlockParamLiteral, TradeSide, TransferType} from '../src/types';
 | 
			
		||||
import {ExchangeTransferSimulator} from '../src/utils/exchange_transfer_simulator';
 | 
			
		||||
import {OrderValidationUtils} from '../src/utils/order_validation_utils';
 | 
			
		||||
import { ExchangeContractErrs, SignedOrder, Token, ZeroEx, ZeroExError } from '../src';
 | 
			
		||||
import { BlockParamLiteral, TradeSide, TransferType } from '../src/types';
 | 
			
		||||
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
 | 
			
		||||
import { OrderValidationUtils } from '../src/utils/order_validation_utils';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {FillScenarios} from './utils/fill_scenarios';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { FillScenarios } from './utils/fill_scenarios';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -62,108 +62,152 @@ describe('OrderValidation', () => {
 | 
			
		||||
    describe('validateOrderFillableOrThrowAsync', () => {
 | 
			
		||||
        it('should succeed if the order is fillable', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.exchange.validateOrderFillableOrThrowAsync(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
 | 
			
		||||
        });
 | 
			
		||||
        it('should succeed if the order is asymmetric and fillable', async () => {
 | 
			
		||||
            const makerFillableAmount = fillableAmount;
 | 
			
		||||
            const takerFillableAmount = fillableAmount.minus(4);
 | 
			
		||||
            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
                makerFillableAmount, takerFillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.exchange.validateOrderFillableOrThrowAsync(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                makerFillableAmount,
 | 
			
		||||
                takerFillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when the order is fully filled or cancelled', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
 | 
			
		||||
            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
 | 
			
		||||
            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
 | 
			
		||||
                ExchangeContractErrs.OrderRemainingFillAmountZero,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when order is expired', async () => {
 | 
			
		||||
            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
                fillableAmount, expirationInPast,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                expirationInPast,
 | 
			
		||||
            );
 | 
			
		||||
            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
 | 
			
		||||
                ExchangeContractErrs.OrderFillExpired,
 | 
			
		||||
            );
 | 
			
		||||
            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('validateFillOrderAndThrowIfInvalidAsync', () => {
 | 
			
		||||
        it('should throw when the fill amount is zero', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const zeroFillAmount = new BigNumber(0);
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, zeroFillAmount, takerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when the signature is invalid', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            // 27 <--> 28
 | 
			
		||||
            signedOrder.ecSignature.v = (28 - signedOrder.ecSignature.v) + 27;
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, fillableAmount, takerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.InvalidSignature);
 | 
			
		||||
            signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.InvalidSignature);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when the order is fully filled or cancelled', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, fillableAmount, takerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when sender is not a taker', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const nonTakerAddress = userAddresses[6];
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, fillTakerAmount, nonTakerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when order is expired', async () => {
 | 
			
		||||
            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
                fillableAmount, expirationInPast,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                expirationInPast,
 | 
			
		||||
            );
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, fillTakerAmount, takerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when there a rounding error would have occurred', async () => {
 | 
			
		||||
            const makerAmount = new BigNumber(3);
 | 
			
		||||
            const takerAmount = new BigNumber(5);
 | 
			
		||||
            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
                makerAmount, takerAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                makerAmount,
 | 
			
		||||
                takerAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, fillTakerAmountThatCausesRoundingError, takerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    fillTakerAmountThatCausesRoundingError,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
 | 
			
		||||
        it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const tooLargeFillAmount = new BigNumber(7);
 | 
			
		||||
            const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
 | 
			
		||||
@@ -172,9 +216,13 @@ describe('OrderValidation', () => {
 | 
			
		||||
            await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
 | 
			
		||||
            await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
 | 
			
		||||
 | 
			
		||||
            return expect(zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
 | 
			
		||||
                signedOrder, tooLargeFillAmount, takerAddress,
 | 
			
		||||
            )).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    tooLargeFillAmount,
 | 
			
		||||
                    takerAddress,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
 | 
			
		||||
@@ -186,27 +234,38 @@ describe('OrderValidation', () => {
 | 
			
		||||
            makerTokenAddress = makerToken.address;
 | 
			
		||||
            takerTokenAddress = takerToken.address;
 | 
			
		||||
            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when cancel amount is zero', async () => {
 | 
			
		||||
            const zeroCancelAmount = new BigNumber(0);
 | 
			
		||||
            return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount))
 | 
			
		||||
                .to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when order is expired', async () => {
 | 
			
		||||
            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
 | 
			
		||||
            const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
                fillableAmount, expirationInPast,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                expirationInPast,
 | 
			
		||||
            );
 | 
			
		||||
            return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount))
 | 
			
		||||
                .to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw when order is already cancelled or filled', async () => {
 | 
			
		||||
            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
 | 
			
		||||
            return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount))
 | 
			
		||||
                .to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
 | 
			
		||||
@@ -224,82 +283,159 @@ describe('OrderValidation', () => {
 | 
			
		||||
            const makerFee = new BigNumber(2);
 | 
			
		||||
            const takerFee = new BigNumber(2);
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerFee, takerFee,
 | 
			
		||||
                makerAddress, takerAddress, fillableAmount, feeRecipient,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerFee,
 | 
			
		||||
                takerFee,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                feeRecipient,
 | 
			
		||||
            );
 | 
			
		||||
            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
 | 
			
		||||
                exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
 | 
			
		||||
                exchangeTransferSimulator,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                zrxTokenAddress,
 | 
			
		||||
            );
 | 
			
		||||
            expect(transferFromAsync.callCount).to.be.equal(4);
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(0).calledWith(
 | 
			
		||||
                    makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
 | 
			
		||||
                    TradeSide.Maker, TransferType.Trade,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(0)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        bigNumberMatch(fillableAmount),
 | 
			
		||||
                        TradeSide.Maker,
 | 
			
		||||
                        TransferType.Trade,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(1).calledWith(
 | 
			
		||||
                    takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
 | 
			
		||||
                    TradeSide.Taker, TransferType.Trade,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(1)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        bigNumberMatch(fillableAmount),
 | 
			
		||||
                        TradeSide.Taker,
 | 
			
		||||
                        TransferType.Trade,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(2).calledWith(
 | 
			
		||||
                    zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
 | 
			
		||||
                    TradeSide.Maker, TransferType.Fee,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(2)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        zrxTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                        bigNumberMatch(makerFee),
 | 
			
		||||
                        TradeSide.Maker,
 | 
			
		||||
                        TransferType.Fee,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(3).calledWith(
 | 
			
		||||
                    zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
 | 
			
		||||
                    TradeSide.Taker, TransferType.Fee,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(3)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        zrxTokenAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                        bigNumberMatch(takerFee),
 | 
			
		||||
                        TradeSide.Taker,
 | 
			
		||||
                        TransferType.Fee,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
        it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
 | 
			
		||||
            const makerFee = new BigNumber(2);
 | 
			
		||||
            const takerFee = new BigNumber(2);
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerFee, takerFee,
 | 
			
		||||
                makerAddress, ZeroEx.NULL_ADDRESS, fillableAmount, feeRecipient,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerFee,
 | 
			
		||||
                takerFee,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                ZeroEx.NULL_ADDRESS,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                feeRecipient,
 | 
			
		||||
            );
 | 
			
		||||
            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
 | 
			
		||||
                exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
 | 
			
		||||
                exchangeTransferSimulator,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                zrxTokenAddress,
 | 
			
		||||
            );
 | 
			
		||||
            expect(transferFromAsync.callCount).to.be.equal(4);
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(0).calledWith(
 | 
			
		||||
                    makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
 | 
			
		||||
                    TradeSide.Maker, TransferType.Trade,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(0)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        makerTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        bigNumberMatch(fillableAmount),
 | 
			
		||||
                        TradeSide.Maker,
 | 
			
		||||
                        TransferType.Trade,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(1).calledWith(
 | 
			
		||||
                    takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
 | 
			
		||||
                    TradeSide.Taker, TransferType.Trade,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(1)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        takerTokenAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        bigNumberMatch(fillableAmount),
 | 
			
		||||
                        TradeSide.Taker,
 | 
			
		||||
                        TransferType.Trade,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(2).calledWith(
 | 
			
		||||
                    zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
 | 
			
		||||
                    TradeSide.Maker, TransferType.Fee,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(2)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        zrxTokenAddress,
 | 
			
		||||
                        makerAddress,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                        bigNumberMatch(makerFee),
 | 
			
		||||
                        TradeSide.Maker,
 | 
			
		||||
                        TransferType.Fee,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
            expect(
 | 
			
		||||
                transferFromAsync.getCall(3).calledWith(
 | 
			
		||||
                    zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
 | 
			
		||||
                    TradeSide.Taker, TransferType.Fee,
 | 
			
		||||
                ),
 | 
			
		||||
                transferFromAsync
 | 
			
		||||
                    .getCall(3)
 | 
			
		||||
                    .calledWith(
 | 
			
		||||
                        zrxTokenAddress,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
                        feeRecipient,
 | 
			
		||||
                        bigNumberMatch(takerFee),
 | 
			
		||||
                        TradeSide.Taker,
 | 
			
		||||
                        TransferType.Fee,
 | 
			
		||||
                    ),
 | 
			
		||||
            ).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
        it('should correctly round the fillMakerTokenAmount', async () => {
 | 
			
		||||
            const makerTokenAmount = new BigNumber(3);
 | 
			
		||||
            const takerTokenAmount = new BigNumber(1);
 | 
			
		||||
            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, makerTokenAmount, takerTokenAmount,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                makerTokenAmount,
 | 
			
		||||
                takerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
 | 
			
		||||
                exchangeTransferSimulator, signedOrder, takerTokenAmount, takerAddress, zrxTokenAddress,
 | 
			
		||||
                exchangeTransferSimulator,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                takerTokenAmount,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                zrxTokenAddress,
 | 
			
		||||
            );
 | 
			
		||||
            expect(transferFromAsync.callCount).to.be.equal(4);
 | 
			
		||||
            const makerFillAmount = transferFromAsync.getCall(0).args[3];
 | 
			
		||||
@@ -309,12 +445,22 @@ describe('OrderValidation', () => {
 | 
			
		||||
            const makerFee = new BigNumber(2);
 | 
			
		||||
            const takerFee = new BigNumber(4);
 | 
			
		||||
            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
                makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
 | 
			
		||||
                fillableAmount, ZeroEx.NULL_ADDRESS,
 | 
			
		||||
                makerTokenAddress,
 | 
			
		||||
                takerTokenAddress,
 | 
			
		||||
                makerFee,
 | 
			
		||||
                takerFee,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                fillableAmount,
 | 
			
		||||
                ZeroEx.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
            const fillTakerTokenAmount = fillableAmount.div(2).round(0);
 | 
			
		||||
            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
 | 
			
		||||
                exchangeTransferSimulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress,
 | 
			
		||||
                exchangeTransferSimulator,
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                fillTakerTokenAmount,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
                zrxTokenAddress,
 | 
			
		||||
            );
 | 
			
		||||
            const makerPartialFee = makerFee.div(2);
 | 
			
		||||
            const takerPartialFee = takerFee.div(2);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,11 @@ import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
 | 
			
		||||
import {ZeroEx} from '../src/0x';
 | 
			
		||||
import {RemainingFillableCalculator} from '../src/order_watcher/remaining_fillable_calculator';
 | 
			
		||||
import {ECSignature, SignedOrder} from '../src/types';
 | 
			
		||||
import { ZeroEx } from '../src/0x';
 | 
			
		||||
import { RemainingFillableCalculator } from '../src/order_watcher/remaining_fillable_calculator';
 | 
			
		||||
import { ECSignature, SignedOrder } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -26,29 +26,34 @@ describe('RemainingFillableCalculator', () => {
 | 
			
		||||
    const decimals: number = 4;
 | 
			
		||||
    const zero: BigNumber = new BigNumber(0);
 | 
			
		||||
    const zeroAddress = '0x0';
 | 
			
		||||
    const signature: ECSignature = {v: 27, r: '', s: ''};
 | 
			
		||||
    const signature: ECSignature = { v: 27, r: '', s: '' };
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
        [makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
 | 
			
		||||
                                                      ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
 | 
			
		||||
                                                      ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals)];
 | 
			
		||||
        [makerAmount, takerAmount, makerFeeAmount] = [
 | 
			
		||||
            ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
 | 
			
		||||
            ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
 | 
			
		||||
            ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
 | 
			
		||||
        ];
 | 
			
		||||
        [transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
 | 
			
		||||
                                                ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
 | 
			
		||||
                                                ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals)];
 | 
			
		||||
            ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
 | 
			
		||||
            ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
 | 
			
		||||
        ];
 | 
			
		||||
    });
 | 
			
		||||
    function buildSignedOrder(): SignedOrder {
 | 
			
		||||
        return { ecSignature: signature,
 | 
			
		||||
                 exchangeContractAddress: zeroAddress,
 | 
			
		||||
                 feeRecipient: zeroAddress,
 | 
			
		||||
                 maker: zeroAddress,
 | 
			
		||||
                 taker: zeroAddress,
 | 
			
		||||
                 makerFee: makerFeeAmount,
 | 
			
		||||
                 takerFee: zero,
 | 
			
		||||
                 makerTokenAmount: makerAmount,
 | 
			
		||||
                 takerTokenAmount: takerAmount,
 | 
			
		||||
                 makerTokenAddress: makerToken,
 | 
			
		||||
                 takerTokenAddress: takerToken,
 | 
			
		||||
                 salt: zero,
 | 
			
		||||
                 expirationUnixTimestampSec: zero };
 | 
			
		||||
        return {
 | 
			
		||||
            ecSignature: signature,
 | 
			
		||||
            exchangeContractAddress: zeroAddress,
 | 
			
		||||
            feeRecipient: zeroAddress,
 | 
			
		||||
            maker: zeroAddress,
 | 
			
		||||
            taker: zeroAddress,
 | 
			
		||||
            makerFee: makerFeeAmount,
 | 
			
		||||
            takerFee: zero,
 | 
			
		||||
            makerTokenAmount: makerAmount,
 | 
			
		||||
            takerTokenAmount: takerAmount,
 | 
			
		||||
            makerTokenAddress: makerToken,
 | 
			
		||||
            takerTokenAddress: takerToken,
 | 
			
		||||
            salt: zero,
 | 
			
		||||
            expirationUnixTimestampSec: zero,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    describe('Maker token is NOT ZRX', () => {
 | 
			
		||||
        before(async () => {
 | 
			
		||||
@@ -57,23 +62,38 @@ describe('RemainingFillableCalculator', () => {
 | 
			
		||||
        it('calculates the correct amount when unfilled and funds available', () => {
 | 
			
		||||
            signedOrder = buildSignedOrder();
 | 
			
		||||
            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
 | 
			
		||||
        });
 | 
			
		||||
        it('calculates the correct amount when partially filled and funds available', () => {
 | 
			
		||||
            signedOrder = buildSignedOrder();
 | 
			
		||||
            remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
 | 
			
		||||
        });
 | 
			
		||||
        it('calculates the amount to be 0 when all fee funds are transferred', () => {
 | 
			
		||||
            signedOrder = buildSignedOrder();
 | 
			
		||||
            transferrableMakerFeeTokenAmount = zero;
 | 
			
		||||
            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
 | 
			
		||||
        });
 | 
			
		||||
        it('calculates the correct amount when balance is less than remaining fillable', () => {
 | 
			
		||||
@@ -81,41 +101,58 @@ describe('RemainingFillableCalculator', () => {
 | 
			
		||||
            const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
 | 
			
		||||
            remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
 | 
			
		||||
            transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
 | 
			
		||||
        });
 | 
			
		||||
        describe('Order to Fee Ratio is < 1', () => {
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                [makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
 | 
			
		||||
                                                              ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
 | 
			
		||||
                                                              ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals)];
 | 
			
		||||
                [makerAmount, takerAmount, makerFeeAmount] = [
 | 
			
		||||
                    ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
 | 
			
		||||
                    ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
 | 
			
		||||
                    ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
 | 
			
		||||
                ];
 | 
			
		||||
            });
 | 
			
		||||
            it('calculates the correct amount when funds unavailable', () => {
 | 
			
		||||
                signedOrder = buildSignedOrder();
 | 
			
		||||
                remainingMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
                const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
 | 
			
		||||
                transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
 | 
			
		||||
                calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                                 transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount,
 | 
			
		||||
                                 remainingMakerTokenAmount);
 | 
			
		||||
                calculator = new RemainingFillableCalculator(
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    isMakerTokenZRX,
 | 
			
		||||
                    transferrableMakerTokenAmount,
 | 
			
		||||
                    transferrableMakerFeeTokenAmount,
 | 
			
		||||
                    remainingMakerTokenAmount,
 | 
			
		||||
                );
 | 
			
		||||
                expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        describe('Ratio is not evenly divisble', () => {
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                [makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
 | 
			
		||||
                                                              ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
 | 
			
		||||
                                                              ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals)];
 | 
			
		||||
                [makerAmount, takerAmount, makerFeeAmount] = [
 | 
			
		||||
                    ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
 | 
			
		||||
                    ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
 | 
			
		||||
                    ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
 | 
			
		||||
                ];
 | 
			
		||||
            });
 | 
			
		||||
            it('calculates the correct amount when funds unavailable', () => {
 | 
			
		||||
                signedOrder = buildSignedOrder();
 | 
			
		||||
                remainingMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
                const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
 | 
			
		||||
                transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
 | 
			
		||||
                calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                                 transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount,
 | 
			
		||||
                                 remainingMakerTokenAmount);
 | 
			
		||||
                calculator = new RemainingFillableCalculator(
 | 
			
		||||
                    signedOrder,
 | 
			
		||||
                    isMakerTokenZRX,
 | 
			
		||||
                    transferrableMakerTokenAmount,
 | 
			
		||||
                    transferrableMakerFeeTokenAmount,
 | 
			
		||||
                    remainingMakerTokenAmount,
 | 
			
		||||
                );
 | 
			
		||||
                const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
 | 
			
		||||
                expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
 | 
			
		||||
                expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
 | 
			
		||||
@@ -134,15 +171,25 @@ describe('RemainingFillableCalculator', () => {
 | 
			
		||||
            transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
 | 
			
		||||
            transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
 | 
			
		||||
            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
 | 
			
		||||
        });
 | 
			
		||||
        it('calculates the correct amount when partially filled and funds available', () => {
 | 
			
		||||
            signedOrder = buildSignedOrder();
 | 
			
		||||
            remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
 | 
			
		||||
        });
 | 
			
		||||
        it('calculates the amount to be 0 when all fee funds are transferred', () => {
 | 
			
		||||
@@ -150,8 +197,13 @@ describe('RemainingFillableCalculator', () => {
 | 
			
		||||
            transferrableMakerTokenAmount = zero;
 | 
			
		||||
            transferrableMakerFeeTokenAmount = zero;
 | 
			
		||||
            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
 | 
			
		||||
        });
 | 
			
		||||
        it('calculates the correct amount when balance is less than remaining fillable', () => {
 | 
			
		||||
@@ -163,8 +215,13 @@ describe('RemainingFillableCalculator', () => {
 | 
			
		||||
 | 
			
		||||
            const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
 | 
			
		||||
            const expectedFillableAmount = new BigNumber(450980);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
 | 
			
		||||
                           transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
 | 
			
		||||
            calculator = new RemainingFillableCalculator(
 | 
			
		||||
                signedOrder,
 | 
			
		||||
                isMakerTokenZRX,
 | 
			
		||||
                transferrableMakerTokenAmount,
 | 
			
		||||
                transferrableMakerFeeTokenAmount,
 | 
			
		||||
                remainingMakerTokenAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
 | 
			
		||||
            const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
 | 
			
		||||
            const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
@@ -6,19 +6,13 @@ import 'mocha';
 | 
			
		||||
import * as Sinon from 'sinon';
 | 
			
		||||
import * as Web3 from 'web3';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
    ApprovalContractEventArgs,
 | 
			
		||||
    DecodedLogEvent,
 | 
			
		||||
    Token,
 | 
			
		||||
    TokenEvents,
 | 
			
		||||
    ZeroEx,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {DoneCallback} from '../src/types';
 | 
			
		||||
import { ApprovalContractEventArgs, DecodedLogEvent, Token, TokenEvents, ZeroEx } from '../src';
 | 
			
		||||
import { DoneCallback } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {reportCallbackErrors} from './utils/report_callback_errors';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { reportCallbackErrors } from './utils/report_callback_errors';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -72,12 +66,8 @@ describe('SubscriptionTest', () => {
 | 
			
		||||
                        done();
 | 
			
		||||
                    },
 | 
			
		||||
                );
 | 
			
		||||
                stubs = [
 | 
			
		||||
                  Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
 | 
			
		||||
                   .throws(new Error(errMsg)),
 | 
			
		||||
                ];
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -91,24 +81,16 @@ describe('SubscriptionTest', () => {
 | 
			
		||||
                        done();
 | 
			
		||||
                    },
 | 
			
		||||
                );
 | 
			
		||||
                stubs = [
 | 
			
		||||
                  Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync')
 | 
			
		||||
                   .throws(new Error(errMsg)),
 | 
			
		||||
                ];
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                stubs = [
 | 
			
		||||
                  Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
 | 
			
		||||
                   .throws(new Error('JSON RPC error')),
 | 
			
		||||
                ];
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
 | 
			
		||||
                zeroEx.token.unsubscribeAll();
 | 
			
		||||
                done();
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import {schemas, SchemaValidator} from '@0xproject/json-schemas';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
 | 
			
		||||
import {Token, ZeroEx} from '../src';
 | 
			
		||||
import { Token, ZeroEx } from '../src';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -19,10 +19,10 @@ const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
 | 
			
		||||
describe('TokenRegistryWrapper', () => {
 | 
			
		||||
    let zeroEx: ZeroEx;
 | 
			
		||||
    let tokens: Token[];
 | 
			
		||||
    const tokenAddressBySymbol: {[symbol: string]: string} = {};
 | 
			
		||||
    const tokenAddressByName: {[symbol: string]: string} = {};
 | 
			
		||||
    const tokenBySymbol: {[symbol: string]: Token} = {};
 | 
			
		||||
    const tokenByName: {[symbol: string]: Token} = {};
 | 
			
		||||
    const tokenAddressBySymbol: { [symbol: string]: string } = {};
 | 
			
		||||
    const tokenAddressByName: { [symbol: string]: string } = {};
 | 
			
		||||
    const tokenBySymbol: { [symbol: string]: Token } = {};
 | 
			
		||||
    const tokenByName: { [symbol: string]: Token } = {};
 | 
			
		||||
    const registeredSymbol = 'ZRX';
 | 
			
		||||
    const registeredName = '0x Protocol Token';
 | 
			
		||||
    const unregisteredSymbol = 'MAL';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
 | 
			
		||||
import {ZeroEx} from '../src';
 | 
			
		||||
import { ZeroEx } from '../src';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
 | 
			
		||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
@@ -16,12 +16,12 @@ import {
 | 
			
		||||
    ZeroEx,
 | 
			
		||||
    ZeroExError,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {DoneCallback} from '../src/types';
 | 
			
		||||
import { DoneCallback } from '../src/types';
 | 
			
		||||
 | 
			
		||||
import {chaiSetup} from './utils/chai_setup';
 | 
			
		||||
import {constants} from './utils/constants';
 | 
			
		||||
import {TokenUtils} from './utils/token_utils';
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { constants } from './utils/constants';
 | 
			
		||||
import { TokenUtils } from './utils/token_utils';
 | 
			
		||||
import { web3Factory } from './utils/web3_factory';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -74,17 +74,17 @@ describe('TokenWrapper', () => {
 | 
			
		||||
        it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
 | 
			
		||||
            const fromAddress = addressWithoutFunds;
 | 
			
		||||
            const toAddress = coinbase;
 | 
			
		||||
            return expect(zeroEx.token.transferAsync(
 | 
			
		||||
                token.address, fromAddress, toAddress, transferAmount,
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
 | 
			
		||||
            const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
 | 
			
		||||
            const fromAddress = coinbase;
 | 
			
		||||
            const toAddress = coinbase;
 | 
			
		||||
            return expect(zeroEx.token.transferAsync(
 | 
			
		||||
                nonExistentTokenAddress, fromAddress, toAddress, transferAmount,
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#transferFromAsync', () => {
 | 
			
		||||
@@ -103,24 +103,22 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
 | 
			
		||||
            expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
 | 
			
		||||
 | 
			
		||||
            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress,
 | 
			
		||||
                                                                              toAddress);
 | 
			
		||||
            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
 | 
			
		||||
            expect(fromAddressAllowance).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
            return expect(zeroEx.token.transferFromAsync(
 | 
			
		||||
                token.address, fromAddress, toAddress, senderAddress, transferAmount,
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
 | 
			
		||||
        });
 | 
			
		||||
        it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress',
 | 
			
		||||
            async () => {
 | 
			
		||||
        it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
 | 
			
		||||
            const fromAddress = coinbase;
 | 
			
		||||
            const transferAmount = new BigNumber(42);
 | 
			
		||||
 | 
			
		||||
            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
 | 
			
		||||
 | 
			
		||||
            return expect(zeroEx.token.transferFromAsync(
 | 
			
		||||
                token.address, fromAddress, toAddress, senderAddress, transferAmount,
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
 | 
			
		||||
        });
 | 
			
		||||
        it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
 | 
			
		||||
            const fromAddress = addressWithoutFunds;
 | 
			
		||||
@@ -130,13 +128,16 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            expect(fromAddressBalance).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
 | 
			
		||||
            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress,
 | 
			
		||||
                                                                              senderAddress);
 | 
			
		||||
            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
 | 
			
		||||
                token.address,
 | 
			
		||||
                fromAddress,
 | 
			
		||||
                senderAddress,
 | 
			
		||||
            );
 | 
			
		||||
            expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
 | 
			
		||||
 | 
			
		||||
            return expect(zeroEx.token.transferFromAsync(
 | 
			
		||||
                token.address, fromAddress, toAddress, senderAddress, transferAmount,
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
 | 
			
		||||
        });
 | 
			
		||||
        it('should successfully transfer tokens', async () => {
 | 
			
		||||
            const fromAddress = coinbase;
 | 
			
		||||
@@ -147,17 +148,22 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            const transferAmount = new BigNumber(42);
 | 
			
		||||
            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
 | 
			
		||||
 | 
			
		||||
            await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress,
 | 
			
		||||
                                                 transferAmount);
 | 
			
		||||
            await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
 | 
			
		||||
            const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
 | 
			
		||||
            return expect(postBalance).to.be.bignumber.equal(transferAmount);
 | 
			
		||||
        });
 | 
			
		||||
        it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
 | 
			
		||||
            const fromAddress = coinbase;
 | 
			
		||||
            const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
 | 
			
		||||
            return expect(zeroEx.token.transferFromAsync(
 | 
			
		||||
                nonExistentTokenAddress, fromAddress, toAddress, senderAddress, new BigNumber(42),
 | 
			
		||||
            )).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
 | 
			
		||||
            return expect(
 | 
			
		||||
                zeroEx.token.transferFromAsync(
 | 
			
		||||
                    nonExistentTokenAddress,
 | 
			
		||||
                    fromAddress,
 | 
			
		||||
                    toAddress,
 | 
			
		||||
                    senderAddress,
 | 
			
		||||
                    new BigNumber(42),
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#getBalanceAsync', () => {
 | 
			
		||||
@@ -172,8 +178,9 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
 | 
			
		||||
                const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
 | 
			
		||||
                const ownerAddress = coinbase;
 | 
			
		||||
                return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress))
 | 
			
		||||
                    .to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
 | 
			
		||||
                return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
 | 
			
		||||
                    ZeroExError.TokenContractDoesNotExist,
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
            it('should return a balance of 0 for a non-existent owner address', async () => {
 | 
			
		||||
                const token = tokens[0];
 | 
			
		||||
@@ -191,22 +198,25 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
 | 
			
		||||
            });
 | 
			
		||||
            it('should return balance even when called with Web3 provider instance without addresses', async () => {
 | 
			
		||||
                    const token = tokens[0];
 | 
			
		||||
                    const ownerAddress = coinbase;
 | 
			
		||||
                    const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
 | 
			
		||||
                    const expectedBalance = new BigNumber('1000000000000000000000000000');
 | 
			
		||||
                    return expect(balance).to.be.bignumber.equal(expectedBalance);
 | 
			
		||||
                const token = tokens[0];
 | 
			
		||||
                const ownerAddress = coinbase;
 | 
			
		||||
                const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
 | 
			
		||||
                const expectedBalance = new BigNumber('1000000000000000000000000000');
 | 
			
		||||
                return expect(balance).to.be.bignumber.equal(expectedBalance);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#setAllowanceAsync', () => {
 | 
			
		||||
        it('should set the spender\'s allowance', async () => {
 | 
			
		||||
        it("should set the spender's allowance", async () => {
 | 
			
		||||
            const token = tokens[0];
 | 
			
		||||
            const ownerAddress = coinbase;
 | 
			
		||||
            const spenderAddress = addressWithoutFunds;
 | 
			
		||||
 | 
			
		||||
            const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress,
 | 
			
		||||
                                                                            spenderAddress);
 | 
			
		||||
            const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
 | 
			
		||||
                token.address,
 | 
			
		||||
                ownerAddress,
 | 
			
		||||
                spenderAddress,
 | 
			
		||||
            );
 | 
			
		||||
            const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
 | 
			
		||||
            expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
 | 
			
		||||
 | 
			
		||||
@@ -219,7 +229,7 @@ describe('TokenWrapper', () => {
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#setUnlimitedAllowanceAsync', () => {
 | 
			
		||||
        it('should set the unlimited spender\'s allowance', async () => {
 | 
			
		||||
        it("should set the unlimited spender's allowance", async () => {
 | 
			
		||||
            const token = tokens[0];
 | 
			
		||||
            const ownerAddress = coinbase;
 | 
			
		||||
            const spenderAddress = addressWithoutFunds;
 | 
			
		||||
@@ -241,10 +251,18 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            await zeroEx.token.transferFromAsync(
 | 
			
		||||
                zrx.address, coinbase, userWithNormalAllowance, userWithNormalAllowance, transferAmount,
 | 
			
		||||
                zrx.address,
 | 
			
		||||
                coinbase,
 | 
			
		||||
                userWithNormalAllowance,
 | 
			
		||||
                userWithNormalAllowance,
 | 
			
		||||
                transferAmount,
 | 
			
		||||
            );
 | 
			
		||||
            await zeroEx.token.transferFromAsync(
 | 
			
		||||
                zrx.address, coinbase, userWithUnlimitedAllowance, userWithUnlimitedAllowance, transferAmount,
 | 
			
		||||
                zrx.address,
 | 
			
		||||
                coinbase,
 | 
			
		||||
                userWithUnlimitedAllowance,
 | 
			
		||||
                userWithUnlimitedAllowance,
 | 
			
		||||
                transferAmount,
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
 | 
			
		||||
@@ -300,7 +318,9 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
 | 
			
		||||
 | 
			
		||||
                const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
 | 
			
		||||
                    token.address, ownerAddress, spenderAddress,
 | 
			
		||||
                    token.address,
 | 
			
		||||
                    ownerAddress,
 | 
			
		||||
                    spenderAddress,
 | 
			
		||||
                );
 | 
			
		||||
                const expectedAllowance = amountInBaseUnits;
 | 
			
		||||
                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
 | 
			
		||||
@@ -378,8 +398,7 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                    expect(args._value).to.be.bignumber.equal(transferAmount);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -394,8 +413,7 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                    expect(args._value).to.be.bignumber.equal(allowanceAmount);
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
 | 
			
		||||
                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -404,17 +422,13 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been cancelled'));
 | 
			
		||||
                };
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
 | 
			
		||||
                const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
 | 
			
		||||
                    done();
 | 
			
		||||
                };
 | 
			
		||||
                const newProvider = web3Factory.getRpcProvider();
 | 
			
		||||
                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 | 
			
		||||
                zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
            })().catch(done);
 | 
			
		||||
        });
 | 
			
		||||
@@ -424,7 +438,11 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been cancelled'));
 | 
			
		||||
                };
 | 
			
		||||
                const subscriptionToken = zeroEx.token.subscribe(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
 | 
			
		||||
                    tokenAddress,
 | 
			
		||||
                    TokenEvents.Transfer,
 | 
			
		||||
                    indexFilterValues,
 | 
			
		||||
                    callbackNeverToBeCalled,
 | 
			
		||||
                );
 | 
			
		||||
                zeroEx.token.unsubscribe(subscriptionToken);
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
                done();
 | 
			
		||||
@@ -450,7 +468,10 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            const eventName = TokenEvents.Approval;
 | 
			
		||||
            const indexFilterValues = {};
 | 
			
		||||
            const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
 | 
			
		||||
                tokenAddress, eventName, blockRange, indexFilterValues,
 | 
			
		||||
                tokenAddress,
 | 
			
		||||
                eventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(1);
 | 
			
		||||
            const args = logs[0].args;
 | 
			
		||||
@@ -465,7 +486,10 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            const differentEventName = TokenEvents.Transfer;
 | 
			
		||||
            const indexFilterValues = {};
 | 
			
		||||
            const logs = await zeroEx.token.getLogsAsync(
 | 
			
		||||
                tokenAddress, differentEventName, blockRange, indexFilterValues,
 | 
			
		||||
                tokenAddress,
 | 
			
		||||
                differentEventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(0);
 | 
			
		||||
        });
 | 
			
		||||
@@ -479,7 +503,10 @@ describe('TokenWrapper', () => {
 | 
			
		||||
                _owner: coinbase,
 | 
			
		||||
            };
 | 
			
		||||
            const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
 | 
			
		||||
                tokenAddress, eventName, blockRange, indexFilterValues,
 | 
			
		||||
                tokenAddress,
 | 
			
		||||
                eventName,
 | 
			
		||||
                blockRange,
 | 
			
		||||
                indexFilterValues,
 | 
			
		||||
            );
 | 
			
		||||
            expect(logs).to.have.length(1);
 | 
			
		||||
            const args = logs[0].args;
 | 
			
		||||
@@ -487,3 +514,4 @@ describe('TokenWrapper', () => {
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// tslint:disable:max-file-line-count
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
 | 
			
		||||
import {SignedOrder, Token, ZeroEx} from '../../src';
 | 
			
		||||
import {artifacts} from '../../src/artifacts';
 | 
			
		||||
import {DummyTokenContract} from '../../src/contract_wrappers/generated/dummy_token';
 | 
			
		||||
import {orderFactory} from '../utils/order_factory';
 | 
			
		||||
import { SignedOrder, Token, ZeroEx } from '../../src';
 | 
			
		||||
import { artifacts } from '../../src/artifacts';
 | 
			
		||||
import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token';
 | 
			
		||||
import { orderFactory } from '../utils/order_factory';
 | 
			
		||||
 | 
			
		||||
import {constants} from './constants';
 | 
			
		||||
import { constants } from './constants';
 | 
			
		||||
 | 
			
		||||
const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
 | 
			
		||||
 | 
			
		||||
@@ -17,8 +17,13 @@ export class FillScenarios {
 | 
			
		||||
    private _coinbase: string;
 | 
			
		||||
    private _zrxTokenAddress: string;
 | 
			
		||||
    private _exchangeContractAddress: string;
 | 
			
		||||
    constructor(zeroEx: ZeroEx, userAddresses: string[],
 | 
			
		||||
                tokens: Token[], zrxTokenAddress: string, exchangeContractAddress: string) {
 | 
			
		||||
    constructor(
 | 
			
		||||
        zeroEx: ZeroEx,
 | 
			
		||||
        userAddresses: string[],
 | 
			
		||||
        tokens: Token[],
 | 
			
		||||
        zrxTokenAddress: string,
 | 
			
		||||
        exchangeContractAddress: string,
 | 
			
		||||
    ) {
 | 
			
		||||
        this._zeroEx = zeroEx;
 | 
			
		||||
        this._userAddresses = userAddresses;
 | 
			
		||||
        this._tokens = tokens;
 | 
			
		||||
@@ -31,7 +36,8 @@ export class FillScenarios {
 | 
			
		||||
        for (const token of this._tokens) {
 | 
			
		||||
            if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
 | 
			
		||||
                const contractInstance = web3Wrapper.getContractInstance(
 | 
			
		||||
                    artifacts.DummyTokenArtifact.abi, token.address,
 | 
			
		||||
                    artifacts.DummyTokenArtifact.abi,
 | 
			
		||||
                    token.address,
 | 
			
		||||
                );
 | 
			
		||||
                const defaults = {};
 | 
			
		||||
                const dummyToken = new DummyTokenContract(contractInstance, defaults);
 | 
			
		||||
@@ -43,61 +49,110 @@ export class FillScenarios {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public async createFillableSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
 | 
			
		||||
                                                makerAddress: string, takerAddress: string,
 | 
			
		||||
                                                fillableAmount: BigNumber,
 | 
			
		||||
                                                expirationUnixTimestampSec?: BigNumber):
 | 
			
		||||
                                           Promise<SignedOrder> {
 | 
			
		||||
    public async createFillableSignedOrderAsync(
 | 
			
		||||
        makerTokenAddress: string,
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        makerAddress: string,
 | 
			
		||||
        takerAddress: string,
 | 
			
		||||
        fillableAmount: BigNumber,
 | 
			
		||||
        expirationUnixTimestampSec?: BigNumber,
 | 
			
		||||
    ): Promise<SignedOrder> {
 | 
			
		||||
        return this.createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
            makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
            fillableAmount, fillableAmount, expirationUnixTimestampSec,
 | 
			
		||||
            makerTokenAddress,
 | 
			
		||||
            takerTokenAddress,
 | 
			
		||||
            makerAddress,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
            fillableAmount,
 | 
			
		||||
            fillableAmount,
 | 
			
		||||
            expirationUnixTimestampSec,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    public async createFillableSignedOrderWithFeesAsync(
 | 
			
		||||
        makerTokenAddress: string, takerTokenAddress: string,
 | 
			
		||||
        makerFee: BigNumber, takerFee: BigNumber,
 | 
			
		||||
        makerAddress: string, takerAddress: string,
 | 
			
		||||
        makerTokenAddress: string,
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        makerFee: BigNumber,
 | 
			
		||||
        takerFee: BigNumber,
 | 
			
		||||
        makerAddress: string,
 | 
			
		||||
        takerAddress: string,
 | 
			
		||||
        fillableAmount: BigNumber,
 | 
			
		||||
        feeRecepient: string, expirationUnixTimestampSec?: BigNumber,
 | 
			
		||||
        feeRecepient: string,
 | 
			
		||||
        expirationUnixTimestampSec?: BigNumber,
 | 
			
		||||
    ): Promise<SignedOrder> {
 | 
			
		||||
        return this._createAsymmetricFillableSignedOrderWithFeesAsync(
 | 
			
		||||
            makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
 | 
			
		||||
            fillableAmount, fillableAmount, feeRecepient, expirationUnixTimestampSec,
 | 
			
		||||
            makerTokenAddress,
 | 
			
		||||
            takerTokenAddress,
 | 
			
		||||
            makerFee,
 | 
			
		||||
            takerFee,
 | 
			
		||||
            makerAddress,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
            fillableAmount,
 | 
			
		||||
            fillableAmount,
 | 
			
		||||
            feeRecepient,
 | 
			
		||||
            expirationUnixTimestampSec,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    public async createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
        makerTokenAddress: string, takerTokenAddress: string, makerAddress: string, takerAddress: string,
 | 
			
		||||
        makerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
 | 
			
		||||
        expirationUnixTimestampSec?: BigNumber): Promise<SignedOrder> {
 | 
			
		||||
        makerTokenAddress: string,
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        makerAddress: string,
 | 
			
		||||
        takerAddress: string,
 | 
			
		||||
        makerFillableAmount: BigNumber,
 | 
			
		||||
        takerFillableAmount: BigNumber,
 | 
			
		||||
        expirationUnixTimestampSec?: BigNumber,
 | 
			
		||||
    ): Promise<SignedOrder> {
 | 
			
		||||
        const makerFee = new BigNumber(0);
 | 
			
		||||
        const takerFee = new BigNumber(0);
 | 
			
		||||
        const feeRecepient = constants.NULL_ADDRESS;
 | 
			
		||||
        return this._createAsymmetricFillableSignedOrderWithFeesAsync(
 | 
			
		||||
            makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
 | 
			
		||||
            makerFillableAmount, takerFillableAmount, feeRecepient, expirationUnixTimestampSec,
 | 
			
		||||
            makerTokenAddress,
 | 
			
		||||
            takerTokenAddress,
 | 
			
		||||
            makerFee,
 | 
			
		||||
            takerFee,
 | 
			
		||||
            makerAddress,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
            makerFillableAmount,
 | 
			
		||||
            takerFillableAmount,
 | 
			
		||||
            feeRecepient,
 | 
			
		||||
            expirationUnixTimestampSec,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    public async createPartiallyFilledSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
 | 
			
		||||
                                                       takerAddress: string, fillableAmount: BigNumber,
 | 
			
		||||
                                                       partialFillAmount: BigNumber) {
 | 
			
		||||
    public async createPartiallyFilledSignedOrderAsync(
 | 
			
		||||
        makerTokenAddress: string,
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        takerAddress: string,
 | 
			
		||||
        fillableAmount: BigNumber,
 | 
			
		||||
        partialFillAmount: BigNumber,
 | 
			
		||||
    ) {
 | 
			
		||||
        const [makerAddress] = this._userAddresses;
 | 
			
		||||
        const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
 | 
			
		||||
            makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
 | 
			
		||||
            fillableAmount, fillableAmount,
 | 
			
		||||
            makerTokenAddress,
 | 
			
		||||
            takerTokenAddress,
 | 
			
		||||
            makerAddress,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
            fillableAmount,
 | 
			
		||||
            fillableAmount,
 | 
			
		||||
        );
 | 
			
		||||
        const shouldThrowOnInsufficientBalanceOrAllowance = false;
 | 
			
		||||
        await this._zeroEx.exchange.fillOrderAsync(
 | 
			
		||||
            signedOrder, partialFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
 | 
			
		||||
            signedOrder,
 | 
			
		||||
            partialFillAmount,
 | 
			
		||||
            shouldThrowOnInsufficientBalanceOrAllowance,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
        );
 | 
			
		||||
        return signedOrder;
 | 
			
		||||
    }
 | 
			
		||||
    private async _createAsymmetricFillableSignedOrderWithFeesAsync(
 | 
			
		||||
        makerTokenAddress: string, takerTokenAddress: string,
 | 
			
		||||
        makerFee: BigNumber, takerFee: BigNumber,
 | 
			
		||||
        makerAddress: string, takerAddress: string,
 | 
			
		||||
        makerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
 | 
			
		||||
        feeRecepient: string, expirationUnixTimestampSec?: BigNumber): Promise<SignedOrder> {
 | 
			
		||||
 | 
			
		||||
        makerTokenAddress: string,
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        makerFee: BigNumber,
 | 
			
		||||
        takerFee: BigNumber,
 | 
			
		||||
        makerAddress: string,
 | 
			
		||||
        takerAddress: string,
 | 
			
		||||
        makerFillableAmount: BigNumber,
 | 
			
		||||
        takerFillableAmount: BigNumber,
 | 
			
		||||
        feeRecepient: string,
 | 
			
		||||
        expirationUnixTimestampSec?: BigNumber,
 | 
			
		||||
    ): Promise<SignedOrder> {
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
            this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
 | 
			
		||||
            this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
 | 
			
		||||
@@ -107,14 +162,27 @@ export class FillScenarios {
 | 
			
		||||
            this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        const signedOrder = await orderFactory.createSignedOrderAsync(this._zeroEx,
 | 
			
		||||
            makerAddress, takerAddress, makerFee, takerFee,
 | 
			
		||||
            makerFillableAmount, makerTokenAddress, takerFillableAmount, takerTokenAddress,
 | 
			
		||||
            this._exchangeContractAddress, feeRecepient, expirationUnixTimestampSec);
 | 
			
		||||
        const signedOrder = await orderFactory.createSignedOrderAsync(
 | 
			
		||||
            this._zeroEx,
 | 
			
		||||
            makerAddress,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
            makerFee,
 | 
			
		||||
            takerFee,
 | 
			
		||||
            makerFillableAmount,
 | 
			
		||||
            makerTokenAddress,
 | 
			
		||||
            takerFillableAmount,
 | 
			
		||||
            takerTokenAddress,
 | 
			
		||||
            this._exchangeContractAddress,
 | 
			
		||||
            feeRecepient,
 | 
			
		||||
            expirationUnixTimestampSec,
 | 
			
		||||
        );
 | 
			
		||||
        return signedOrder;
 | 
			
		||||
    }
 | 
			
		||||
    private async _increaseBalanceAndAllowanceAsync(
 | 
			
		||||
        tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
 | 
			
		||||
        tokenAddress: string,
 | 
			
		||||
        address: string,
 | 
			
		||||
        amount: BigNumber,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
 | 
			
		||||
            return; // noop
 | 
			
		||||
        }
 | 
			
		||||
@@ -123,16 +191,12 @@ export class FillScenarios {
 | 
			
		||||
            this._increaseAllowanceAsync(tokenAddress, address, amount),
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
    private async _increaseBalanceAsync(
 | 
			
		||||
        tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
 | 
			
		||||
    private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
 | 
			
		||||
        await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
 | 
			
		||||
    }
 | 
			
		||||
    private async _increaseAllowanceAsync(
 | 
			
		||||
        tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
 | 
			
		||||
    private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
 | 
			
		||||
        const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
 | 
			
		||||
        const newMakerAllowance = oldMakerAllowance.plus(amount);
 | 
			
		||||
        await this._zeroEx.token.setProxyAllowanceAsync(
 | 
			
		||||
            tokenAddress, address, newMakerAllowance,
 | 
			
		||||
        );
 | 
			
		||||
        await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import {SignedOrder, ZeroEx} from '../../src';
 | 
			
		||||
import { SignedOrder, ZeroEx } from '../../src';
 | 
			
		||||
 | 
			
		||||
export const orderFactory = {
 | 
			
		||||
    async createSignedOrderAsync(
 | 
			
		||||
@@ -16,11 +16,12 @@ export const orderFactory = {
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        exchangeContractAddress: string,
 | 
			
		||||
        feeRecipient: string,
 | 
			
		||||
        expirationUnixTimestampSecIfExists?: BigNumber): Promise<SignedOrder> {
 | 
			
		||||
        expirationUnixTimestampSecIfExists?: BigNumber,
 | 
			
		||||
    ): Promise<SignedOrder> {
 | 
			
		||||
        const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
 | 
			
		||||
        const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists) ?
 | 
			
		||||
            defaultExpirationUnixTimestampSec :
 | 
			
		||||
            expirationUnixTimestampSecIfExists;
 | 
			
		||||
        const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
 | 
			
		||||
            ? defaultExpirationUnixTimestampSec
 | 
			
		||||
            : expirationUnixTimestampSecIfExists;
 | 
			
		||||
        const order = {
 | 
			
		||||
            maker,
 | 
			
		||||
            taker,
 | 
			
		||||
@@ -37,7 +38,7 @@ export const orderFactory = {
 | 
			
		||||
        };
 | 
			
		||||
        const orderHash = ZeroEx.getOrderHashHex(order);
 | 
			
		||||
        const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker);
 | 
			
		||||
        const signedOrder: SignedOrder = _.assign(order, {ecSignature});
 | 
			
		||||
        const signedOrder: SignedOrder = _.assign(order, { ecSignature });
 | 
			
		||||
        return signedOrder;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {DoneCallback} from '../../src/types';
 | 
			
		||||
import { DoneCallback } from '../../src/types';
 | 
			
		||||
 | 
			
		||||
export const reportCallbackErrors = (done: DoneCallback) => {
 | 
			
		||||
    return (f: (...args: any[]) => void) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {JSONRPCPayload} from '../../../src/types';
 | 
			
		||||
import { JSONRPCPayload } from '../../../src/types';
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This class implements the web3-provider-engine subprovider interface and returns
 | 
			
		||||
@@ -8,7 +8,7 @@ import {JSONRPCPayload} from '../../../src/types';
 | 
			
		||||
export class EmptyWalletSubprovider {
 | 
			
		||||
    // This method needs to be here to satisfy the interface but linter wants it to be static.
 | 
			
		||||
    // tslint:disable-next-line:prefer-function-over-method
 | 
			
		||||
    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
 | 
			
		||||
    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
 | 
			
		||||
        switch (payload.method) {
 | 
			
		||||
            case 'eth_accounts':
 | 
			
		||||
                end(null, []);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {JSONRPCPayload} from '../../../src/types';
 | 
			
		||||
import { JSONRPCPayload } from '../../../src/types';
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This class implements the web3-provider-engine subprovider interface and returns
 | 
			
		||||
@@ -15,7 +15,7 @@ export class FakeGasEstimateSubprovider {
 | 
			
		||||
    }
 | 
			
		||||
    // This method needs to be here to satisfy the interface but linter wants it to be static.
 | 
			
		||||
    // tslint:disable-next-line:prefer-function-over-method
 | 
			
		||||
    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
 | 
			
		||||
    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
 | 
			
		||||
        switch (payload.method) {
 | 
			
		||||
            case 'eth_estimateGas':
 | 
			
		||||
                end(null, this._constantGasAmount);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import {InternalZeroExError, Token} from '../../src/types';
 | 
			
		||||
import { InternalZeroExError, Token } from '../../src/types';
 | 
			
		||||
 | 
			
		||||
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
 | 
			
		||||
const WETH_TOKEN_SYMBOL = 'WETH';
 | 
			
		||||
@@ -11,14 +11,14 @@ export class TokenUtils {
 | 
			
		||||
        this._tokens = tokens;
 | 
			
		||||
    }
 | 
			
		||||
    public getProtocolTokenOrThrow(): Token {
 | 
			
		||||
        const zrxToken = _.find(this._tokens, {symbol: PROTOCOL_TOKEN_SYMBOL});
 | 
			
		||||
        const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
 | 
			
		||||
        if (_.isUndefined(zrxToken)) {
 | 
			
		||||
            throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
 | 
			
		||||
        }
 | 
			
		||||
        return zrxToken;
 | 
			
		||||
    }
 | 
			
		||||
    public getWethTokenOrThrow(): Token {
 | 
			
		||||
        const wethToken = _.find(this._tokens, {symbol: WETH_TOKEN_SYMBOL});
 | 
			
		||||
        const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
 | 
			
		||||
        if (_.isUndefined(wethToken)) {
 | 
			
		||||
            throw new Error(InternalZeroExError.WethNotInTokenRegistry);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,10 @@
 | 
			
		||||
import ProviderEngine = require('web3-provider-engine');
 | 
			
		||||
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
 | 
			
		||||
 | 
			
		||||
import {EmptyWalletSubprovider} from './subproviders/empty_wallet_subprovider';
 | 
			
		||||
import {FakeGasEstimateSubprovider} from './subproviders/fake_gas_estimate_subprovider';
 | 
			
		||||
import { EmptyWalletSubprovider } from './subproviders/empty_wallet_subprovider';
 | 
			
		||||
import { FakeGasEstimateSubprovider } from './subproviders/fake_gas_estimate_subprovider';
 | 
			
		||||
 | 
			
		||||
import {constants} from './constants';
 | 
			
		||||
import { constants } from './constants';
 | 
			
		||||
 | 
			
		||||
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
 | 
			
		||||
// because they are using the wrong XHR package.
 | 
			
		||||
@@ -31,9 +31,11 @@ export const web3Factory = {
 | 
			
		||||
            provider.addProvider(new EmptyWalletSubprovider());
 | 
			
		||||
        }
 | 
			
		||||
        provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
 | 
			
		||||
        provider.addProvider(new RpcSubprovider({
 | 
			
		||||
            rpcUrl: constants.RPC_URL,
 | 
			
		||||
        }));
 | 
			
		||||
        provider.addProvider(
 | 
			
		||||
            new RpcSubprovider({
 | 
			
		||||
                rpcUrl: constants.RPC_URL,
 | 
			
		||||
            }),
 | 
			
		||||
        );
 | 
			
		||||
        provider.start();
 | 
			
		||||
        return provider;
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user