aboutsummaryrefslogtreecommitdiffstats
path: root/packages/0x.js/test
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-01-25 23:42:58 +0800
committerFabio Berger <me@fabioberger.com>2018-01-25 23:42:58 +0800
commit71d68f975cd7bc089f0cbef4e5888a73eab4ee42 (patch)
tree9482602fc23d2baec3fff1fb97750ad45adc6eca /packages/0x.js/test
parentec3d8a034fe763d8255935985b1fb97aff6c177b (diff)
parentf58f0ddb67555c3f0c7252ea3e003824984c48ad (diff)
downloaddexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.tar
dexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.tar.gz
dexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.tar.bz2
dexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.tar.lz
dexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.tar.xz
dexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.tar.zst
dexon-sol-tools-71d68f975cd7bc089f0cbef4e5888a73eab4ee42.zip
Merge branch 'development' into feature/portal-ledger-support
* development: (437 commits) Publish Update yarn.lock Update the CHANGELOG Fix the bug making it impossible to specify the custom ZRX address Fix fill/cancel order by looking for NoError instead of empty blockchainErr given the BlockchainErrs type refactor Add a comment about a yarn bug Add our mainnet and kovan nodes as backups for Portal requests Fix bug hiding the user info from topBar Add dev-utils package to top level README Prettier newline Prettier Allow Token symbols to be alphanumeric Update CHANGELOG, rebase on development Should not -> cannot Reject negative amounts in isValidBaseUnitAmount Re-add changelog for 0x.js Fix prettier Update yarn.lock Move tests to a separate folder Change file layout ... # Conflicts: # packages/website/README.md
Diffstat (limited to 'packages/0x.js/test')
-rw-r--r--packages/0x.js/test/0x.js_test.ts93
-rw-r--r--packages/0x.js/test/artifacts_test.ts8
-rw-r--r--packages/0x.js/test/assert_test.ts29
-rw-r--r--packages/0x.js/test/ether_token_wrapper_test.ts286
-rw-r--r--packages/0x.js/test/event_watcher_test.ts34
-rw-r--r--packages/0x.js/test/exchange_transfer_simulator_test.ts68
-rw-r--r--packages/0x.js/test/exchange_wrapper_test.ts755
-rw-r--r--packages/0x.js/test/expiration_watcher_test.ts66
-rw-r--r--packages/0x.js/test/order_state_watcher_test.ts290
-rw-r--r--packages/0x.js/test/order_validation_test.ts381
-rw-r--r--packages/0x.js/test/remaining_fillable_calculator_test.ts154
-rw-r--r--packages/0x.js/test/subscription_test.ts74
-rw-r--r--packages/0x.js/test/token_registry_wrapper_test.ts22
-rw-r--r--packages/0x.js/test/token_transfer_proxy_wrapper_test.ts9
-rw-r--r--packages/0x.js/test/token_wrapper_test.ts230
-rw-r--r--packages/0x.js/test/utils/blockchain_lifecycle.ts26
-rw-r--r--packages/0x.js/test/utils/constants.ts7
-rw-r--r--packages/0x.js/test/utils/fill_scenarios.ts234
-rw-r--r--packages/0x.js/test/utils/order_factory.ts15
-rw-r--r--packages/0x.js/test/utils/report_callback_errors.ts60
-rw-r--r--packages/0x.js/test/utils/rpc.ts58
-rw-r--r--packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts4
-rw-r--r--packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts10
-rw-r--r--packages/0x.js/test/utils/token_utils.ts24
-rw-r--r--packages/0x.js/test/utils/web3_factory.ts23
25 files changed, 1957 insertions, 1003 deletions
diff --git a/packages/0x.js/test/0x.js_test.ts b/packages/0x.js/test/0x.js_test.ts
index 6b7a70699..5bc2c149c 100644
--- a/packages/0x.js/test/0x.js_test.ts
+++ b/packages/0x.js/test/0x.js_test.ts
@@ -1,18 +1,18 @@
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'mocha';
import * as Sinon from 'sinon';
-import {ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx, ZeroExError} from '../src';
+import { ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx } from '../src';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
chaiSetup.configure();
const expect = chai.expect;
@@ -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),
@@ -82,9 +85,9 @@ describe('ZeroEx library', () => {
it('should return true if the signature does pertain to the dataHex & address', async () => {
const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
expect(isValidSignatureLocal).to.be.true();
- const isValidSignatureOnContract = await (zeroEx.exchange as any)
- ._isValidSignatureUsingContractCallAsync(dataHex, signature, address);
- return expect(isValidSignatureOnContract).to.be.true();
+ return expect(
+ (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
+ ).to.become(true);
});
});
describe('#generateSalt', () => {
@@ -114,6 +117,13 @@ describe('ZeroEx library', () => {
});
});
describe('#toUnitAmount', () => {
+ 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',
+ );
+ });
it('Should return the expected unit amount for the decimals passed in', () => {
const baseUnitAmount = new BigNumber(1000000000);
const decimals = 6;
@@ -130,6 +140,13 @@ describe('ZeroEx library', () => {
const expectedUnitAmount = new BigNumber(1000000000);
expect(baseUnitAmount).to.be.bignumber.equal(expectedUnitAmount);
});
+ 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',
+ );
+ });
});
describe('#getOrderHashHex', () => {
const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
@@ -152,6 +169,15 @@ describe('ZeroEx library', () => {
const orderHash = ZeroEx.getOrderHashHex(order);
expect(orderHash).to.be.equal(expectedOrderHash);
});
+ it('throws a readable error message if taker format is invalid', async () => {
+ const orderWithInvalidtakerFormat = {
+ ...order,
+ taker: (null as any) as string,
+ };
+ 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);
+ });
});
describe('#signOrderHashAsync', () => {
let stubs: Sinon.SinonStub[] = [];
@@ -177,16 +203,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),
];
@@ -195,16 +220,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),
];
@@ -244,22 +268,15 @@ describe('ZeroEx library', () => {
const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
});
- it('allows to specify ether token contract address', async () => {
- const zeroExConfig = {
- etherTokenContractAddress: ZeroEx.NULL_ADDRESS,
- networkId: constants.TESTRPC_NETWORK_ID,
- };
- const zeroExWithWrongEtherTokenAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
- expect(zeroExWithWrongEtherTokenAddress.etherToken.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
- });
it('allows to specify token registry token contract address', async () => {
const zeroExConfig = {
tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
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,
+ );
});
});
});
diff --git a/packages/0x.js/test/artifacts_test.ts b/packages/0x.js/test/artifacts_test.ts
index f4599a24d..e8ab9aa97 100644
--- a/packages/0x.js/test/artifacts_test.ts
+++ b/packages/0x.js/test/artifacts_test.ts
@@ -1,14 +1,12 @@
-import * as chai from 'chai';
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();
-const expect = chai.expect;
// Those tests are slower cause they're talking to a remote node
const TIMEOUT = 10000;
diff --git a/packages/0x.js/test/assert_test.ts b/packages/0x.js/test/assert_test.ts
index 9fa7f780f..1f2820070 100644
--- a/packages/0x.js/test/assert_test.ts
+++ b/packages/0x.js/test/assert_test.ts
@@ -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);
});
});
});
diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts
index d3e4439ee..b810fc9f1 100644
--- a/packages/0x.js/test/ether_token_wrapper_test.ts
+++ b/packages/0x.js/test/ether_token_wrapper_test.ts
@@ -1,18 +1,34 @@
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'mocha';
import * as Web3 from 'web3';
-import {ZeroEx, ZeroExError} from '../src';
+import {
+ ApprovalContractEventArgs,
+ BlockParamLiteral,
+ BlockRange,
+ DecodedLogEvent,
+ DepositContractEventArgs,
+ EtherTokenEvents,
+ Token,
+ TransferContractEventArgs,
+ WithdrawalContractEventArgs,
+ ZeroEx,
+ ZeroExError,
+} from '../src';
+import { artifacts } from '../src/artifacts';
+import { DoneCallback } from '../src/types';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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 { reportNodeCallbackErrors } from './utils/report_callback_errors';
+import { TokenUtils } from './utils/token_utils';
+import { web3Factory } from './utils/web3_factory';
chaiSetup.configure();
const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
// Since the address depositing/withdrawing ETH/WETH also needs to pay gas costs for the transaction,
// a small amount of ETH will be used to pay this gas cost. We therefore check that the difference between
@@ -23,24 +39,32 @@ const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
describe('EtherTokenWrapper', () => {
let web3: Web3;
let zeroEx: ZeroEx;
+ let tokens: Token[];
let userAddresses: string[];
let addressWithETH: string;
let wethContractAddress: string;
let depositWeiAmount: BigNumber;
let decimalPlaces: number;
+ let addressWithoutFunds: string;
const gasPrice = new BigNumber(1);
const zeroExConfig = {
gasPrice,
networkId: constants.TESTRPC_NETWORK_ID,
};
+ const transferAmount = new BigNumber(42);
+ const allowanceAmount = new BigNumber(42);
+ const depositAmount = new BigNumber(42);
+ const withdrawalAmount = new BigNumber(42);
before(async () => {
web3 = web3Factory.create();
zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
+ tokens = await zeroEx.tokenRegistry.getTokensAsync();
userAddresses = await zeroEx.getAvailableAddressesAsync();
addressWithETH = userAddresses[0];
- wethContractAddress = zeroEx.etherToken.getContractAddress();
+ wethContractAddress = (zeroEx.etherToken as any)._getContractAddress(artifacts.EtherTokenArtifact);
depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5));
decimalPlaces = 7;
+ addressWithoutFunds = userAddresses[1];
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -55,7 +79,7 @@ describe('EtherTokenWrapper', () => {
expect(preETHBalance).to.be.bignumber.gt(0);
expect(preWETHBalance).to.be.bignumber.equal(0);
- const txHash = await zeroEx.etherToken.depositAsync(depositWeiAmount, addressWithETH);
+ const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
@@ -73,7 +97,7 @@ describe('EtherTokenWrapper', () => {
const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
return expect(
- zeroEx.etherToken.depositAsync(overETHBalanceinWei, addressWithETH),
+ zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
});
});
@@ -81,7 +105,7 @@ describe('EtherTokenWrapper', () => {
it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
- await zeroEx.etherToken.depositAsync(depositWeiAmount, addressWithETH);
+ await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
@@ -90,7 +114,7 @@ describe('EtherTokenWrapper', () => {
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
- const txHash = await zeroEx.etherToken.withdrawAsync(depositWeiAmount, addressWithETH);
+ const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
@@ -108,8 +132,244 @@ describe('EtherTokenWrapper', () => {
const overWETHBalance = preWETHBalance.add(999999999);
return expect(
- zeroEx.etherToken.withdrawAsync(overWETHBalance, addressWithETH),
+ zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
});
});
+ describe('#subscribe', () => {
+ const indexFilterValues = {};
+ let etherTokenAddress: string;
+ before(() => {
+ const tokenUtils = new TokenUtils(tokens);
+ const etherToken = tokenUtils.getWethTokenOrThrow();
+ etherTokenAddress = etherToken.address;
+ });
+ afterEach(() => {
+ zeroEx.etherToken.unsubscribeAll();
+ });
+ // Hack: Mocha does not allow a test to be both async and have a `done` callback
+ // Since we need to await the receipt of the event in the `subscribe` callback,
+ // we do need both. A hack is to make the top-level async fn w/ a done callback and then
+ // wrap the rest of the test in an async block
+ // Source: https://github.com/mochajs/mocha/issues/2407
+ it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
+ (async () => {
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+ expect(logEvent).to.not.be.undefined();
+ expect(logEvent.isRemoved).to.be.false();
+ expect(logEvent.log.logIndex).to.be.equal(0);
+ expect(logEvent.log.transactionIndex).to.be.equal(0);
+ expect(logEvent.log.blockNumber).to.be.a('number');
+ const args = logEvent.log.args;
+ expect(args._from).to.be.equal(addressWithETH);
+ expect(args._to).to.be.equal(addressWithoutFunds);
+ expect(args._value).to.be.bignumber.equal(transferAmount);
+ },
+ );
+ await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+ zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
+ await zeroEx.token.transferAsync(
+ etherTokenAddress,
+ addressWithETH,
+ addressWithoutFunds,
+ transferAmount,
+ );
+ })().catch(done);
+ });
+ it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
+ (async () => {
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ expect(logEvent).to.not.be.undefined();
+ expect(logEvent.isRemoved).to.be.false();
+ const args = logEvent.log.args;
+ expect(args._owner).to.be.equal(addressWithETH);
+ expect(args._spender).to.be.equal(addressWithoutFunds);
+ expect(args._value).to.be.bignumber.equal(allowanceAmount);
+ },
+ );
+ zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
+ await zeroEx.token.setAllowanceAsync(
+ etherTokenAddress,
+ addressWithETH,
+ addressWithoutFunds,
+ allowanceAmount,
+ );
+ })().catch(done);
+ });
+ it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
+ (async () => {
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
+ expect(logEvent).to.not.be.undefined();
+ expect(logEvent.isRemoved).to.be.false();
+ const args = logEvent.log.args;
+ expect(args._owner).to.be.equal(addressWithETH);
+ expect(args._value).to.be.bignumber.equal(depositAmount);
+ },
+ );
+ 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) => {
+ (async () => {
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
+ expect(logEvent).to.not.be.undefined();
+ expect(logEvent.isRemoved).to.be.false();
+ const args = logEvent.log.args;
+ expect(args._owner).to.be.equal(addressWithETH);
+ expect(args._value).to.be.bignumber.equal(depositAmount);
+ },
+ );
+ await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+ zeroEx.etherToken.subscribe(
+ 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) => {
+ (async () => {
+ const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ done(new Error('Expected this subscription to have been cancelled'));
+ },
+ );
+ zeroEx.etherToken.subscribe(
+ etherTokenAddress,
+ EtherTokenEvents.Transfer,
+ indexFilterValues,
+ callbackNeverToBeCalled,
+ );
+ const callbackToBeCalled = reportNodeCallbackErrors(done)();
+ const newProvider = web3Factory.getRpcProvider();
+ zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+ await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+ zeroEx.etherToken.subscribe(
+ etherTokenAddress,
+ EtherTokenEvents.Transfer,
+ indexFilterValues,
+ callbackToBeCalled,
+ );
+ await zeroEx.token.transferAsync(
+ etherTokenAddress,
+ addressWithETH,
+ addressWithoutFunds,
+ transferAmount,
+ );
+ })().catch(done);
+ });
+ it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+ (async () => {
+ const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ done(new Error('Expected this subscription to have been cancelled'));
+ },
+ );
+ await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+ const subscriptionToken = zeroEx.etherToken.subscribe(
+ etherTokenAddress,
+ EtherTokenEvents.Transfer,
+ indexFilterValues,
+ callbackNeverToBeCalled,
+ );
+ zeroEx.etherToken.unsubscribe(subscriptionToken);
+ await zeroEx.token.transferAsync(
+ etherTokenAddress,
+ addressWithETH,
+ addressWithoutFunds,
+ transferAmount,
+ );
+ done();
+ })().catch(done);
+ });
+ });
+ describe('#getLogsAsync', () => {
+ let etherTokenAddress: string;
+ let tokenTransferProxyAddress: string;
+ const blockRange: BlockRange = {
+ fromBlock: 0,
+ toBlock: BlockParamLiteral.Latest,
+ };
+ let txHash: string;
+ before(() => {
+ addressWithETH = userAddresses[0];
+ const tokenUtils = new TokenUtils(tokens);
+ const etherToken = tokenUtils.getWethTokenOrThrow();
+ etherTokenAddress = etherToken.address;
+ tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
+ });
+ it('should get logs with decoded args emitted by Approval', async () => {
+ txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+ await zeroEx.awaitTransactionMinedAsync(txHash);
+ const eventName = EtherTokenEvents.Approval;
+ const indexFilterValues = {};
+ const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+ etherTokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(1);
+ const args = logs[0].args;
+ expect(logs[0].event).to.be.equal(eventName);
+ expect(args._owner).to.be.equal(addressWithETH);
+ expect(args._spender).to.be.equal(tokenTransferProxyAddress);
+ expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+ });
+ it('should get logs with decoded args emitted by Deposit', async () => {
+ await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+ const eventName = EtherTokenEvents.Deposit;
+ const indexFilterValues = {};
+ const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
+ etherTokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(1);
+ const args = logs[0].args;
+ expect(logs[0].event).to.be.equal(eventName);
+ expect(args._owner).to.be.equal(addressWithETH);
+ expect(args._value).to.be.bignumber.equal(depositAmount);
+ });
+ it('should only get the logs with the correct event name', async () => {
+ txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+ await zeroEx.awaitTransactionMinedAsync(txHash);
+ const differentEventName = EtherTokenEvents.Transfer;
+ const indexFilterValues = {};
+ const logs = await zeroEx.etherToken.getLogsAsync(
+ etherTokenAddress,
+ differentEventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(0);
+ });
+ it('should only get the logs with the correct indexed fields', async () => {
+ txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+ await zeroEx.awaitTransactionMinedAsync(txHash);
+ txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithoutFunds);
+ await zeroEx.awaitTransactionMinedAsync(txHash);
+ const eventName = EtherTokenEvents.Approval;
+ const indexFilterValues = {
+ _owner: addressWithETH,
+ };
+ const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+ etherTokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(1);
+ const args = logs[0].args;
+ expect(args._owner).to.be.equal(addressWithETH);
+ });
+ });
});
diff --git a/packages/0x.js/test/event_watcher_test.ts b/packages/0x.js/test/event_watcher_test.ts
index 3d92c62a3..f92fb2b02 100644
--- a/packages/0x.js/test/event_watcher_test.ts
+++ b/packages/0x.js/test/event_watcher_test.ts
@@ -1,22 +1,17 @@
-import {Web3Wrapper} from '@0xproject/web3-wrapper';
-import BigNumber from 'bignumber.js';
+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 {
- DecodedLogEvent,
- LogEvent,
- ZeroEx,
-} 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 {constants} from './utils/constants';
-import {web3Factory} from './utils/web3_factory';
+import { chaiSetup } from './utils/chai_setup';
+import { reportNodeCallbackErrors } from './utils/report_callback_errors';
+import { web3Factory } from './utils/web3_factory';
chaiSetup.configure();
const expect = chai.expect;
@@ -26,7 +21,6 @@ describe('EventWatcher', () => {
let stubs: Sinon.SinonStub[] = [];
let eventWatcher: EventWatcher;
let web3Wrapper: Web3Wrapper;
- const numConfirmations = 0;
const logA: Web3.LogEntry = {
address: '0x71d271f8b14adef568f8f28f1587ce7271ac4ca5',
blockHash: null,
@@ -43,7 +37,7 @@ describe('EventWatcher', () => {
blockNumber: null,
data: '',
logIndex: null,
- topics: [ '0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567' ],
+ topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
transactionIndex: 0,
};
@@ -53,7 +47,7 @@ describe('EventWatcher', () => {
blockNumber: null,
data: '',
logIndex: null,
- topics: [ '0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567' ],
+ topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
transactionIndex: 0,
};
@@ -84,13 +78,14 @@ describe('EventWatcher', () => {
const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
getLogsStub.onCall(0).returns(logs);
stubs.push(getLogsStub);
- const callback = (event: LogEvent) => {
+ const expectedToBeCalledOnce = false;
+ const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
const expectedLogEvent = expectedLogEvents.shift();
expect(event).to.be.deep.equal(expectedLogEvent);
if (_.isEmpty(expectedLogEvents)) {
done();
}
- };
+ });
eventWatcher.subscribe(callback);
});
it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
@@ -118,13 +113,14 @@ describe('EventWatcher', () => {
getLogsStub.onCall(0).returns(initialLogs);
getLogsStub.onCall(1).returns(changedLogs);
stubs.push(getLogsStub);
- const callback = (event: LogEvent) => {
+ const expectedToBeCalledOnce = false;
+ const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
const expectedLogEvent = expectedLogEvents.shift();
expect(event).to.be.deep.equal(expectedLogEvent);
if (_.isEmpty(expectedLogEvents)) {
done();
}
- };
+ });
eventWatcher.subscribe(callback);
});
});
diff --git a/packages/0x.js/test/exchange_transfer_simulator_test.ts b/packages/0x.js/test/exchange_transfer_simulator_test.ts
index a1d9bdade..20b4a05ca 100644
--- a/packages/0x.js/test/exchange_transfer_simulator_test.ts
+++ b/packages/0x.js/test/exchange_transfer_simulator_test.ts
@@ -1,18 +1,18 @@
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
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 {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
describe('ExchangeTransferSimulator', () => {
const web3 = web3Factory.create();
@@ -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,9 +77,14 @@ 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 store = (exchangeTransferSimulator as any)._store;
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
@@ -73,15 +92,20 @@ 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 store = (exchangeTransferSimulator as any)._store;
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts
index 14559c706..7e0ffd818 100644
--- a/packages/0x.js/test/exchange_wrapper_test.ts
+++ b/packages/0x.js/test/exchange_wrapper_test.ts
@@ -1,34 +1,35 @@
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
+import * as _ from 'lodash';
import 'mocha';
import * as Web3 from 'web3';
import {
+ BlockRange,
DecodedLogEvent,
ExchangeContractErrs,
ExchangeEvents,
LogCancelContractEventArgs,
- LogEvent,
LogFillContractEventArgs,
OrderCancellationRequest,
OrderFillRequest,
SignedOrder,
- SubscriptionOpts,
Token,
ZeroEx,
} from '../src';
-import {BlockParamLiteral, DoneCallback} from '../src/types';
+import { BlockParamLiteral, DoneCallback } from '../src/types';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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 { reportNodeCallbackErrors } from './utils/report_callback_errors';
+import { TokenUtils } from './utils/token_utils';
+import { web3Factory } from './utils/web3_factory';
chaiSetup.configure();
const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
@@ -53,6 +54,7 @@ describe('ExchangeWrapper', () => {
tokenUtils = new TokenUtils(tokens);
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+ await fillScenarios.initTokenBalancesAsync();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -71,7 +73,7 @@ describe('ExchangeWrapper', () => {
before(async () => {
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
});
@@ -80,10 +82,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 +113,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 +127,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 +152,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);
});
});
});
@@ -201,7 +241,7 @@ describe('ExchangeWrapper', () => {
before(async () => {
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
});
@@ -209,57 +249,96 @@ describe('ExchangeWrapper', () => {
describe('successful fills', () => {
it('should fill a valid order', async () => {
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- 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);
+ 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,
+ );
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 +346,71 @@ 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);
+ });
+ });
+ describe('negative fill amount', async () => {
+ let signedOrder: SignedOrder;
+ const negativeFillTakerAmount = new BigNumber(-100);
+ beforeEach(async () => {
+ signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerTokenAddress,
+ takerTokenAddress,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ );
+ });
+ it('should not allow the exchange wrapper to fill if amount is negative', async () => {
+ return expect(
+ zeroEx.exchange.fillOrderAsync(
+ signedOrder,
+ negativeFillTakerAmount,
+ shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
+ ),
+ ).to.be.rejected();
});
});
});
@@ -297,11 +422,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 +452,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 +488,61 @@ 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);
+ });
+ });
+ describe('negative batch fill amount', async () => {
+ beforeEach(async () => {
+ const negativeFillTakerAmount = new BigNumber(-100);
+ orderFillBatch = [
+ {
+ signedOrder,
+ takerTokenFillAmount,
+ },
+ {
+ signedOrder: anotherSignedOrder,
+ takerTokenFillAmount: negativeFillTakerAmount,
+ },
+ ];
+ });
+ it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
+ return expect(
+ zeroEx.exchange.batchFillOrdersAsync(
+ orderFillBatch,
+ shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
+ ),
+ ).to.be.rejected();
});
});
});
@@ -375,24 +555,57 @@ 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 () => {
+ it('should successfully fill up to specified amount when all orders are fully funded', async () => {
+ const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
+ signedOrders,
+ fillUpToAmount,
+ shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
+ );
+ await zeroEx.awaitTransactionMinedAsync(txHash);
+ const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+ const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+ expect(filledAmount).to.be.bignumber.equal(fillableAmount);
+ const remainingFillAmount = fillableAmount.minus(1);
+ expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
+ });
+ it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
+ const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
+ // but won't have 10 to fully fill all orders in a batch.
+ await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
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);
@@ -402,24 +615,57 @@ describe('ExchangeWrapper', () => {
expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
});
});
+ describe('failed batch fills', () => {
+ it("should fail validation if user doesn't have enough balance without fill up to", async () => {
+ const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
+ await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
+ return expect(
+ zeroEx.exchange.fillOrdersUpToAsync(
+ signedOrders,
+ fillUpToAmount,
+ shouldThrowOnInsufficientBalanceOrAllowance,
+ takerAddress,
+ ),
+ ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
+ });
+ });
describe('order transaction options', () => {
const emptyFillUpToAmount = new BigNumber(0);
it('should validate when orderTransactionOptions are not present', async () => {
- return expect(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);
});
});
});
@@ -436,11 +682,15 @@ describe('ExchangeWrapper', () => {
const cancelAmount = new BigNumber(3);
beforeEach(async () => {
[coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
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 +706,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 +732,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 +753,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 +796,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);
});
});
});
@@ -557,7 +827,8 @@ describe('ExchangeWrapper', () => {
let orderHash: string;
before(() => {
takerAddress = userAddresses[1];
- const [makerToken, takerToken] = tokens;
+ tokenUtils = new TokenUtils(tokens);
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
});
@@ -565,7 +836,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);
});
@@ -589,8 +864,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 () => {
@@ -633,14 +907,18 @@ describe('ExchangeWrapper', () => {
const cancelTakerAmountInBaseUnits = new BigNumber(1);
before(() => {
[coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokens;
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
});
beforeEach(async () => {
fillableAmount = new BigNumber(5);
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ makerTokenAddress,
+ takerTokenAddress,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
);
});
afterEach(async () => {
@@ -653,70 +931,74 @@ 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,
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+ },
);
+ 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,
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
+ },
);
+ 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,
+ const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ done(new Error('Expected this subscription to have been cancelled'));
+ },
);
+ zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
const newProvider = web3Factory.getRpcProvider();
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
- const callback = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
- done();
- };
- zeroEx.exchange.subscribe(
- ExchangeEvents.LogFill, indexFilterValues, callback,
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+ },
);
+ zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
await zeroEx.exchange.fillOrderAsync(
- signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
+ signedOrder,
+ takerTokenFillAmountInBaseUnits,
+ shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
})().catch(done);
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
- const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
- done(new Error('Expected this subscription to have been cancelled'));
- };
+ const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ 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();
@@ -731,17 +1013,22 @@ describe('ExchangeWrapper', () => {
const fillableAmount = new BigNumber(5);
before(async () => {
[, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
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);
});
});
@@ -759,59 +1046,87 @@ describe('ExchangeWrapper', () => {
let takerAddress: string;
const fillableAmount = new BigNumber(5);
const shouldThrowOnInsufficientBalanceOrAllowance = true;
- const subscriptionOpts: SubscriptionOpts = {
+ const blockRange: BlockRange = {
fromBlock: 0,
toBlock: BlockParamLiteral.Latest,
};
let txHash: string;
before(async () => {
[, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
});
it('should get logs with decoded args emitted by LogFill', async () => {
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ 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;
const indexFilterValues = {};
- const logs = await zeroEx.exchange.getLogsAsync(eventName, subscriptionOpts, indexFilterValues);
+ const logs = await zeroEx.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
expect(logs).to.have.length(1);
expect(logs[0].event).to.be.equal(eventName);
});
it('should only get the logs with the correct event name', async () => {
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ 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;
const indexFilterValues = {};
- const logs = await zeroEx.exchange.getLogsAsync(differentEventName, subscriptionOpts, indexFilterValues);
+ const logs = await zeroEx.exchange.getLogsAsync(differentEventName, blockRange, indexFilterValues);
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ 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);
@@ -820,7 +1135,9 @@ describe('ExchangeWrapper', () => {
maker: differentMakerAddress,
};
const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
- eventName, subscriptionOpts, indexFilterValues,
+ eventName,
+ blockRange,
+ indexFilterValues,
);
expect(logs).to.have.length(1);
const args = logs[0].args;
diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts
index d4581259d..770615f88 100644
--- a/packages/0x.js/test/expiration_watcher_test.ts
+++ b/packages/0x.js/test/expiration_watcher_test.ts
@@ -1,27 +1,27 @@
-import {Web3Wrapper} from '@0xproject/web3-wrapper';
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
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 {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-import {chaiSetup} from './utils/chai_setup';
-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 { reportNoErrorCallbackErrors } from './utils/report_callback_errors';
+import { TokenUtils } from './utils/token_utils';
+import { web3Factory } from './utils/web3_factory';
chaiSetup.configure();
const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(testConstants.RPC_URL);
describe('ExpirationWatcher', () => {
let web3: Web3;
@@ -56,13 +56,13 @@ describe('ExpirationWatcher', () => {
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
});
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,31 +78,38 @@ 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);
expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
- const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
+ const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => {
expect(hash).to.be.equal(orderHash);
expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
- done();
});
expirationWatcher.subscribe(callbackAsync);
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);
expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
- const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
+ const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => {
done(new Error('Emitted expiration went before the order actually expired'));
});
expirationWatcher.subscribe(callbackAsync);
@@ -118,11 +125,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);
@@ -130,7 +145,8 @@ describe('ExpirationWatcher', () => {
expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
const expirationOrder = [orderHash1, orderHash2];
- const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
+ const expectToBeCalledOnce = false;
+ const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => {
const orderHash = expirationOrder.shift();
expect(hash).to.be.equal(orderHash);
if (_.isEmpty(expirationOrder)) {
diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts
index b5968dc24..2e9202fe2 100644
--- a/packages/0x.js/test/order_state_watcher_test.ts
+++ b/packages/0x.js/test/order_state_watcher_test.ts
@@ -1,39 +1,34 @@
-import {Web3Wrapper} from '@0xproject/web3-wrapper';
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'mocha';
import * as Web3 from 'web3';
import {
- DecodedLogEvent,
ExchangeContractErrs,
- LogEvent,
OrderState,
OrderStateInvalid,
OrderStateValid,
SignedOrder,
Token,
ZeroEx,
- ZeroExConfig,
ZeroExError,
} from '../src';
-import {OrderStateWatcher} from '../src/order_watcher/order_state_watcher';
-import {DoneCallback} from '../src/types';
+import { DoneCallback } from '../src/types';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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 { reportNodeCallbackErrors } from './utils/report_callback_errors';
+import { TokenUtils } from './utils/token_utils';
+import { web3Factory } from './utils/web3_factory';
const TIMEOUT_MS = 150;
chaiSetup.configure();
const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
describe('OrderStateWatcher', () => {
let web3: Web3;
@@ -48,7 +43,6 @@ describe('OrderStateWatcher', () => {
let takerToken: Token;
let maker: string;
let taker: string;
- let web3Wrapper: Web3Wrapper;
let signedOrder: SignedOrder;
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
@@ -65,8 +59,8 @@ describe('OrderStateWatcher', () => {
tokenUtils = new TokenUtils(tokens);
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
- [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
- web3Wrapper = (zeroEx as any)._web3Wrapper;
+ await fillScenarios.initTokenBalancesAsync();
+ [makerToken, takerToken] = tokenUtils.getDummyTokens();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -77,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);
@@ -95,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);
});
});
@@ -108,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 () => {
@@ -121,16 +126,19 @@ 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);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- done();
});
zeroEx.orderStateWatcher.subscribe(callback);
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
@@ -139,18 +147,20 @@ 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,
);
- const orderHash = ZeroEx.getOrderHashHex(signedOrder);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
throw new Error('OrderState callback fired for irrelevant order');
});
zeroEx.orderStateWatcher.subscribe(callback);
const notTheMaker = userAddresses[0];
const anyRecipient = taker;
const transferAmount = new BigNumber(2);
- const notTheMakerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, notTheMaker);
await zeroEx.token.transferAsync(makerToken.address, notTheMaker, anyRecipient, transferAmount);
setTimeout(() => {
done();
@@ -160,16 +170,19 @@ 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);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
- done();
});
zeroEx.orderStateWatcher.subscribe(callback);
const anyRecipient = taker;
@@ -180,40 +193,48 @@ 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);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
- done();
});
zeroEx.orderStateWatcher.subscribe(callback);
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);
- const takerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, taker);
-
const fillAmountInBaseUnits = new BigNumber(2);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.true();
const validOrderState = orderState as OrderStateValid;
expect(validOrderState.orderHash).to.be.equal(orderHash);
@@ -221,16 +242,20 @@ 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);
});
@@ -239,13 +264,17 @@ 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);
- const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+ makerToken.address,
+ takerToken.address,
+ makerFee,
+ takerFee,
+ maker,
+ taker,
+ fillableAmount,
+ taker,
+ );
+ const callback = reportNodeCallbackErrors(done)();
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
- done();
- });
zeroEx.orderStateWatcher.subscribe(callback);
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
})().catch(done);
@@ -256,51 +285,60 @@ 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 makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
- const takerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, taker);
const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.true();
const validOrderState = orderState as OrderStateValid;
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));
- done();
+ ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
+ );
});
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 makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
-
const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
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);
- done();
+ changedMakerApprovalAmount,
+ );
});
zeroEx.orderStateWatcher.subscribe(callback);
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
@@ -309,7 +347,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);
@@ -318,19 +360,19 @@ describe('OrderStateWatcher', () => {
const transferAmount = makerBalance.sub(remainingAmount);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.true();
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);
- done();
+ remainingAmount,
+ );
});
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) => {
@@ -339,22 +381,27 @@ 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);
-
- const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+ makerToken.address,
+ takerToken.address,
+ makerFee,
+ takerFee,
+ maker,
+ taker,
+ fillableAmount,
+ feeRecipient,
+ );
const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.true();
const validOrderState = orderState as OrderStateValid;
const orderRelevantState = validOrderState.orderRelevantState;
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
- remainingTokenAmount);
- done();
+ remainingTokenAmount,
+ );
});
zeroEx.orderStateWatcher.subscribe(callback);
await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
@@ -366,29 +413,37 @@ 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);
-
- const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+ makerToken.address,
+ takerToken.address,
+ makerFee,
+ takerFee,
+ maker,
+ taker,
+ fillableAmount,
+ feeRecipient,
+ );
const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
- const transferFeeAmount = makerFee.sub(remainingFeeAmount);
const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
const validOrderState = orderState as OrderStateValid;
const orderRelevantState = validOrderState.orderRelevantState;
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
- remainingFeeAmount);
- done();
+ remainingFeeAmount,
+ );
});
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) => {
@@ -397,43 +452,54 @@ 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,
+ );
- const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
const validOrderState = orderState as OrderStateValid;
const orderRelevantState = validOrderState.orderRelevantState;
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
- fillableAmount);
- done();
+ fillableAmount,
+ );
});
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);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
- done();
});
zeroEx.orderStateWatcher.subscribe(callback);
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
})().catch(done);
});
@@ -441,44 +507,48 @@ 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);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
- done();
});
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 makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
- const takerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, taker);
-
const cancelAmountInBaseUnits = new BigNumber(2);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
zeroEx.orderStateWatcher.addOrder(signedOrder);
- const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.true();
const validOrderState = orderState as OrderStateValid;
expect(validOrderState.orderHash).to.be.equal(orderHash);
const orderRelevantState = validOrderState.orderRelevantState;
expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
- done();
});
zeroEx.orderStateWatcher.subscribe(callback);
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
diff --git a/packages/0x.js/test/order_validation_test.ts b/packages/0x.js/test/order_validation_test.ts
index d585c1f3c..be3e0590c 100644
--- a/packages/0x.js/test/order_validation_test.ts
+++ b/packages/0x.js/test/order_validation_test.ts
@@ -1,23 +1,23 @@
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
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 {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
describe('OrderValidation', () => {
let web3: Web3;
@@ -34,7 +34,6 @@ describe('OrderValidation', () => {
let makerAddress: string;
let takerAddress: string;
let feeRecipient: string;
- let orderValidationUtils: OrderValidationUtils;
const fillableAmount = new BigNumber(5);
const fillTakerAmount = new BigNumber(5);
const config = {
@@ -50,10 +49,9 @@ describe('OrderValidation', () => {
tokenUtils = new TokenUtils(tokens);
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
- orderValidationUtils = new OrderValidationUtils(zeroEx.token, zeroEx.exchange);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -64,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);
@@ -174,44 +216,56 @@ 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', () => {
let signedOrder: SignedOrder;
- let orderHashHex: string;
const cancelAmount = new BigNumber(3);
beforeEach(async () => {
[coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ makerTokenAddress,
+ takerTokenAddress,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
);
- orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
});
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,
);
- orderHashHex = ZeroEx.getOrderHashHex(expiredSignedOrder);
- 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', () => {
@@ -229,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];
@@ -314,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);
diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts
index 610bf9b1a..4c6b8f3ac 100644
--- a/packages/0x.js/test/remaining_fillable_calculator_test.ts
+++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts
@@ -1,4 +1,4 @@
-import BigNumber from 'bignumber.js';
+import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'mocha';
@@ -7,7 +7,6 @@ import { RemainingFillableCalculator } from '../src/order_watcher/remaining_fill
import { ECSignature, SignedOrder } from '../src/types';
import { chaiSetup } from './utils/chai_setup';
-import { TokenUtils } from './utils/token_utils';
chaiSetup.configure();
const expect = chai.expect;
@@ -27,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 () => {
@@ -58,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', () => {
@@ -82,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));
@@ -135,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', () => {
@@ -151,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', () => {
@@ -164,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);
diff --git a/packages/0x.js/test/subscription_test.ts b/packages/0x.js/test/subscription_test.ts
index 3aeeaa109..f4c6f748f 100644
--- a/packages/0x.js/test/subscription_test.ts
+++ b/packages/0x.js/test/subscription_test.ts
@@ -1,37 +1,26 @@
-import BigNumber from 'bignumber.js';
-import * as chai from 'chai';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import 'mocha';
import * as Sinon from 'sinon';
import * as Web3 from 'web3';
-import {
- ApprovalContractEventArgs,
- DecodedLogEvent,
- Token,
- TokenEvents,
- ZeroEx,
- ZeroExError,
-} from '../src';
-import {BlockParamLiteral, DoneCallback} from '../src/types';
+import { ApprovalContractEventArgs, DecodedLogEvent, Token, TokenEvents, ZeroEx } from '../src';
+import { DoneCallback } from '../src/types';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-import {chaiSetup} from './utils/chai_setup';
-import {constants} from './utils/constants';
-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 { assertNodeCallbackError } from './utils/report_callback_errors';
+import { web3Factory } from './utils/web3_factory';
chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
describe('SubscriptionTest', () => {
let web3: Web3;
let zeroEx: ZeroEx;
let userAddresses: string[];
let tokens: Token[];
- let tokenUtils: TokenUtils;
let coinbase: string;
let addressWithoutFunds: string;
const config = {
@@ -42,7 +31,6 @@ describe('SubscriptionTest', () => {
zeroEx = new ZeroEx(web3.currentProvider, config);
userAddresses = await zeroEx.getAvailableAddressesAsync();
tokens = await zeroEx.tokenRegistry.getTokensAsync();
- tokenUtils = new TokenUtils(tokens);
coinbase = userAddresses[0];
addressWithoutFunds = userAddresses[1];
});
@@ -54,9 +42,7 @@ describe('SubscriptionTest', () => {
});
describe('#subscribe', () => {
const indexFilterValues = {};
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
let tokenAddress: string;
- const transferAmount = new BigNumber(42);
const allowanceAmount = new BigNumber(42);
let stubs: Sinon.SinonStub[] = [];
before(() => {
@@ -71,50 +57,26 @@ describe('SubscriptionTest', () => {
it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
(async () => {
const errMsg = 'Error fetching block';
- const callback = reportCallbackErrors(done)(
- (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
- expect(err.message).to.be.equal(errMsg);
- expect(logEvent).to.be.undefined();
- done();
- },
- );
- stubs = [
- Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
- .throws(new Error(errMsg)),
- ];
- zeroEx.token.subscribe(
- tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+ const callback = assertNodeCallbackError(done, errMsg);
+ 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);
});
it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
(async () => {
const errMsg = 'Error fetching logs';
- const callback = reportCallbackErrors(done)(
- (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
- expect(err.message).to.be.equal(errMsg);
- expect(logEvent).to.be.undefined();
- done();
- },
- );
- stubs = [
- Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync')
- .throws(new Error(errMsg)),
- ];
- zeroEx.token.subscribe(
- tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+ const callback = assertNodeCallbackError(done, errMsg);
+ 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')),
- ];
+ const callback = (err: Error | null, 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.unsubscribeAll();
done();
})().catch(done);
diff --git a/packages/0x.js/test/token_registry_wrapper_test.ts b/packages/0x.js/test/token_registry_wrapper_test.ts
index f1f307f3a..0a170db8f 100644
--- a/packages/0x.js/test/token_registry_wrapper_test.ts
+++ b/packages/0x.js/test/token_registry_wrapper_test.ts
@@ -1,28 +1,28 @@
-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 {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
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';
diff --git a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
index 05861d112..15bd7a8ba 100644
--- a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
+++ b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
@@ -1,11 +1,10 @@
import * as chai from 'chai';
-import {ZeroEx} from '../src';
-import {TokenTransferProxyWrapper} from '../src/contract_wrappers/token_transfer_proxy_wrapper';
+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;
diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts
index ae6016869..4ba1f07c5 100644
--- a/packages/0x.js/test/token_wrapper_test.ts
+++ b/packages/0x.js/test/token_wrapper_test.ts
@@ -1,35 +1,32 @@
-import {promisify} from '@0xproject/utils';
-import {Web3Wrapper} from '@0xproject/web3-wrapper';
-import BigNumber from 'bignumber.js';
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
import 'mocha';
import * as Web3 from 'web3';
import {
ApprovalContractEventArgs,
- ContractEvent,
+ BlockParamLiteral,
+ BlockRange,
DecodedLogEvent,
- LogEvent,
- LogWithDecodedArgs,
- SubscriptionOpts,
Token,
- TokenContractEventArgs,
TokenEvents,
TransferContractEventArgs,
ZeroEx,
ZeroExError,
} from '../src';
-import {BlockParamLiteral, DoneCallback} from '../src/types';
+import { DoneCallback } from '../src/types';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-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 { reportNodeCallbackErrors } from './utils/report_callback_errors';
+import { TokenUtils } from './utils/token_utils';
+import { web3Factory } from './utils/web3_factory';
chaiSetup.configure();
const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
+const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
describe('TokenWrapper', () => {
let web3: Web3;
@@ -71,25 +68,24 @@ describe('TokenWrapper', () => {
const toAddress = addressWithoutFunds;
const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
expect(preBalance).to.be.bignumber.equal(0);
- const txHash = await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
- const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+ await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
return expect(postBalance).to.be.bignumber.equal(transferAmount);
});
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', () => {
@@ -108,24 +104,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;
@@ -135,13 +129,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;
@@ -152,17 +149,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', () => {
@@ -177,8 +179,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];
@@ -196,22 +199,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);
@@ -224,7 +230,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;
@@ -246,10 +252,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);
@@ -305,7 +319,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);
@@ -354,7 +370,6 @@ describe('TokenWrapper', () => {
});
describe('#subscribe', () => {
const indexFilterValues = {};
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
let tokenAddress: string;
const transferAmount = new BigNumber(42);
const allowanceAmount = new BigNumber(42);
@@ -372,65 +387,66 @@ describe('TokenWrapper', () => {
// Source: https://github.com/mochajs/mocha/issues/2407
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
(async () => {
- const callback = (err: Error, logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
- expect(logEvent).to.not.be.undefined();
- expect(logEvent.isRemoved).to.be.false();
- expect(logEvent.log.logIndex).to.be.equal(0);
- expect(logEvent.log.transactionIndex).to.be.equal(0);
- expect(logEvent.log.blockNumber).to.be.a('number');
- const args = logEvent.log.args;
- expect(args._from).to.be.equal(coinbase);
- expect(args._to).to.be.equal(addressWithoutFunds);
- expect(args._value).to.be.bignumber.equal(transferAmount);
- done();
- };
- zeroEx.token.subscribe(
- tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+ expect(logEvent.isRemoved).to.be.false();
+ expect(logEvent.log.logIndex).to.be.equal(0);
+ expect(logEvent.log.transactionIndex).to.be.equal(0);
+ expect(logEvent.log.blockNumber).to.be.a('number');
+ const args = logEvent.log.args;
+ expect(args._from).to.be.equal(coinbase);
+ expect(args._to).to.be.equal(addressWithoutFunds);
+ expect(args._value).to.be.bignumber.equal(transferAmount);
+ },
+ );
+ zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
})().catch(done);
});
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
(async () => {
- const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
- expect(logEvent).to.not.be.undefined();
- expect(logEvent.isRemoved).to.be.false();
- const args = logEvent.log.args;
- expect(args._owner).to.be.equal(coinbase);
- expect(args._spender).to.be.equal(addressWithoutFunds);
- expect(args._value).to.be.bignumber.equal(allowanceAmount);
- done();
- };
- zeroEx.token.subscribe(
- tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+ const callback = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ expect(logEvent).to.not.be.undefined();
+ expect(logEvent.isRemoved).to.be.false();
+ const args = logEvent.log.args;
+ expect(args._owner).to.be.equal(coinbase);
+ expect(args._spender).to.be.equal(addressWithoutFunds);
+ expect(args._value).to.be.bignumber.equal(allowanceAmount);
+ },
+ );
+ zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
})().catch(done);
});
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
(async () => {
- 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,
+ const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ done(new Error('Expected this subscription to have been cancelled'));
+ },
);
- const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
- done();
- };
+ zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
+ const callbackToBeCalled = reportNodeCallbackErrors(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);
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
- const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
- done(new Error('Expected this subscription to have been cancelled'));
- };
+ const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ 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();
@@ -440,7 +456,7 @@ describe('TokenWrapper', () => {
describe('#getLogsAsync', () => {
let tokenAddress: string;
let tokenTransferProxyAddress: string;
- const subscriptionOpts: SubscriptionOpts = {
+ const blockRange: BlockRange = {
fromBlock: 0,
toBlock: BlockParamLiteral.Latest,
};
@@ -456,7 +472,10 @@ describe('TokenWrapper', () => {
const eventName = TokenEvents.Approval;
const indexFilterValues = {};
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
- tokenAddress, eventName, subscriptionOpts, indexFilterValues,
+ tokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
);
expect(logs).to.have.length(1);
const args = logs[0].args;
@@ -471,7 +490,10 @@ describe('TokenWrapper', () => {
const differentEventName = TokenEvents.Transfer;
const indexFilterValues = {};
const logs = await zeroEx.token.getLogsAsync(
- tokenAddress, differentEventName, subscriptionOpts, indexFilterValues,
+ tokenAddress,
+ differentEventName,
+ blockRange,
+ indexFilterValues,
);
expect(logs).to.have.length(0);
});
@@ -485,7 +507,10 @@ describe('TokenWrapper', () => {
_owner: coinbase,
};
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
- tokenAddress, eventName, subscriptionOpts, indexFilterValues,
+ tokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
);
expect(logs).to.have.length(1);
const args = logs[0].args;
@@ -493,3 +518,4 @@ describe('TokenWrapper', () => {
});
});
});
+// tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/utils/blockchain_lifecycle.ts b/packages/0x.js/test/utils/blockchain_lifecycle.ts
deleted file mode 100644
index 9a44ccd6f..000000000
--- a/packages/0x.js/test/utils/blockchain_lifecycle.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import {RPC} from './rpc';
-
-export class BlockchainLifecycle {
- private rpc: RPC;
- private snapshotIdsStack: number[];
- constructor() {
- this.rpc = new RPC();
- this.snapshotIdsStack = [];
- }
- // TODO: In order to run these tests on an actual node, we should check if we are running against
- // TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
- public async startAsync(): Promise<void> {
- const snapshotId = await this.rpc.takeSnapshotAsync();
- this.snapshotIdsStack.push(snapshotId);
- }
- public async revertAsync(): Promise<void> {
- const snapshotId = this.snapshotIdsStack.pop() as number;
- const didRevert = await this.rpc.revertSnapshotAsync(snapshotId);
- if (!didRevert) {
- throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
- }
- }
- public async mineABlock(): Promise<void> {
- await this.rpc.mineBlockAsync();
- }
-}
diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts
index 75fdf49c9..a9e665c25 100644
--- a/packages/0x.js/test/utils/constants.ts
+++ b/packages/0x.js/test/utils/constants.ts
@@ -1,12 +1,11 @@
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
- RPC_HOST: 'localhost',
- RPC_PORT: 8545,
+ RPC_URL: 'http://localhost:8545',
ROPSTEN_NETWORK_ID: 3,
KOVAN_NETWORK_ID: 42,
TESTRPC_NETWORK_ID: 50,
- KOVAN_RPC_URL: 'https://kovan.infura.io',
- ROPSTEN_RPC_URL: 'https://ropsten.infura.io',
+ KOVAN_RPC_URL: 'https://kovan.infura.io/',
+ ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
ZRX_DECIMALS: 18,
GAS_ESTIMATE: 500000,
};
diff --git a/packages/0x.js/test/utils/fill_scenarios.ts b/packages/0x.js/test/utils/fill_scenarios.ts
index 090493935..1a61487f4 100644
--- a/packages/0x.js/test/utils/fill_scenarios.ts
+++ b/packages/0x.js/test/utils/fill_scenarios.ts
@@ -1,116 +1,202 @@
-import BigNumber from 'bignumber.js';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
-import {SignedOrder, Token, ZeroEx} from '../../src';
-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);
export class FillScenarios {
- private zeroEx: ZeroEx;
- private userAddresses: string[];
- private tokens: Token[];
- private coinbase: string;
- private zrxTokenAddress: string;
- private exchangeContractAddress: string;
- constructor(zeroEx: ZeroEx, userAddresses: string[],
- tokens: Token[], zrxTokenAddress: string, exchangeContractAddress: string) {
- this.zeroEx = zeroEx;
- this.userAddresses = userAddresses;
- this.tokens = tokens;
- this.coinbase = userAddresses[0];
- this.zrxTokenAddress = zrxTokenAddress;
- this.exchangeContractAddress = exchangeContractAddress;
+ private _zeroEx: ZeroEx;
+ private _userAddresses: string[];
+ private _tokens: Token[];
+ private _coinbase: string;
+ private _zrxTokenAddress: string;
+ private _exchangeContractAddress: string;
+ constructor(
+ zeroEx: ZeroEx,
+ userAddresses: string[],
+ tokens: Token[],
+ zrxTokenAddress: string,
+ exchangeContractAddress: string,
+ ) {
+ this._zeroEx = zeroEx;
+ this._userAddresses = userAddresses;
+ this._tokens = tokens;
+ this._coinbase = userAddresses[0];
+ this._zrxTokenAddress = zrxTokenAddress;
+ this._exchangeContractAddress = exchangeContractAddress;
+ }
+ public async initTokenBalancesAsync() {
+ const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
+ for (const token of this._tokens) {
+ if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
+ const contractInstance = web3Wrapper.getContractInstance(
+ artifacts.DummyTokenArtifact.abi,
+ token.address,
+ );
+ const defaults = {};
+ const dummyToken = new DummyTokenContract(contractInstance, defaults);
+ const tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals);
+ const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
+ from: this._coinbase,
+ });
+ await this._zeroEx.awaitTransactionMinedAsync(txHash);
+ }
+ }
}
- 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,
+ return this._createAsymmetricFillableSignedOrderWithFeesAsync(
+ 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,
+ return this._createAsymmetricFillableSignedOrderWithFeesAsync(
+ makerTokenAddress,
+ takerTokenAddress,
+ makerFee,
+ takerFee,
+ makerAddress,
+ takerAddress,
+ makerFillableAmount,
+ takerFillableAmount,
+ feeRecepient,
+ expirationUnixTimestampSec,
);
}
- public async createPartiallyFilledSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
- takerAddress: string, fillableAmount: BigNumber,
- partialFillAmount: BigNumber) {
- const [makerAddress] = this.userAddresses;
+ 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,
+ await this._zeroEx.exchange.fillOrderAsync(
+ 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> {
-
+ 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> {
await Promise.all([
- this.increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
- this.increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
+ this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
+ this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
]);
await Promise.all([
- this.increaseBalanceAndAllowanceAsync(this.zrxTokenAddress, makerAddress, makerFee),
- this.increaseBalanceAndAllowanceAsync(this.zrxTokenAddress, takerAddress, takerFee),
+ this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
+ 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> {
+ private async _increaseBalanceAndAllowanceAsync(
+ tokenAddress: string,
+ address: string,
+ amount: BigNumber,
+ ): Promise<void> {
if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
return; // noop
}
await Promise.all([
- this.increaseBalanceAsync(tokenAddress, address, amount),
- this.increaseAllowanceAsync(tokenAddress, address, amount),
+ this._increaseBalanceAsync(tokenAddress, address, amount),
+ this._increaseAllowanceAsync(tokenAddress, address, amount),
]);
}
- private async increaseBalanceAsync(
- tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
- await this.zeroEx.token.transferAsync(tokenAddress, this.coinbase, address, amount);
+ 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> {
- const oldMakerAllowance = await this.zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
+ 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);
}
}
diff --git a/packages/0x.js/test/utils/order_factory.ts b/packages/0x.js/test/utils/order_factory.ts
index 41d93e340..60a7c5fb2 100644
--- a/packages/0x.js/test/utils/order_factory.ts
+++ b/packages/0x.js/test/utils/order_factory.ts
@@ -1,7 +1,7 @@
-import BigNumber from 'bignumber.js';
+import { BigNumber } from '@0xproject/utils';
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;
},
};
diff --git a/packages/0x.js/test/utils/report_callback_errors.ts b/packages/0x.js/test/utils/report_callback_errors.ts
index 8a8f4d966..27c9745c9 100644
--- a/packages/0x.js/test/utils/report_callback_errors.ts
+++ b/packages/0x.js/test/utils/report_callback_errors.ts
@@ -1,10 +1,22 @@
+import * as chai from 'chai';
+import * as _ from 'lodash';
+
import { DoneCallback } from '../../src/types';
-export const reportCallbackErrors = (done: DoneCallback) => {
- return (f: (...args: any[]) => void) => {
- const wrapped = async (...args: any[]) => {
+const expect = chai.expect;
+
+export const reportNoErrorCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
+ return <T>(f?: (value: T) => void) => {
+ const wrapped = (value: T) => {
+ if (_.isUndefined(f)) {
+ done();
+ return;
+ }
try {
- f(...args);
+ f(value);
+ if (expectToBeCalledOnce) {
+ done();
+ }
} catch (err) {
done(err);
}
@@ -12,3 +24,43 @@ export const reportCallbackErrors = (done: DoneCallback) => {
return wrapped;
};
};
+
+export const reportNodeCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
+ return <T>(f?: (value: T) => void) => {
+ const wrapped = (error: Error | null, value: T | undefined) => {
+ if (!_.isNull(error)) {
+ done(error);
+ } else {
+ if (_.isUndefined(f)) {
+ done();
+ return;
+ }
+ try {
+ f(value as T);
+ if (expectToBeCalledOnce) {
+ done();
+ }
+ } catch (err) {
+ done(err);
+ }
+ }
+ };
+ return wrapped;
+ };
+};
+
+export const assertNodeCallbackError = (done: DoneCallback, errMsg: string) => {
+ const wrapped = <T>(error: Error | null, value: T | undefined) => {
+ if (_.isNull(error)) {
+ done(new Error('Expected callback to receive an error'));
+ } else {
+ try {
+ expect(error.message).to.be.equal(errMsg);
+ done();
+ } catch (err) {
+ done(err);
+ }
+ }
+ };
+ return wrapped;
+};
diff --git a/packages/0x.js/test/utils/rpc.ts b/packages/0x.js/test/utils/rpc.ts
deleted file mode 100644
index 309a96d5e..000000000
--- a/packages/0x.js/test/utils/rpc.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as ethUtil from 'ethereumjs-util';
-import * as request from 'request-promise-native';
-
-import {constants} from './constants';
-
-export class RPC {
- private host: string;
- private port: number;
- private id: number;
- constructor() {
- this.host = constants.RPC_HOST;
- this.port = constants.RPC_PORT;
- this.id = 0;
- }
- public async takeSnapshotAsync(): Promise<number> {
- const method = 'evm_snapshot';
- const params: any[] = [];
- const payload = this.toPayload(method, params);
- const snapshotIdHex = await this.sendAsync(payload);
- const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex));
- return snapshotId;
- }
- public async revertSnapshotAsync(snapshotId: number): Promise<boolean> {
- const method = 'evm_revert';
- const params = [snapshotId];
- const payload = this.toPayload(method, params);
- const didRevert = await this.sendAsync(payload);
- return didRevert;
- }
- public async mineBlockAsync(): Promise<void> {
- const method = 'evm_mine';
- const params: any[] = [];
- const payload = this.toPayload(method, params);
- await this.sendAsync(payload);
- }
- private toPayload(method: string, params: any[] = []): string {
- const payload = JSON.stringify({
- id: this.id,
- method,
- params,
- });
- this.id += 1;
- return payload;
- }
- private async sendAsync(payload: string): Promise<any> {
- const opts = {
- method: 'POST',
- uri: `http://${this.host}:${this.port}`,
- body: payload,
- headers: {
- 'content-type': 'application/json',
- },
- };
- const bodyString = await request(opts);
- const body = JSON.parse(bodyString);
- return body.result;
- }
-}
diff --git a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts b/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
index e5e279873..53f2be83d 100644
--- a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
+++ b/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
@@ -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, []);
diff --git a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts b/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
index 059163f2e..e1113a851 100644
--- a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
+++ b/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
@@ -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
@@ -9,16 +9,16 @@ import {JSONRPCPayload} from '../../../src/types';
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
*/
export class FakeGasEstimateSubprovider {
- private constantGasAmount: number;
+ private _constantGasAmount: number;
constructor(constantGasAmount: number) {
- this.constantGasAmount = constantGasAmount;
+ this._constantGasAmount = constantGasAmount;
}
// 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);
+ end(null, this._constantGasAmount);
return;
default:
diff --git a/packages/0x.js/test/utils/token_utils.ts b/packages/0x.js/test/utils/token_utils.ts
index 9c20f52a1..d3fc22ff4 100644
--- a/packages/0x.js/test/utils/token_utils.ts
+++ b/packages/0x.js/test/utils/token_utils.ts
@@ -1,25 +1,33 @@
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';
export class TokenUtils {
- private tokens: Token[];
+ private _tokens: Token[];
constructor(tokens: Token[]) {
- this.tokens = tokens;
+ 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 getNonProtocolTokens(): Token[] {
- const nonProtocolTokens = _.filter(this.tokens, token => {
- return token.symbol !== PROTOCOL_TOKEN_SYMBOL;
+ public getWethTokenOrThrow(): Token {
+ const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
+ if (_.isUndefined(wethToken)) {
+ throw new Error(InternalZeroExError.WethNotInTokenRegistry);
+ }
+ return wethToken;
+ }
+ public getDummyTokens(): Token[] {
+ const dummyTokens = _.filter(this._tokens, token => {
+ return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
});
- return nonProtocolTokens;
+ return dummyTokens;
}
}
diff --git a/packages/0x.js/test/utils/web3_factory.ts b/packages/0x.js/test/utils/web3_factory.ts
index da4828943..26c26e03d 100644
--- a/packages/0x.js/test/utils/web3_factory.ts
+++ b/packages/0x.js/test/utils/web3_factory.ts
@@ -3,14 +3,20 @@
// we are not running in a browser env.
// Filed issue: https://github.com/ethereum/web3.js/issues/844
(global as any).XMLHttpRequest = undefined;
-import * as Web3 from 'web3';
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.
+// importing web3 after subproviders fixes this issue
+// Filed issue: https://github.com/ethereum/web3.js/issues/844
+// tslint:disable-next-line:ordered-imports
+import * as Web3 from 'web3';
export const web3Factory = {
create(hasAddresses: boolean = true): Web3 {
@@ -21,14 +27,15 @@ export const web3Factory = {
},
getRpcProvider(hasAddresses: boolean = true): Web3.Provider {
const provider = new ProviderEngine();
- const rpcUrl = `http://${constants.RPC_HOST}:${constants.RPC_PORT}`;
if (!hasAddresses) {
provider.addProvider(new EmptyWalletSubprovider());
}
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
- provider.addProvider(new RpcSubprovider({
- rpcUrl,
- }));
+ provider.addProvider(
+ new RpcSubprovider({
+ rpcUrl: constants.RPC_URL,
+ }),
+ );
provider.start();
return provider;
},