From 590552d3e07a74dc6ca76f0ac2a7d814d6a987be Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 15 Nov 2017 11:12:40 -0500 Subject: Initial tests --- packages/0x.js/src/utils/order_state_utils.ts | 34 +++++++++++++++++++++--- packages/0x.js/test/order_state_watcher_test.ts | 35 ++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 4 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 123584f90..e11435f1d 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -78,12 +78,19 @@ export class OrderStateUtils { const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount) .dividedToIntegerBy(totalTakerTokenAmount); - const fillableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); - const remainingFillableMakerTokenAmount = BigNumber.min(fillableMakerTokenAmount, remainingMakerTokenAmount); + const remainingFeeTokenAmount = remainingTakerTokenAmount.times(signedOrder.makerFee) + .dividedToIntegerBy(totalTakerTokenAmount); + const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); + const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); + + const remainingFillableMakerTokenAmount = this.calculateFillableMakerTokenAmount( + transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, + remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, + zrxTokenAddress); + const remainingFillableTakerTokenAmount = remainingFillableMakerTokenAmount .times(totalTakerTokenAmount) .dividedToIntegerBy(totalMakerTokenAmount); - // TODO: Handle edge case where maker token is ZRX with fee const orderRelevantState = { makerBalance, makerProxyAllowance, @@ -96,6 +103,27 @@ export class OrderStateUtils { }; return orderRelevantState; } + private calculateFillableMakerTokenAmount(makerTransferrable: BigNumber, makerFeeTransferrable: BigNumber, + remainingMakerAmount: BigNumber, remainingMakerFee: BigNumber, + totalMakerAmount: BigNumber, makerFee: BigNumber, + makerTokenAddress: string, zrxTokenAddress: string): BigNumber { + if (makerFee.isZero()) { + return BigNumber.min(makerTransferrable, remainingMakerAmount); + } + const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFee); + console.log('Order to Fee Ratio: ', orderToFeeRatio.toString()); + let fillableTimesInMakerToken = makerTransferrable.dividedToIntegerBy(orderToFeeRatio); + console.log('Fillable Token Times: ', fillableTimesInMakerToken.toString()); + const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrable, remainingMakerFee); + console.log('Fillable Fee Times: ', fillableTimesInFeeToken.toString()); + if (makerTokenAddress === zrxTokenAddress) { + fillableTimesInMakerToken = makerTransferrable.plus(makerFeeTransferrable) + .dividedToIntegerBy(orderToFeeRatio.plus(new BigNumber(1))); + + } + return BigNumber.min(fillableTimesInMakerToken.times(orderToFeeRatio), + fillableTimesInFeeToken.times(orderToFeeRatio)); + } private validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void { const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add( orderRelevantState.filledTakerTokenAmount, diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index a112bac1d..3bf768769 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -235,7 +235,7 @@ describe('OrderStateWatcher', () => { ); })().catch(done); }); - describe('remainingFillable(M|T)akerTokenAmount', () => { + describe.only('remainingFillable(M|T)akerTokenAmount', () => { it('should calculate correct remaining fillable', (done: DoneCallback) => { (async () => { const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), 18); @@ -321,6 +321,39 @@ describe('OrderStateWatcher', () => { makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount); })().catch(done); }); + it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => { + (async () => { + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), 18); + 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); + + const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); + const transferFeeAmount = makerFee.sub(remainingFeeAmount); + + const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); + const transferTokenAmount = makerFee.sub(remainingFeeAmount); + zeroEx.orderStateWatcher.addOrder(signedOrder); + + const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const validOrderState = orderState as OrderStateValid; + const orderRelevantState = validOrderState.orderRelevantState; + expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( + remainingAmount); + expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( + remainingAmount); + done(); + }); + zeroEx.orderStateWatcher.subscribe(callback); + await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingAmount); + // await zeroEx.token.transferAsync( + // zrxTokenAddress, maker, ZeroEx.NULL_ADDRESS, transferAmount); + })().catch(done); + }); }); it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => { (async () => { -- cgit v1.2.3 From a2e1d28efc8dbb9dcc07fae39b2be25a9d1a22be Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 15 Nov 2017 15:26:22 -0500 Subject: Remove comments --- packages/0x.js/src/utils/order_state_utils.ts | 3 --- 1 file changed, 3 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index e11435f1d..69e749952 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -111,11 +111,8 @@ export class OrderStateUtils { return BigNumber.min(makerTransferrable, remainingMakerAmount); } const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFee); - console.log('Order to Fee Ratio: ', orderToFeeRatio.toString()); let fillableTimesInMakerToken = makerTransferrable.dividedToIntegerBy(orderToFeeRatio); - console.log('Fillable Token Times: ', fillableTimesInMakerToken.toString()); const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrable, remainingMakerFee); - console.log('Fillable Fee Times: ', fillableTimesInFeeToken.toString()); if (makerTokenAddress === zrxTokenAddress) { fillableTimesInMakerToken = makerTransferrable.plus(makerFeeTransferrable) .dividedToIntegerBy(orderToFeeRatio.plus(new BigNumber(1))); -- cgit v1.2.3 From 54c891a447fb5b47355e8f44a5b29bcc20bae1a1 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 15 Nov 2017 15:52:23 -0500 Subject: Fix test --- packages/0x.js/test/order_state_watcher_test.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 3bf768769..ac77ce4d7 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -335,7 +335,7 @@ describe('OrderStateWatcher', () => { const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); const transferFeeAmount = makerFee.sub(remainingFeeAmount); - const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); + const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); const transferTokenAmount = makerFee.sub(remainingFeeAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); @@ -343,15 +343,13 @@ describe('OrderStateWatcher', () => { const validOrderState = orderState as OrderStateValid; const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( - remainingAmount); - expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( - remainingAmount); + remainingFeeAmount); done(); }); zeroEx.orderStateWatcher.subscribe(callback); - await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingAmount); - // await zeroEx.token.transferAsync( - // zrxTokenAddress, maker, ZeroEx.NULL_ADDRESS, transferAmount); + await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount); + await zeroEx.token.transferAsync( + makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferTokenAmount); })().catch(done); }); }); -- cgit v1.2.3 From c32938fa43ef7ab538465e5eeade924b23776e6c Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 15 Nov 2017 16:20:39 -0500 Subject: Shortcut if everything satisfies in the non dependent use case --- packages/0x.js/src/utils/order_state_utils.ts | 6 ++++++ packages/0x.js/test/order_state_watcher_test.ts | 28 +++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 69e749952..d1b2feb43 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -110,7 +110,13 @@ export class OrderStateUtils { if (makerFee.isZero()) { return BigNumber.min(makerTransferrable, remainingMakerAmount); } + if (makerFeeTransferrable.greaterThanOrEqualTo(makerFee) && + makerTransferrable.greaterThanOrEqualTo(remainingMakerAmount) && + makerTokenAddress !== zrxTokenAddress) { + return BigNumber.min(makerTransferrable, remainingMakerAmount); + } const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFee); + console.log('order to fee ratio: ', orderToFeeRatio.toString()); let fillableTimesInMakerToken = makerTransferrable.dividedToIntegerBy(orderToFeeRatio); const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrable, remainingMakerFee); if (makerTokenAddress === zrxTokenAddress) { diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index ac77ce4d7..fef7b5d13 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -335,8 +335,8 @@ describe('OrderStateWatcher', () => { const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); const transferFeeAmount = makerFee.sub(remainingFeeAmount); - const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); - const transferTokenAmount = makerFee.sub(remainingFeeAmount); + const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), 18); + const transferTokenAmount = makerFee.sub(remainingTokenAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { @@ -352,6 +352,30 @@ describe('OrderStateWatcher', () => { makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferTokenAmount); })().catch(done); }); + it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => { + (async () => { + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + 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); + zeroEx.orderStateWatcher.addOrder(signedOrder); + + const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const validOrderState = orderState as OrderStateValid; + const orderRelevantState = validOrderState.orderRelevantState; + expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( + fillableAmount); + done(); + }); + zeroEx.orderStateWatcher.subscribe(callback); + await zeroEx.token.setProxyAllowanceAsync( + makerToken.address, maker, ZeroEx.toBaseUnitAmount(new BigNumber(100), 18)); + })().catch(done); + }); }); it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => { (async () => { -- cgit v1.2.3 From 9133e764a504f07fd0059334abc5f31ee2c4c59c Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 15 Nov 2017 16:22:35 -0500 Subject: Use 18 decimal place units --- packages/0x.js/src/utils/order_state_utils.ts | 4 ++-- packages/0x.js/test/order_state_watcher_test.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index d1b2feb43..c68eaf85d 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -116,12 +116,12 @@ export class OrderStateUtils { return BigNumber.min(makerTransferrable, remainingMakerAmount); } const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFee); - console.log('order to fee ratio: ', orderToFeeRatio.toString()); let fillableTimesInMakerToken = makerTransferrable.dividedToIntegerBy(orderToFeeRatio); const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrable, remainingMakerFee); if (makerTokenAddress === zrxTokenAddress) { fillableTimesInMakerToken = makerTransferrable.plus(makerFeeTransferrable) - .dividedToIntegerBy(orderToFeeRatio.plus(new BigNumber(1))); + .dividedToIntegerBy(orderToFeeRatio.plus( + ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); } return BigNumber.min(fillableTimesInMakerToken.times(orderToFeeRatio), diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index fef7b5d13..9d432a713 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -235,7 +235,7 @@ describe('OrderStateWatcher', () => { ); })().catch(done); }); - describe.only('remainingFillable(M|T)akerTokenAmount', () => { + describe('remainingFillable(M|T)akerTokenAmount', () => { it('should calculate correct remaining fillable', (done: DoneCallback) => { (async () => { const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), 18); -- cgit v1.2.3 From cf7727debc5ae030795a876a316668e83891cdbf Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 15 Nov 2017 16:37:02 -0500 Subject: refactor up --- packages/0x.js/src/utils/order_state_utils.ts | 32 ++++++++++++------------- packages/0x.js/test/order_state_watcher_test.ts | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index c68eaf85d..4c1bef64e 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -83,10 +83,18 @@ export class OrderStateUtils { const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); - const remainingFillableMakerTokenAmount = this.calculateFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, - remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, - zrxTokenAddress); + let remainingFillableMakerTokenAmount; + if (signedOrder.makerFee.isZero() || + (transferrableFeeTokenAmount.greaterThanOrEqualTo(signedOrder.makerFee) && + transferrableMakerTokenAmount.greaterThanOrEqualTo(remainingMakerTokenAmount) && + signedOrder.makerTokenAddress !== zrxTokenAddress)) { + remainingFillableMakerTokenAmount = transferrableMakerTokenAmount; + } else { + remainingFillableMakerTokenAmount = this.calculatePartiallyFillableMakerTokenAmount( + transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, + remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, + zrxTokenAddress); + } const remainingFillableTakerTokenAmount = remainingFillableMakerTokenAmount .times(totalTakerTokenAmount) @@ -103,18 +111,10 @@ export class OrderStateUtils { }; return orderRelevantState; } - private calculateFillableMakerTokenAmount(makerTransferrable: BigNumber, makerFeeTransferrable: BigNumber, - remainingMakerAmount: BigNumber, remainingMakerFee: BigNumber, - totalMakerAmount: BigNumber, makerFee: BigNumber, - makerTokenAddress: string, zrxTokenAddress: string): BigNumber { - if (makerFee.isZero()) { - return BigNumber.min(makerTransferrable, remainingMakerAmount); - } - if (makerFeeTransferrable.greaterThanOrEqualTo(makerFee) && - makerTransferrable.greaterThanOrEqualTo(remainingMakerAmount) && - makerTokenAddress !== zrxTokenAddress) { - return BigNumber.min(makerTransferrable, remainingMakerAmount); - } + private calculatePartiallyFillableMakerTokenAmount(makerTransferrable: BigNumber, makerFeeTransferrable: BigNumber, + remainingMakerAmount: BigNumber, remainingMakerFee: BigNumber, + totalMakerAmount: BigNumber, makerFee: BigNumber, + makerTokenAddress: string, zrxTokenAddress: string): BigNumber { const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFee); let fillableTimesInMakerToken = makerTransferrable.dividedToIntegerBy(orderToFeeRatio); const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrable, remainingMakerFee); diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 9d432a713..7be552e7a 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -32,7 +32,7 @@ chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(); -describe('OrderStateWatcher', () => { +describe.only('OrderStateWatcher', () => { let web3: Web3; let zeroEx: ZeroEx; let tokens: Token[]; -- cgit v1.2.3 From 3bb6d8871b459c4f3975b600d391558188aa48b7 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 09:04:26 +1100 Subject: Readability variable names --- packages/0x.js/src/utils/order_state_utils.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 4c1bef64e..4d8f90f62 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -85,7 +85,7 @@ export class OrderStateUtils { let remainingFillableMakerTokenAmount; if (signedOrder.makerFee.isZero() || - (transferrableFeeTokenAmount.greaterThanOrEqualTo(signedOrder.makerFee) && + (transferrableFeeTokenAmount.greaterThanOrEqualTo(remainingFeeTokenAmount) && transferrableMakerTokenAmount.greaterThanOrEqualTo(remainingMakerTokenAmount) && signedOrder.makerTokenAddress !== zrxTokenAddress)) { remainingFillableMakerTokenAmount = transferrableMakerTokenAmount; @@ -111,17 +111,17 @@ export class OrderStateUtils { }; return orderRelevantState; } - private calculatePartiallyFillableMakerTokenAmount(makerTransferrable: BigNumber, makerFeeTransferrable: BigNumber, - remainingMakerAmount: BigNumber, remainingMakerFee: BigNumber, - totalMakerAmount: BigNumber, makerFee: BigNumber, + private calculatePartiallyFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, makerFeeTransferrableAmount: BigNumber, + remainingMakerAmount: BigNumber, remainingMakerFeeAmount: BigNumber, + totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, makerTokenAddress: string, zrxTokenAddress: string): BigNumber { - const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFee); - let fillableTimesInMakerToken = makerTransferrable.dividedToIntegerBy(orderToFeeRatio); - const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrable, remainingMakerFee); + const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFeeAmount); + const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrableAmount, remainingMakerFeeAmount); + let fillableTimesInMakerToken = makerTransferrableAmount.dividedToIntegerBy(orderToFeeRatio); if (makerTokenAddress === zrxTokenAddress) { - fillableTimesInMakerToken = makerTransferrable.plus(makerFeeTransferrable) - .dividedToIntegerBy(orderToFeeRatio.plus( - ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); + const totalFeeTokenPool = makerTransferrableAmount.plus(makerFeeTransferrableAmount); + fillableTimesInMakerToken = totalFeeTokenPool.dividedToIntegerBy( + orderToFeeRatio.plus(ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); } return BigNumber.min(fillableTimesInMakerToken.times(orderToFeeRatio), -- cgit v1.2.3 From 94ce7a54c3e352e671c0ccdde09535f85b05d353 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 09:20:37 +1100 Subject: Incorrect amount when is zero or non-zrx fee --- packages/0x.js/src/utils/order_state_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 4d8f90f62..1fe5e3ae4 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -88,7 +88,7 @@ export class OrderStateUtils { (transferrableFeeTokenAmount.greaterThanOrEqualTo(remainingFeeTokenAmount) && transferrableMakerTokenAmount.greaterThanOrEqualTo(remainingMakerTokenAmount) && signedOrder.makerTokenAddress !== zrxTokenAddress)) { - remainingFillableMakerTokenAmount = transferrableMakerTokenAmount; + remainingFillableMakerTokenAmount = remainingMakerTokenAmount; } else { remainingFillableMakerTokenAmount = this.calculatePartiallyFillableMakerTokenAmount( transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, -- cgit v1.2.3 From 7b373e29eae61b7b6e97ad180f6a6614b3242435 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 10:45:01 +1100 Subject: Split into Pooled and non-pooled --- packages/0x.js/src/utils/order_state_utils.ts | 62 +++++++++++++++++++++------ 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 1fe5e3ae4..437ff1d82 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -17,6 +17,7 @@ import {utils} from '../utils/utils'; import {constants} from '../utils/constants'; import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store'; import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; +import { TokenTransferProxyWrapper } from '../contract_wrappers/token_transfer_proxy_wrapper'; const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001; @@ -84,16 +85,16 @@ export class OrderStateUtils { const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); let remainingFillableMakerTokenAmount; - if (signedOrder.makerFee.isZero() || - (transferrableFeeTokenAmount.greaterThanOrEqualTo(remainingFeeTokenAmount) && - transferrableMakerTokenAmount.greaterThanOrEqualTo(remainingMakerTokenAmount) && - signedOrder.makerTokenAddress !== zrxTokenAddress)) { - remainingFillableMakerTokenAmount = remainingMakerTokenAmount; + if ((signedOrder.makerTokenAddress !== zrxTokenAddress || signedOrder.makerFee.isZero())) { + remainingFillableMakerTokenAmount = this.calculateFillableMakerTokenAmount( + transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, + remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, + zrxTokenAddress); } else { - remainingFillableMakerTokenAmount = this.calculatePartiallyFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, - remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, - zrxTokenAddress); + remainingFillableMakerTokenAmount = this.calculatePooledFillableMakerTokenAmount( + transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, + remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, + zrxTokenAddress); } const remainingFillableTakerTokenAmount = remainingFillableMakerTokenAmount @@ -111,8 +112,44 @@ export class OrderStateUtils { }; return orderRelevantState; } - private calculatePartiallyFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, makerFeeTransferrableAmount: BigNumber, - remainingMakerAmount: BigNumber, remainingMakerFeeAmount: BigNumber, + private calculateFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, + makerFeeTransferrableAmount: BigNumber, + remainingMakerAmount: BigNumber, + remainingMakerFeeAmount: BigNumber, + totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, + makerTokenAddress: string, zrxTokenAddress: string): BigNumber { + if (makerFeeAmount.isZero()) { + return BigNumber.min(remainingMakerAmount, makerTransferrableAmount); + } else if (makerTransferrableAmount.gte(remainingMakerAmount) && + makerFeeTransferrableAmount.gte(remainingMakerFeeAmount)) { + return makerTransferrableAmount; + } else { + return this.calculatePartiallyFillableMakerTokenAmount( + makerTransferrableAmount, makerFeeTransferrableAmount, remainingMakerAmount, + remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, + zrxTokenAddress); + } + } + private calculatePooledFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, + makerFeeTransferrableAmount: BigNumber, + remainingMakerAmount: BigNumber, + remainingMakerFeeAmount: BigNumber, + totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, + makerTokenAddress: string, zrxTokenAddress: string): BigNumber { + if (makerTransferrableAmount.plus(makerFeeTransferrableAmount).gte( + remainingMakerAmount.plus(remainingMakerFeeAmount))) { + return remainingMakerAmount; + } else { + return this.calculatePartiallyFillableMakerTokenAmount( + makerTransferrableAmount, makerFeeTransferrableAmount, remainingMakerAmount, + remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, + zrxTokenAddress); + } + } + private calculatePartiallyFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, + makerFeeTransferrableAmount: BigNumber, + remainingMakerAmount: BigNumber, + remainingMakerFeeAmount: BigNumber, totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, makerTokenAddress: string, zrxTokenAddress: string): BigNumber { const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFeeAmount); @@ -121,7 +158,8 @@ export class OrderStateUtils { if (makerTokenAddress === zrxTokenAddress) { const totalFeeTokenPool = makerTransferrableAmount.plus(makerFeeTransferrableAmount); fillableTimesInMakerToken = totalFeeTokenPool.dividedToIntegerBy( - orderToFeeRatio.plus(ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); + orderToFeeRatio.plus( + ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); } return BigNumber.min(fillableTimesInMakerToken.times(orderToFeeRatio), -- cgit v1.2.3 From c8f6e3f923e81ac0b024aa075e5532002a0bb38f Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 10:45:40 +1100 Subject: Remove only --- packages/0x.js/test/order_state_watcher_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 7be552e7a..9d432a713 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -32,7 +32,7 @@ chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(); -describe.only('OrderStateWatcher', () => { +describe('OrderStateWatcher', () => { let web3: Web3; let zeroEx: ZeroEx; let tokens: Token[]; -- cgit v1.2.3 From 7460a36ce2683c61b168192ced5fd3899a4f709c Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 10:55:28 +1100 Subject: calculate remaining maker token amount --- packages/0x.js/src/utils/order_state_utils.ts | 60 ++++++++++++++++----------- 1 file changed, 35 insertions(+), 25 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 437ff1d82..6a9a1310c 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -84,18 +84,10 @@ export class OrderStateUtils { const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); - let remainingFillableMakerTokenAmount; - if ((signedOrder.makerTokenAddress !== zrxTokenAddress || signedOrder.makerFee.isZero())) { - remainingFillableMakerTokenAmount = this.calculateFillableMakerTokenAmount( + const remainingFillableMakerTokenAmount = this.calculateRemainingMakerTokenAmount( transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, zrxTokenAddress); - } else { - remainingFillableMakerTokenAmount = this.calculatePooledFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, - remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, - zrxTokenAddress); - } const remainingFillableTakerTokenAmount = remainingFillableMakerTokenAmount .times(totalTakerTokenAmount) @@ -112,51 +104,69 @@ export class OrderStateUtils { }; return orderRelevantState; } - private calculateFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, - makerFeeTransferrableAmount: BigNumber, + private calculateRemainingMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, + remainingMakerAmount: BigNumber, + remainingMakerFeeAmount: BigNumber, + totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, + makerTokenAddress: string, zrxTokenAddress: string): BigNumber { + if ((makerTokenAddress !== zrxTokenAddress || makerFeeAmount.isZero())) { + return this.calculateFillableMakerTokenAmount( + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, + remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, + zrxTokenAddress); + } else { + return this.calculatePooledFillableMakerTokenAmount( + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, + remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, + zrxTokenAddress); + } + } + private calculateFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, remainingMakerAmount: BigNumber, remainingMakerFeeAmount: BigNumber, totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, makerTokenAddress: string, zrxTokenAddress: string): BigNumber { if (makerFeeAmount.isZero()) { - return BigNumber.min(remainingMakerAmount, makerTransferrableAmount); - } else if (makerTransferrableAmount.gte(remainingMakerAmount) && - makerFeeTransferrableAmount.gte(remainingMakerFeeAmount)) { - return makerTransferrableAmount; + return BigNumber.min(remainingMakerAmount, transferrableMakerTokenAmount); + } else if (transferrableMakerTokenAmount.gte(remainingMakerAmount) && + transferrableMakerFeeTokenAmount.gte(remainingMakerFeeAmount)) { + return transferrableMakerTokenAmount; } else { return this.calculatePartiallyFillableMakerTokenAmount( - makerTransferrableAmount, makerFeeTransferrableAmount, remainingMakerAmount, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, zrxTokenAddress); } } - private calculatePooledFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, - makerFeeTransferrableAmount: BigNumber, + private calculatePooledFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, remainingMakerAmount: BigNumber, remainingMakerFeeAmount: BigNumber, totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, makerTokenAddress: string, zrxTokenAddress: string): BigNumber { - if (makerTransferrableAmount.plus(makerFeeTransferrableAmount).gte( + if (transferrableMakerTokenAmount.plus(transferrableMakerFeeTokenAmount).gte( remainingMakerAmount.plus(remainingMakerFeeAmount))) { return remainingMakerAmount; } else { return this.calculatePartiallyFillableMakerTokenAmount( - makerTransferrableAmount, makerFeeTransferrableAmount, remainingMakerAmount, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, zrxTokenAddress); } } - private calculatePartiallyFillableMakerTokenAmount(makerTransferrableAmount: BigNumber, - makerFeeTransferrableAmount: BigNumber, + private calculatePartiallyFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, remainingMakerAmount: BigNumber, remainingMakerFeeAmount: BigNumber, totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, makerTokenAddress: string, zrxTokenAddress: string): BigNumber { const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFeeAmount); - const fillableTimesInFeeToken = BigNumber.min(makerFeeTransferrableAmount, remainingMakerFeeAmount); - let fillableTimesInMakerToken = makerTransferrableAmount.dividedToIntegerBy(orderToFeeRatio); + const fillableTimesInFeeToken = BigNumber.min(transferrableMakerFeeTokenAmount, remainingMakerFeeAmount); + let fillableTimesInMakerToken = transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); if (makerTokenAddress === zrxTokenAddress) { - const totalFeeTokenPool = makerTransferrableAmount.plus(makerFeeTransferrableAmount); + const totalFeeTokenPool = transferrableMakerTokenAmount.plus(transferrableMakerFeeTokenAmount); fillableTimesInMakerToken = totalFeeTokenPool.dividedToIntegerBy( orderToFeeRatio.plus( ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); -- cgit v1.2.3 From 519f1318c67ca4e40426cc23cce10dbb45985d6a Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 11:02:16 +1100 Subject: remove import --- packages/0x.js/src/utils/order_state_utils.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 6a9a1310c..80ab0de63 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -17,7 +17,6 @@ import {utils} from '../utils/utils'; import {constants} from '../utils/constants'; import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store'; import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; -import { TokenTransferProxyWrapper } from '../contract_wrappers/token_transfer_proxy_wrapper'; const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001; -- cgit v1.2.3 From d6589004c7f7c4d1af28c3aae110995da4c63531 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 20 Nov 2017 11:10:50 +1100 Subject: fix bug when fees and partial asymmetric --- packages/0x.js/src/utils/order_state_utils.ts | 2 +- packages/0x.js/test/order_state_watcher_test.ts | 26 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 80ab0de63..4187c7139 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -131,7 +131,7 @@ export class OrderStateUtils { return BigNumber.min(remainingMakerAmount, transferrableMakerTokenAmount); } else if (transferrableMakerTokenAmount.gte(remainingMakerAmount) && transferrableMakerFeeTokenAmount.gte(remainingMakerFeeAmount)) { - return transferrableMakerTokenAmount; + return remainingMakerAmount; } else { return this.calculatePartiallyFillableMakerTokenAmount( transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 9d432a713..8ab4939c0 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -321,6 +321,32 @@ describe('OrderStateWatcher', () => { makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount); })().catch(done); }); + it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => { + (async () => { + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), 18); + 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); + + const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), 18); + const transferTokenAmount = makerFee.sub(remainingTokenAmount); + zeroEx.orderStateWatcher.addOrder(signedOrder); + + const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const validOrderState = orderState as OrderStateValid; + const orderRelevantState = validOrderState.orderRelevantState; + expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( + remainingTokenAmount); + done(); + }); + zeroEx.orderStateWatcher.subscribe(callback); + await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount); + })().catch(done); + }); it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => { (async () => { const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); -- cgit v1.2.3 From c858ff61f7ef8b1941f3f5832713b1d87d92a2af Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 20 Nov 2017 16:07:16 -0600 Subject: Add an order state cache to filter out duplicate events --- packages/0x.js/src/order_watcher/order_state_watcher.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts index 33fa69b1c..648345c48 100644 --- a/packages/0x.js/src/order_watcher/order_state_watcher.ts +++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts @@ -43,6 +43,10 @@ interface OrderByOrderHash { [orderHash: string]: SignedOrder; } +interface OrderStateByOrderHash { + [orderHash: string]: OrderState; +} + /** * This class includes all the functionality related to watching a set of orders * for potential changes in order validity/fillability. The orderWatcher notifies @@ -50,6 +54,7 @@ interface OrderByOrderHash { * the order should be deemed invalid. */ export class OrderStateWatcher { + private _orderStateByOrderHashCache: OrderStateByOrderHash = {}; private _orderByOrderHash: OrderByOrderHash = {}; private _dependentOrderHashes: DependentOrderHashes = {}; private _callbackIfExists?: OnOrderStateChangeCallback; @@ -96,6 +101,7 @@ export class OrderStateWatcher { return; // noop } delete this._orderByOrderHash[orderHash]; + delete this._orderStateByOrderHashCache[orderHash]; const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper; const zrxTokenAddress = await exchange.getZRXTokenAddressAsync(); this.removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash); @@ -210,6 +216,12 @@ export class OrderStateWatcher { if (_.isUndefined(this._callbackIfExists)) { break; // Unsubscribe was called } + if (_.isEqual(orderState, this._orderStateByOrderHashCache[orderHash])) { + // Actual order state didn't change + continue; + } else { + this._orderStateByOrderHashCache[orderHash] = orderState; + } this._callbackIfExists(orderState); } } -- cgit v1.2.3 From fb812d59b0f0c11f50669899ffb6818d5ddeec1f Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 09:50:37 +1100 Subject: Fixes before refactor --- packages/0x.js/src/utils/order_state_utils.ts | 82 +++++++++++++++------------ 1 file changed, 47 insertions(+), 35 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 4187c7139..78333e907 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -78,14 +78,14 @@ export class OrderStateUtils { const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount) .dividedToIntegerBy(totalTakerTokenAmount); - const remainingFeeTokenAmount = remainingTakerTokenAmount.times(signedOrder.makerFee) - .dividedToIntegerBy(totalTakerTokenAmount); + const remainingMakerFeeAmount = remainingTakerTokenAmount.times(signedOrder.makerFee) + .dividedToIntegerBy(totalTakerTokenAmount); const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); const remainingFillableMakerTokenAmount = this.calculateRemainingMakerTokenAmount( transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, - remainingFeeTokenAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, + remainingMakerFeeAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, zrxTokenAddress); const remainingFillableTakerTokenAmount = remainingFillableMakerTokenAmount @@ -107,52 +107,63 @@ export class OrderStateUtils { transferrableMakerFeeTokenAmount: BigNumber, remainingMakerAmount: BigNumber, remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, - makerTokenAddress: string, zrxTokenAddress: string): BigNumber { + totalMakerAmount: BigNumber, + makerFeeAmount: BigNumber, + makerTokenAddress: string, + zrxTokenAddress: string): BigNumber { if ((makerTokenAddress !== zrxTokenAddress || makerFeeAmount.isZero())) { - return this.calculateFillableMakerTokenAmount( + return this.computeFillableMakerTokenAmountWhenMakerTokenIsNotZRX( transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, zrxTokenAddress); } else { - return this.calculatePooledFillableMakerTokenAmount( + return this.computeFillableMakerTokenAmountWhenMakerTokenIsZRX( transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, zrxTokenAddress); } } - private calculateFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerAmount: BigNumber, - remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, - makerTokenAddress: string, zrxTokenAddress: string): BigNumber { + private computeFillableMakerTokenAmountWhenMakerTokenIsNotZRX(transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, + remainingMakerAmount: BigNumber, + remainingMakerFeeAmount: BigNumber, + totalMakerAmount: BigNumber, + makerFeeAmount: BigNumber, + makerTokenAddress: string, + zrxTokenAddress: string): BigNumber { + const hasSufficientFundsForTransferAmount = transferrableMakerTokenAmount.gte(remainingMakerAmount); + const hasSufficientFundsForFeeAmount = transferrableMakerFeeTokenAmount.gte(remainingMakerFeeAmount); + const hasSufficientFundsForFeeAndTransferAmount = (hasSufficientFundsForTransferAmount && + hasSufficientFundsForFeeAmount); + if (makerFeeAmount.isZero()) { return BigNumber.min(remainingMakerAmount, transferrableMakerTokenAmount); - } else if (transferrableMakerTokenAmount.gte(remainingMakerAmount) && - transferrableMakerFeeTokenAmount.gte(remainingMakerFeeAmount)) { + } else if (hasSufficientFundsForFeeAndTransferAmount) { return remainingMakerAmount; } else { return this.calculatePartiallyFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, - remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, - zrxTokenAddress); + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, + remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, + zrxTokenAddress); } } - private calculatePooledFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerAmount: BigNumber, - remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, - makerTokenAddress: string, zrxTokenAddress: string): BigNumber { - if (transferrableMakerTokenAmount.plus(transferrableMakerFeeTokenAmount).gte( - remainingMakerAmount.plus(remainingMakerFeeAmount))) { + private computeFillableMakerTokenAmountWhenMakerTokenIsZRX(transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, + remainingMakerAmount: BigNumber, + remainingMakerFeeAmount: BigNumber, + totalMakerAmount: BigNumber, + makerFeeAmount: BigNumber, + makerTokenAddress: string, + zrxTokenAddress: string): BigNumber { + const totalZRXTransferAmount = remainingMakerAmount.plus(remainingMakerFeeAmount); + const hasSufficientFundsForFeeAndTransferAmount = transferrableMakerTokenAmount.gte(totalZRXTransferAmount); + if (hasSufficientFundsForFeeAndTransferAmount) { return remainingMakerAmount; } else { return this.calculatePartiallyFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, - remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, - zrxTokenAddress); + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, + remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, + zrxTokenAddress); } } private calculatePartiallyFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, @@ -165,14 +176,15 @@ export class OrderStateUtils { const fillableTimesInFeeToken = BigNumber.min(transferrableMakerFeeTokenAmount, remainingMakerFeeAmount); let fillableTimesInMakerToken = transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); if (makerTokenAddress === zrxTokenAddress) { - const totalFeeTokenPool = transferrableMakerTokenAmount.plus(transferrableMakerFeeTokenAmount); - fillableTimesInMakerToken = totalFeeTokenPool.dividedToIntegerBy( - orderToFeeRatio.plus( - ZeroEx.toBaseUnitAmount(new BigNumber(1), 18))); + // when zrx == maker token transferrable maker == transfer + const totalZRXTokenPooled = transferrableMakerTokenAmount; + fillableTimesInMakerToken = totalZRXTokenPooled.dividedToIntegerBy( + orderToFeeRatio.plus(new BigNumber(1))); } - return BigNumber.min(fillableTimesInMakerToken.times(orderToFeeRatio), - fillableTimesInFeeToken.times(orderToFeeRatio)); + const partiallyFillableMakerTokenAmount = fillableTimesInMakerToken.times(orderToFeeRatio); + const partiallyFillableFeeTokenAmount = fillableTimesInFeeToken.times(orderToFeeRatio); + return BigNumber.min(partiallyFillableMakerTokenAmount, partiallyFillableFeeTokenAmount); } private validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void { const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add( -- cgit v1.2.3 From 4bd5789203aa9f75cc7834aa0e29412ba3abba4f Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 10:30:29 +1100 Subject: Refactor into a calculator class --- .../order_watcher/remaining_fillable_calculator.ts | 68 ++++++++++++++ packages/0x.js/src/utils/order_state_utils.ts | 101 ++------------------- 2 files changed, 76 insertions(+), 93 deletions(-) create mode 100644 packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts new file mode 100644 index 000000000..fe373eae4 --- /dev/null +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -0,0 +1,68 @@ +import { + SignedOrder, +} from '../types'; +import { BigNumber } from 'bignumber.js'; +export class RemainingFillableCalculator { + private _signedOrder: SignedOrder; + private _isMakerTokenZRX: boolean; + private _transferrableMakerTokenAmount: BigNumber; + private _transferrableMakerFeeTokenAmount: BigNumber; + private _remainingMakerTokenAmount: BigNumber; + private _remainingMakerFeeAmount: BigNumber; + constructor(signedOrder: SignedOrder, + zrxAddress: string, + transferrableMakerTokenAmount: BigNumber, + transferrableMakerFeeTokenAmount: BigNumber, + remainingMakerTokenAmount: BigNumber) { + this._signedOrder = signedOrder; + this._isMakerTokenZRX = signedOrder.makerTokenAddress === zrxAddress; + this._transferrableMakerTokenAmount = transferrableMakerTokenAmount; + this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount; + this._remainingMakerTokenAmount = remainingMakerTokenAmount; + this._remainingMakerFeeAmount = remainingMakerTokenAmount.times(signedOrder.makerFee) + .dividedToIntegerBy(signedOrder.makerTokenAmount); + } + public computeRemainingMakerFillable(): BigNumber { + if (this.hasSufficientFundsForFeeAndTransferAmount()) { + return this._remainingMakerTokenAmount; + } + if (this._signedOrder.makerFee.isZero()) { + return BigNumber.min(this._remainingMakerTokenAmount, this._transferrableMakerTokenAmount); + } else { + return this.calculatePartiallyFillableMakerTokenAmount(); + } + } + public computeRemainingTakerFillable(): BigNumber { + return this.computeRemainingMakerFillable().times(this._signedOrder.takerTokenAmount) + .dividedToIntegerBy(this._signedOrder.makerTokenAmount); + } + private hasSufficientFundsForFeeAndTransferAmount(): boolean { + if (this._isMakerTokenZRX) { + const totalZRXTransferAmount = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount); + return this._transferrableMakerTokenAmount.gte(totalZRXTransferAmount); + } else { + const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.gte( + this._remainingMakerTokenAmount); + const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.gte( + this._remainingMakerFeeAmount); + return (hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount); + } + } + + private calculatePartiallyFillableMakerTokenAmount(): BigNumber { + const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedToIntegerBy(this._signedOrder.makerFee); + const fillableTimesInFeeToken = BigNumber.min(this._transferrableMakerFeeTokenAmount, + this._remainingMakerFeeAmount); + let fillableTimesInMakerToken = this._transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); + if (this._isMakerTokenZRX) { + // when zrx == maker token transferrable maker == transfer + const totalZRXTokenPooled = this._transferrableMakerTokenAmount; + fillableTimesInMakerToken = totalZRXTokenPooled.dividedToIntegerBy( + orderToFeeRatio.plus(new BigNumber(1))); + + } + const partiallyFillableMakerTokenAmount = fillableTimesInMakerToken.times(orderToFeeRatio); + const partiallyFillableFeeTokenAmount = fillableTimesInFeeToken.times(orderToFeeRatio); + return BigNumber.min(partiallyFillableMakerTokenAmount, partiallyFillableFeeTokenAmount); + } +} diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 78333e907..9ff26a7f1 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -17,6 +17,7 @@ import {utils} from '../utils/utils'; import {constants} from '../utils/constants'; import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store'; import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; +import {RemainingFillableCalculator} from '../order_watcher/remaining_fillable_calculator'; const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001; @@ -78,19 +79,16 @@ export class OrderStateUtils { const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount) .dividedToIntegerBy(totalTakerTokenAmount); - const remainingMakerFeeAmount = remainingTakerTokenAmount.times(signedOrder.makerFee) - .dividedToIntegerBy(totalTakerTokenAmount); const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); - const remainingFillableMakerTokenAmount = this.calculateRemainingMakerTokenAmount( - transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount, - remainingMakerFeeAmount, totalMakerTokenAmount, signedOrder.makerFee, signedOrder.makerTokenAddress, - zrxTokenAddress); - - const remainingFillableTakerTokenAmount = remainingFillableMakerTokenAmount - .times(totalTakerTokenAmount) - .dividedToIntegerBy(totalMakerTokenAmount); + const remainingFillableCalculator = new RemainingFillableCalculator(signedOrder, + zrxTokenAddress, + transferrableMakerTokenAmount, + transferrableFeeTokenAmount, + remainingMakerTokenAmount); + const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable(); + const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable(); const orderRelevantState = { makerBalance, makerProxyAllowance, @@ -103,89 +101,6 @@ export class OrderStateUtils { }; return orderRelevantState; } - private calculateRemainingMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerAmount: BigNumber, - remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, - makerFeeAmount: BigNumber, - makerTokenAddress: string, - zrxTokenAddress: string): BigNumber { - if ((makerTokenAddress !== zrxTokenAddress || makerFeeAmount.isZero())) { - return this.computeFillableMakerTokenAmountWhenMakerTokenIsNotZRX( - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, - remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, - zrxTokenAddress); - } else { - return this.computeFillableMakerTokenAmountWhenMakerTokenIsZRX( - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, - remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, - zrxTokenAddress); - } - } - private computeFillableMakerTokenAmountWhenMakerTokenIsNotZRX(transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerAmount: BigNumber, - remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, - makerFeeAmount: BigNumber, - makerTokenAddress: string, - zrxTokenAddress: string): BigNumber { - const hasSufficientFundsForTransferAmount = transferrableMakerTokenAmount.gte(remainingMakerAmount); - const hasSufficientFundsForFeeAmount = transferrableMakerFeeTokenAmount.gte(remainingMakerFeeAmount); - const hasSufficientFundsForFeeAndTransferAmount = (hasSufficientFundsForTransferAmount && - hasSufficientFundsForFeeAmount); - - if (makerFeeAmount.isZero()) { - return BigNumber.min(remainingMakerAmount, transferrableMakerTokenAmount); - } else if (hasSufficientFundsForFeeAndTransferAmount) { - return remainingMakerAmount; - } else { - return this.calculatePartiallyFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, - remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, - zrxTokenAddress); - } - } - private computeFillableMakerTokenAmountWhenMakerTokenIsZRX(transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerAmount: BigNumber, - remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, - makerFeeAmount: BigNumber, - makerTokenAddress: string, - zrxTokenAddress: string): BigNumber { - const totalZRXTransferAmount = remainingMakerAmount.plus(remainingMakerFeeAmount); - const hasSufficientFundsForFeeAndTransferAmount = transferrableMakerTokenAmount.gte(totalZRXTransferAmount); - if (hasSufficientFundsForFeeAndTransferAmount) { - return remainingMakerAmount; - } else { - return this.calculatePartiallyFillableMakerTokenAmount( - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerAmount, - remainingMakerFeeAmount, totalMakerAmount, makerFeeAmount, makerTokenAddress, - zrxTokenAddress); - } - } - private calculatePartiallyFillableMakerTokenAmount(transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerAmount: BigNumber, - remainingMakerFeeAmount: BigNumber, - totalMakerAmount: BigNumber, makerFeeAmount: BigNumber, - makerTokenAddress: string, zrxTokenAddress: string): BigNumber { - const orderToFeeRatio = totalMakerAmount.dividedToIntegerBy(makerFeeAmount); - const fillableTimesInFeeToken = BigNumber.min(transferrableMakerFeeTokenAmount, remainingMakerFeeAmount); - let fillableTimesInMakerToken = transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); - if (makerTokenAddress === zrxTokenAddress) { - // when zrx == maker token transferrable maker == transfer - const totalZRXTokenPooled = transferrableMakerTokenAmount; - fillableTimesInMakerToken = totalZRXTokenPooled.dividedToIntegerBy( - orderToFeeRatio.plus(new BigNumber(1))); - - } - const partiallyFillableMakerTokenAmount = fillableTimesInMakerToken.times(orderToFeeRatio); - const partiallyFillableFeeTokenAmount = fillableTimesInFeeToken.times(orderToFeeRatio); - return BigNumber.min(partiallyFillableMakerTokenAmount, partiallyFillableFeeTokenAmount); - } private validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void { const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add( orderRelevantState.filledTakerTokenAmount, -- cgit v1.2.3 From 5b8f84f59a5996458d3da5faf0fc7c3fa6c93ee6 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 12:58:17 +1100 Subject: Added unit test for calculator --- .../test/remaining_fillable_calculator_test.ts | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 packages/0x.js/test/remaining_fillable_calculator_test.ts (limited to 'packages') diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts new file mode 100644 index 000000000..7dea660b8 --- /dev/null +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -0,0 +1,89 @@ +import 'mocha'; +import * as chai from 'chai'; +import BigNumber from 'bignumber.js'; +import { chaiSetup } from './utils/chai_setup'; +import { RemainingFillableCalculator } from '../src/order_watcher/remaining_fillable_calculator'; +import { SignedOrder, ECSignature } from '../src/types'; +import { TokenUtils } from './utils/token_utils'; + +chaiSetup.configure(); +const expect = chai.expect; + +describe.only('RemainingFillableCalculator', () => { + let calculator: RemainingFillableCalculator; + let signedOrder: SignedOrder; + let makerToken: string; + let takerToken: string; + let zrxToken: string; + let transferrableMakerTokenAmount: BigNumber; + let transferrableMakerFeeTokenAmount: BigNumber; + let remainingMakerTokenAmount: BigNumber; + let makerAmount: BigNumber; + let takerAmount: BigNumber; + let makerFee: BigNumber; + const zero: BigNumber = new BigNumber(0); + const zeroAddress = '0x0'; + const signature: ECSignature = { v: 27, r: '', s: ''}; + before(async () => { + [makerToken, takerToken, zrxToken] = ['0x1', '0x2', '0x3']; + [makerAmount, takerAmount, makerFee] = [new BigNumber(50), new BigNumber(5), new BigNumber(1)]; + }); + function buildSignedOrder(): SignedOrder { + return { ecSignature: signature, + exchangeContractAddress: zeroAddress, + feeRecipient: zeroAddress, + maker: zeroAddress, + taker: zeroAddress, + makerFee: (makerFee || zero), + takerFee: zero, + makerTokenAmount: makerAmount, + takerTokenAmount: takerAmount, + makerTokenAddress: makerToken, + takerTokenAddress: takerToken, + salt: zero, + expirationUnixTimestampSec: zero }; + } + it('calculates the correct amount when partially filled and funds available', () => { + signedOrder = buildSignedOrder(); + remainingMakerTokenAmount = new BigNumber(1); + transferrableMakerTokenAmount = new BigNumber(100); + transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); + }); + describe('Maker token is NOT ZRX', () => { + it('calculates the amount to be 0 when all fee funds move', () => { + signedOrder = buildSignedOrder(); + transferrableMakerTokenAmount = new BigNumber(100); + transferrableMakerFeeTokenAmount = zero; + remainingMakerTokenAmount = signedOrder.makerTokenAmount; + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero); + }); + }); + describe('Maker Token is ZRX', () => { + before(async () => { + makerToken = zrxToken; + }); + it('calculates the correct amount when partially filled and funds available', () => { + signedOrder = buildSignedOrder(); + transferrableMakerTokenAmount = new BigNumber(100); + transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + remainingMakerTokenAmount = new BigNumber(1); + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); + }); + it('calculates the amount to be 0 when all fee funds move', () => { + signedOrder = buildSignedOrder(); + transferrableMakerTokenAmount = zero; + transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + remainingMakerTokenAmount = signedOrder.makerTokenAmount; + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero); + }); + }); +}); -- cgit v1.2.3 From bbcee8dfa735ae8261b29cd917a99c97c551ed5d Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 13:04:36 +1100 Subject: Move to base units --- .../0x.js/test/remaining_fillable_calculator_test.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts index 7dea660b8..f1821551f 100644 --- a/packages/0x.js/test/remaining_fillable_calculator_test.ts +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -5,6 +5,7 @@ import { chaiSetup } from './utils/chai_setup'; import { RemainingFillableCalculator } from '../src/order_watcher/remaining_fillable_calculator'; import { SignedOrder, ECSignature } from '../src/types'; import { TokenUtils } from './utils/token_utils'; +import { ZeroEx } from '../src/0x'; chaiSetup.configure(); const expect = chai.expect; @@ -26,7 +27,12 @@ describe.only('RemainingFillableCalculator', () => { const signature: ECSignature = { v: 27, r: '', s: ''}; before(async () => { [makerToken, takerToken, zrxToken] = ['0x1', '0x2', '0x3']; - [makerAmount, takerAmount, makerFee] = [new BigNumber(50), new BigNumber(5), new BigNumber(1)]; + [makerAmount, takerAmount, makerFee] = [ZeroEx.toBaseUnitAmount(new BigNumber(50), 18), + ZeroEx.toBaseUnitAmount(new BigNumber(5), 18), + ZeroEx.toBaseUnitAmount(new BigNumber(1), 18)]; + [transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [ + ZeroEx.toBaseUnitAmount(new BigNumber(50), 18), + ZeroEx.toBaseUnitAmount(new BigNumber(5), 18)]; }); function buildSignedOrder(): SignedOrder { return { ecSignature: signature, @@ -45,9 +51,7 @@ describe.only('RemainingFillableCalculator', () => { } it('calculates the correct amount when partially filled and funds available', () => { signedOrder = buildSignedOrder(); - remainingMakerTokenAmount = new BigNumber(1); - transferrableMakerTokenAmount = new BigNumber(100); - transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); calculator = new RemainingFillableCalculator(signedOrder, zrxToken, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); @@ -55,7 +59,6 @@ describe.only('RemainingFillableCalculator', () => { describe('Maker token is NOT ZRX', () => { it('calculates the amount to be 0 when all fee funds move', () => { signedOrder = buildSignedOrder(); - transferrableMakerTokenAmount = new BigNumber(100); transferrableMakerFeeTokenAmount = zero; remainingMakerTokenAmount = signedOrder.makerTokenAmount; calculator = new RemainingFillableCalculator(signedOrder, zrxToken, @@ -69,9 +72,7 @@ describe.only('RemainingFillableCalculator', () => { }); it('calculates the correct amount when partially filled and funds available', () => { signedOrder = buildSignedOrder(); - transferrableMakerTokenAmount = new BigNumber(100); - transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; - remainingMakerTokenAmount = new BigNumber(1); + remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); calculator = new RemainingFillableCalculator(signedOrder, zrxToken, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); @@ -79,7 +80,7 @@ describe.only('RemainingFillableCalculator', () => { it('calculates the amount to be 0 when all fee funds move', () => { signedOrder = buildSignedOrder(); transferrableMakerTokenAmount = zero; - transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + transferrableMakerFeeTokenAmount = zero; remainingMakerTokenAmount = signedOrder.makerTokenAmount; calculator = new RemainingFillableCalculator(signedOrder, zrxToken, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); -- cgit v1.2.3 From 43128234bbb9715094c24c99b6a001a5290fcefd Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 14:00:21 +1100 Subject: setting a failed test --- .../test/remaining_fillable_calculator_test.ts | 57 +++++++++++++++++----- 1 file changed, 46 insertions(+), 11 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts index f1821551f..5d7cd9277 100644 --- a/packages/0x.js/test/remaining_fillable_calculator_test.ts +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -25,7 +25,7 @@ describe.only('RemainingFillableCalculator', () => { const zero: BigNumber = new BigNumber(0); const zeroAddress = '0x0'; const signature: ECSignature = { v: 27, r: '', s: ''}; - before(async () => { + beforeEach(async () => { [makerToken, takerToken, zrxToken] = ['0x1', '0x2', '0x3']; [makerAmount, takerAmount, makerFee] = [ZeroEx.toBaseUnitAmount(new BigNumber(50), 18), ZeroEx.toBaseUnitAmount(new BigNumber(5), 18), @@ -49,15 +49,31 @@ describe.only('RemainingFillableCalculator', () => { salt: zero, expirationUnixTimestampSec: zero }; } - it('calculates the correct amount when partially filled and funds available', () => { - signedOrder = buildSignedOrder(); - remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); - expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); - }); describe('Maker token is NOT ZRX', () => { - it('calculates the amount to be 0 when all fee funds move', () => { + it('calculates the correct amount when balance is less than remaining fillable', () => { + signedOrder = buildSignedOrder(); + const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount); + transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount); + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount); + }); + it('calculates the correct amount when unfilled and funds available', () => { + signedOrder = buildSignedOrder(); + remainingMakerTokenAmount = signedOrder.makerTokenAmount; + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + 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), 18); + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + 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; @@ -67,9 +83,28 @@ describe.only('RemainingFillableCalculator', () => { }); }); describe('Maker Token is ZRX', () => { - before(async () => { + beforeEach(async () => { makerToken = zrxToken; }); + it('calculates the correct amount when balance is less than remaining fillable', () => { + signedOrder = buildSignedOrder(); + const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount); + transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount); + transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount); + }); + it('calculates the correct amount when unfilled and funds available', () => { + signedOrder = buildSignedOrder(); + transferrableMakerTokenAmount = makerAmount.plus(makerFee); + transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + remainingMakerTokenAmount = signedOrder.makerTokenAmount; + calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + 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), 18); @@ -77,7 +112,7 @@ describe.only('RemainingFillableCalculator', () => { transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); }); - it('calculates the amount to be 0 when all fee funds move', () => { + it('calculates the amount to be 0 when all fee funds are transferred', () => { signedOrder = buildSignedOrder(); transferrableMakerTokenAmount = zero; transferrableMakerFeeTokenAmount = zero; -- cgit v1.2.3 From da03331015b810505cfaae1445424f61ce05c656 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 14:51:19 +1100 Subject: Unit test edge case for ZRX and ZRX partial fill --- .../order_watcher/remaining_fillable_calculator.ts | 23 ++++--- packages/0x.js/src/utils/order_state_utils.ts | 3 +- .../test/remaining_fillable_calculator_test.ts | 77 ++++++++++++---------- 3 files changed, 59 insertions(+), 44 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts index fe373eae4..45f60ada3 100644 --- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -10,12 +10,12 @@ export class RemainingFillableCalculator { private _remainingMakerTokenAmount: BigNumber; private _remainingMakerFeeAmount: BigNumber; constructor(signedOrder: SignedOrder, - zrxAddress: string, + isMakerTokenZRX: boolean, transferrableMakerTokenAmount: BigNumber, transferrableMakerFeeTokenAmount: BigNumber, remainingMakerTokenAmount: BigNumber) { this._signedOrder = signedOrder; - this._isMakerTokenZRX = signedOrder.makerTokenAddress === zrxAddress; + this._isMakerTokenZRX = isMakerTokenZRX; this._transferrableMakerTokenAmount = transferrableMakerTokenAmount; this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount; this._remainingMakerTokenAmount = remainingMakerTokenAmount; @@ -51,18 +51,21 @@ export class RemainingFillableCalculator { private calculatePartiallyFillableMakerTokenAmount(): BigNumber { const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedToIntegerBy(this._signedOrder.makerFee); - const fillableTimesInFeeToken = BigNumber.min(this._transferrableMakerFeeTokenAmount, - this._remainingMakerFeeAmount); - let fillableTimesInMakerToken = this._transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); + // Maximum number of times the Maker can fill the order, given the fees + const fillableTimesInFeeTokenUnits = BigNumber.min(this._transferrableMakerFeeTokenAmount, + this._remainingMakerFeeAmount); + // Maximum number of times the Maker can fill the order, given the Maker Token Balance + let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); if (this._isMakerTokenZRX) { - // when zrx == maker token transferrable maker == transfer const totalZRXTokenPooled = this._transferrableMakerTokenAmount; - fillableTimesInMakerToken = totalZRXTokenPooled.dividedToIntegerBy( - orderToFeeRatio.plus(new BigNumber(1))); + // The purchasing power here is less as the tokens are taken from the same Pool + // For every one number of fills, we have to take an extra ZRX out of the pool + fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedToIntegerBy( + orderToFeeRatio.plus(new BigNumber(1))); } - const partiallyFillableMakerTokenAmount = fillableTimesInMakerToken.times(orderToFeeRatio); - const partiallyFillableFeeTokenAmount = fillableTimesInFeeToken.times(orderToFeeRatio); + const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits.times(orderToFeeRatio); + const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenUnits.times(orderToFeeRatio); return BigNumber.min(partiallyFillableMakerTokenAmount, partiallyFillableFeeTokenAmount); } } diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 9ff26a7f1..1d8f02a18 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -82,8 +82,9 @@ export class OrderStateUtils { const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]); + const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress; const remainingFillableCalculator = new RemainingFillableCalculator(signedOrder, - zrxTokenAddress, + isMakerTokenZRX, transferrableMakerTokenAmount, transferrableFeeTokenAmount, remainingMakerTokenAmount); diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts index 5d7cd9277..5b7fd63f1 100644 --- a/packages/0x.js/test/remaining_fillable_calculator_test.ts +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -13,26 +13,26 @@ const expect = chai.expect; describe.only('RemainingFillableCalculator', () => { let calculator: RemainingFillableCalculator; let signedOrder: SignedOrder; - let makerToken: string; - let takerToken: string; - let zrxToken: string; let transferrableMakerTokenAmount: BigNumber; let transferrableMakerFeeTokenAmount: BigNumber; let remainingMakerTokenAmount: BigNumber; let makerAmount: BigNumber; let takerAmount: BigNumber; let makerFee: BigNumber; + let isMakerTokenZRX: boolean; + const makerToken: string = '0x1'; + const takerToken: string = '0x2'; + const decimals: number = 4; const zero: BigNumber = new BigNumber(0); const zeroAddress = '0x0'; const signature: ECSignature = { v: 27, r: '', s: ''}; beforeEach(async () => { - [makerToken, takerToken, zrxToken] = ['0x1', '0x2', '0x3']; - [makerAmount, takerAmount, makerFee] = [ZeroEx.toBaseUnitAmount(new BigNumber(50), 18), - ZeroEx.toBaseUnitAmount(new BigNumber(5), 18), - ZeroEx.toBaseUnitAmount(new BigNumber(1), 18)]; + [makerAmount, takerAmount, makerFee] = [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), 18), - ZeroEx.toBaseUnitAmount(new BigNumber(5), 18)]; + ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals), + ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals)]; }); function buildSignedOrder(): SignedOrder { return { ecSignature: signature, @@ -50,26 +50,20 @@ describe.only('RemainingFillableCalculator', () => { expirationUnixTimestampSec: zero }; } describe('Maker token is NOT ZRX', () => { - it('calculates the correct amount when balance is less than remaining fillable', () => { - signedOrder = buildSignedOrder(); - const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); - remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount); - transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount); - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, - transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); - expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount); + before(async () => { + isMakerTokenZRX = false; }); it('calculates the correct amount when unfilled and funds available', () => { signedOrder = buildSignedOrder(); remainingMakerTokenAmount = signedOrder.makerTokenAmount; - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + 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), 18); - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals); + calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); }); @@ -77,38 +71,37 @@ describe.only('RemainingFillableCalculator', () => { signedOrder = buildSignedOrder(); transferrableMakerFeeTokenAmount = zero; remainingMakerTokenAmount = signedOrder.makerTokenAmount; - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero); }); - }); - describe('Maker Token is ZRX', () => { - beforeEach(async () => { - makerToken = zrxToken; - }); it('calculates the correct amount when balance is less than remaining fillable', () => { signedOrder = buildSignedOrder(); - const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals); remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount); transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount); - transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount); }); + }); + describe('Maker Token is ZRX', () => { + before(async () => { + isMakerTokenZRX = true; + }); it('calculates the correct amount when unfilled and funds available', () => { signedOrder = buildSignedOrder(); transferrableMakerTokenAmount = makerAmount.plus(makerFee); transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; remainingMakerTokenAmount = signedOrder.makerTokenAmount; - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + 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), 18); - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals); + calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount); }); @@ -117,9 +110,27 @@ describe.only('RemainingFillableCalculator', () => { transferrableMakerTokenAmount = zero; transferrableMakerFeeTokenAmount = zero; remainingMakerTokenAmount = signedOrder.makerTokenAmount; - calculator = new RemainingFillableCalculator(signedOrder, zrxToken, + 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', () => { + signedOrder = buildSignedOrder(); + const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals); + remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount); + transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount); + transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; + + const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee); + const expectedRemainingAmount = new BigNumber(450950); + const numberOfFillsInRatio = expectedRemainingAmount.dividedToIntegerBy(orderToFeeRatio); + calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, + transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); + const calculatedRemainingAmount = calculator.computeRemainingMakerFillable(); + const calculatedRemainingAmountPlusFees = calculatedRemainingAmount.plus(numberOfFillsInRatio); + expect(calculatedRemainingAmount).to.be.bignumber.equal(expectedRemainingAmount); + expect(calculatedRemainingAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount); + expect(calculatedRemainingAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount); + }); }); }); -- cgit v1.2.3 From d16f0508bdae9941a0eb5e042bbade5078da1c00 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 14:57:08 +1100 Subject: totalZRXTransferAmount -> totalZRXTransferAmountRequired --- packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts index 45f60ada3..8141dd73c 100644 --- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -38,8 +38,8 @@ export class RemainingFillableCalculator { } private hasSufficientFundsForFeeAndTransferAmount(): boolean { if (this._isMakerTokenZRX) { - const totalZRXTransferAmount = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount); - return this._transferrableMakerTokenAmount.gte(totalZRXTransferAmount); + const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount); + return this._transferrableMakerTokenAmount.gte(totalZRXTransferAmountRequired); } else { const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.gte( this._remainingMakerTokenAmount); -- cgit v1.2.3 From 335b9629b85ac394afc7afb649de29ee608764b5 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 21 Nov 2017 15:00:09 +1100 Subject: calculatedFillableAmountPlusFees --- packages/0x.js/test/remaining_fillable_calculator_test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts index 5b7fd63f1..ca541237f 100644 --- a/packages/0x.js/test/remaining_fillable_calculator_test.ts +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -122,15 +122,15 @@ describe.only('RemainingFillableCalculator', () => { transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee); - const expectedRemainingAmount = new BigNumber(450950); - const numberOfFillsInRatio = expectedRemainingAmount.dividedToIntegerBy(orderToFeeRatio); + const expectedFillableAmount = new BigNumber(450950); + const numberOfFillsInRatio = expectedFillableAmount.dividedToIntegerBy(orderToFeeRatio); calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); - const calculatedRemainingAmount = calculator.computeRemainingMakerFillable(); - const calculatedRemainingAmountPlusFees = calculatedRemainingAmount.plus(numberOfFillsInRatio); - expect(calculatedRemainingAmount).to.be.bignumber.equal(expectedRemainingAmount); - expect(calculatedRemainingAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount); - expect(calculatedRemainingAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount); + const calculatedFillableAmount = calculator.computeRemainingMakerFillable(); + const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio); + expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount); + expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount); + expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount); }); }); }); -- cgit v1.2.3 From a1411e3d52c7692949b9693c0e7a3813e51a4bdb Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 22 Nov 2017 08:05:47 +1100 Subject: Remove only --- packages/0x.js/test/remaining_fillable_calculator_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts index ca541237f..0b1f517fa 100644 --- a/packages/0x.js/test/remaining_fillable_calculator_test.ts +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -10,7 +10,7 @@ import { ZeroEx } from '../src/0x'; chaiSetup.configure(); const expect = chai.expect; -describe.only('RemainingFillableCalculator', () => { +describe('RemainingFillableCalculator', () => { let calculator: RemainingFillableCalculator; let signedOrder: SignedOrder; let transferrableMakerTokenAmount: BigNumber; -- cgit v1.2.3 From 15628a1206d3d694d6d6852157a4e7f2fa799017 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 22 Nov 2017 10:43:38 +1100 Subject: Add a test for when the ratio is < 1 --- .../order_watcher/remaining_fillable_calculator.ts | 98 ++++++++++++---------- .../test/remaining_fillable_calculator_test.ts | 58 +++++++++++-- 2 files changed, 104 insertions(+), 52 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts index 8141dd73c..b98ef3240 100644 --- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -1,71 +1,83 @@ -import { - SignedOrder, -} from '../types'; -import { BigNumber } from 'bignumber.js'; +import {SignedOrder} from '../types'; +import {BigNumber} from 'bignumber.js'; + export class RemainingFillableCalculator { - private _signedOrder: SignedOrder; - private _isMakerTokenZRX: boolean; - private _transferrableMakerTokenAmount: BigNumber; - private _transferrableMakerFeeTokenAmount: BigNumber; - private _remainingMakerTokenAmount: BigNumber; - private _remainingMakerFeeAmount: BigNumber; + private signedOrder: SignedOrder; + private isMakerTokenZRX: boolean; + // Transferrable Amount is the minimum of Approval and Balance + private transferrableMakerTokenAmount: BigNumber; + private transferrableMakerFeeTokenAmount: BigNumber; + private remainingMakerTokenAmount: BigNumber; + private remainingMakerFeeAmount: BigNumber; constructor(signedOrder: SignedOrder, isMakerTokenZRX: boolean, transferrableMakerTokenAmount: BigNumber, transferrableMakerFeeTokenAmount: BigNumber, remainingMakerTokenAmount: BigNumber) { - this._signedOrder = signedOrder; - this._isMakerTokenZRX = isMakerTokenZRX; - this._transferrableMakerTokenAmount = transferrableMakerTokenAmount; - this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount; - this._remainingMakerTokenAmount = remainingMakerTokenAmount; - this._remainingMakerFeeAmount = remainingMakerTokenAmount.times(signedOrder.makerFee) - .dividedToIntegerBy(signedOrder.makerTokenAmount); + this.signedOrder = signedOrder; + this.isMakerTokenZRX = isMakerTokenZRX; + this.transferrableMakerTokenAmount = transferrableMakerTokenAmount; + this.transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount; + this.remainingMakerTokenAmount = remainingMakerTokenAmount; + this.remainingMakerFeeAmount = remainingMakerTokenAmount.times(signedOrder.makerFee) + .dividedToIntegerBy(signedOrder.makerTokenAmount); } public computeRemainingMakerFillable(): BigNumber { if (this.hasSufficientFundsForFeeAndTransferAmount()) { - return this._remainingMakerTokenAmount; + return this.remainingMakerTokenAmount; } - if (this._signedOrder.makerFee.isZero()) { - return BigNumber.min(this._remainingMakerTokenAmount, this._transferrableMakerTokenAmount); - } else { - return this.calculatePartiallyFillableMakerTokenAmount(); + if (this.signedOrder.makerFee.isZero()) { + return BigNumber.min(this.remainingMakerTokenAmount, this.transferrableMakerTokenAmount); } + return this.calculatePartiallyFillableMakerTokenAmount(); } public computeRemainingTakerFillable(): BigNumber { - return this.computeRemainingMakerFillable().times(this._signedOrder.takerTokenAmount) - .dividedToIntegerBy(this._signedOrder.makerTokenAmount); + return this.computeRemainingMakerFillable().times(this.signedOrder.takerTokenAmount) + .dividedToIntegerBy(this.signedOrder.makerTokenAmount); } private hasSufficientFundsForFeeAndTransferAmount(): boolean { - if (this._isMakerTokenZRX) { - const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount); - return this._transferrableMakerTokenAmount.gte(totalZRXTransferAmountRequired); + if (this.isMakerTokenZRX) { + const totalZRXTransferAmountRequired = this.remainingMakerTokenAmount.plus(this.remainingMakerFeeAmount); + const hasSufficientFunds = this.transferrableMakerTokenAmount.greaterThanOrEqualTo( + totalZRXTransferAmountRequired); + return hasSufficientFunds; } else { - const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.gte( - this._remainingMakerTokenAmount); - const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.gte( - this._remainingMakerFeeAmount); - return (hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount); + const hasSufficientFundsForTransferAmount = this.transferrableMakerTokenAmount.greaterThanOrEqualTo( + this.remainingMakerTokenAmount); + const hasSufficientFundsForFeeAmount = this.transferrableMakerFeeTokenAmount.greaterThanOrEqualTo( + this.remainingMakerFeeAmount); + const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount; + return hasSufficientFunds; } } - private calculatePartiallyFillableMakerTokenAmount(): BigNumber { - const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedToIntegerBy(this._signedOrder.makerFee); + // The number of times the maker can fill the order, if each fill only required the transfer of a single + // baseUnit of fee tokens. + // Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1 + const orderToFeeRatio = this.signedOrder.makerTokenAmount.dividedBy(this.signedOrder.makerFee); // Maximum number of times the Maker can fill the order, given the fees - const fillableTimesInFeeTokenUnits = BigNumber.min(this._transferrableMakerFeeTokenAmount, - this._remainingMakerFeeAmount); + // Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2 + const fillableTimesInFeeTokenBaseUnits = BigNumber.min(this.transferrableMakerFeeTokenAmount, + this.remainingMakerFeeAmount); // Maximum number of times the Maker can fill the order, given the Maker Token Balance - let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedToIntegerBy(orderToFeeRatio); - if (this._isMakerTokenZRX) { - const totalZRXTokenPooled = this._transferrableMakerTokenAmount; + // Assuming a balance of 150 wei, maker can fill this order 1 time. + let fillableTimesInMakerTokenUnits = this.transferrableMakerTokenAmount.dividedBy(orderToFeeRatio); + if (this.isMakerTokenZRX) { + // If ZRX is the maker token, the Fee and the Maker amount need to be removed from the same pool; + // 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei) + const totalZRXTokenPooled = this.transferrableMakerTokenAmount; // The purchasing power here is less as the tokens are taken from the same Pool // For every one number of fills, we have to take an extra ZRX out of the pool - fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedToIntegerBy( + fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy( orderToFeeRatio.plus(new BigNumber(1))); } - const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits.times(orderToFeeRatio); - const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenUnits.times(orderToFeeRatio); - return BigNumber.min(partiallyFillableMakerTokenAmount, partiallyFillableFeeTokenAmount); + // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored. + // This can result in a RoundingError being thrown by the Exchange Contract. + const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits.times(orderToFeeRatio).floor(); + const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits.times(orderToFeeRatio).floor(); + const partiallyFillableAmount = BigNumber.min(partiallyFillableMakerTokenAmount, + partiallyFillableFeeTokenAmount); + return partiallyFillableAmount; } } diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts index 0b1f517fa..65b65efd8 100644 --- a/packages/0x.js/test/remaining_fillable_calculator_test.ts +++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts @@ -18,7 +18,7 @@ describe('RemainingFillableCalculator', () => { let remainingMakerTokenAmount: BigNumber; let makerAmount: BigNumber; let takerAmount: BigNumber; - let makerFee: BigNumber; + let makerFeeAmount: BigNumber; let isMakerTokenZRX: boolean; const makerToken: string = '0x1'; const takerToken: string = '0x2'; @@ -27,9 +27,9 @@ describe('RemainingFillableCalculator', () => { const zeroAddress = '0x0'; const signature: ECSignature = { v: 27, r: '', s: ''}; beforeEach(async () => { - [makerAmount, takerAmount, makerFee] = [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)]; @@ -40,7 +40,7 @@ describe('RemainingFillableCalculator', () => { feeRecipient: zeroAddress, maker: zeroAddress, taker: zeroAddress, - makerFee: (makerFee || zero), + makerFee: makerFeeAmount, takerFee: zero, makerTokenAmount: makerAmount, takerTokenAmount: takerAmount, @@ -84,6 +84,45 @@ describe('RemainingFillableCalculator', () => { 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)]; + }); + 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); + 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)]; + }); + 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); + const calculatedFillableAmount = calculator.computeRemainingMakerFillable(); + expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true(); + expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0)); + const orderToFeeRatio = signedOrder.makerTokenAmount.dividedBy(signedOrder.makerFee); + const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio); + expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount); + }); + }); }); describe('Maker Token is ZRX', () => { before(async () => { @@ -91,7 +130,7 @@ describe('RemainingFillableCalculator', () => { }); it('calculates the correct amount when unfilled and funds available', () => { signedOrder = buildSignedOrder(); - transferrableMakerTokenAmount = makerAmount.plus(makerFee); + transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount); transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; remainingMakerTokenAmount = signedOrder.makerTokenAmount; calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, @@ -122,15 +161,16 @@ describe('RemainingFillableCalculator', () => { transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount; const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee); - const expectedFillableAmount = new BigNumber(450950); - const numberOfFillsInRatio = expectedFillableAmount.dividedToIntegerBy(orderToFeeRatio); + const expectedFillableAmount = new BigNumber(450980); calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX, transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount); const calculatedFillableAmount = calculator.computeRemainingMakerFillable(); + const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio); const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio); - expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount); expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount); expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount); + expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount); + expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0); }); }); }); -- cgit v1.2.3 From 4bfb1fcc715b6da3352e1a6cbfe55bed0a973a78 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 22 Nov 2017 10:54:09 +1100 Subject: add a test constant for ZRX decimals --- packages/0x.js/test/order_state_watcher_test.ts | 53 +++++++++++++------------ packages/0x.js/test/utils/constants.ts | 1 + 2 files changed, 29 insertions(+), 25 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 8ab4939c0..e64a69890 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -3,10 +3,10 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as Web3 from 'web3'; import BigNumber from 'bignumber.js'; -import { chaiSetup } from './utils/chai_setup'; -import { web3Factory } from './utils/web3_factory'; -import { Web3Wrapper } from '../src/web3_wrapper'; -import { OrderStateWatcher } from '../src/order_watcher/order_state_watcher'; +import {chaiSetup} from './utils/chai_setup'; +import {web3Factory} from './utils/web3_factory'; +import {Web3Wrapper} from '../src/web3_wrapper'; +import {OrderStateWatcher} from '../src/order_watcher/order_state_watcher'; import { Token, ZeroEx, @@ -20,11 +20,12 @@ import { OrderStateInvalid, ExchangeContractErrs, } from '../src'; -import { TokenUtils } from './utils/token_utils'; -import { FillScenarios } from './utils/fill_scenarios'; -import { DoneCallback } from '../src/types'; +import {TokenUtils} from './utils/token_utils'; +import {FillScenarios} from './utils/fill_scenarios'; +import {DoneCallback} from '../src/types'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; import {reportCallbackErrors} from './utils/report_callback_errors'; +import { constants as constants } from './utils/constants'; const TIMEOUT_MS = 150; @@ -47,7 +48,8 @@ describe('OrderStateWatcher', () => { let taker: string; let web3Wrapper: Web3Wrapper; let signedOrder: SignedOrder; - const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), 18); + const decimals = constants.ZRX_DECIMALS; + const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals); before(async () => { web3 = web3Factory.create(); zeroEx = new ZeroEx(web3.currentProvider); @@ -238,15 +240,15 @@ describe('OrderStateWatcher', () => { describe('remainingFillable(M|T)akerTokenAmount', () => { it('should calculate correct remaining fillable', (done: DoneCallback) => { (async () => { - const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), 18); - const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), 18); + 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, 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), 18); + const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals); const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); let eventCount = 0; @@ -257,9 +259,9 @@ describe('OrderStateWatcher', () => { expect(validOrderState.orderHash).to.be.equal(orderHash); const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( - ZeroEx.toBaseUnitAmount(new BigNumber(16), 18)); + ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals)); expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( - ZeroEx.toBaseUnitAmount(new BigNumber(8), 18)); + ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals)); if (eventCount === 2) { done(); } @@ -279,7 +281,7 @@ describe('OrderStateWatcher', () => { const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); - const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); + const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals); zeroEx.orderStateWatcher.addOrder(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { @@ -303,7 +305,7 @@ describe('OrderStateWatcher', () => { const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); - const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); + const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals); const transferAmount = makerBalance.sub(remainingAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); @@ -323,8 +325,8 @@ describe('OrderStateWatcher', () => { }); it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => { (async () => { - const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); - const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), 18); + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals); + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals); const feeRecipient = taker; signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( makerToken.address, takerToken.address, makerFee, takerFee, maker, @@ -332,11 +334,12 @@ describe('OrderStateWatcher', () => { const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); - const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), 18); + const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals); const transferTokenAmount = makerFee.sub(remainingTokenAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); const callback = reportCallbackErrors(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( @@ -349,8 +352,8 @@ describe('OrderStateWatcher', () => { }); it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => { (async () => { - const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); - const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), 18); + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals); + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals); const feeRecipient = taker; signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( makerToken.address, takerToken.address, makerFee, takerFee, maker, @@ -358,10 +361,10 @@ describe('OrderStateWatcher', () => { const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); - const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); + const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals); const transferFeeAmount = makerFee.sub(remainingFeeAmount); - const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), 18); + const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals); const transferTokenAmount = makerFee.sub(remainingTokenAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); @@ -380,8 +383,8 @@ describe('OrderStateWatcher', () => { }); it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => { (async () => { - const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); - const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals); + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals); const feeRecipient = taker; signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( makerToken.address, takerToken.address, makerFee, takerFee, maker, @@ -399,7 +402,7 @@ describe('OrderStateWatcher', () => { }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.setProxyAllowanceAsync( - makerToken.address, maker, ZeroEx.toBaseUnitAmount(new BigNumber(100), 18)); + makerToken.address, maker, ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals)); })().catch(done); }); }); diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts index c7d3aebca..5992c226e 100644 --- a/packages/0x.js/test/utils/constants.ts +++ b/packages/0x.js/test/utils/constants.ts @@ -5,4 +5,5 @@ export const constants = { TESTRPC_NETWORK_ID: 50, KOVAN_RPC_URL: 'https://kovan.infura.io', ROPSTEN_RPC_URL: 'https://ropsten.infura.io', + ZRX_DECIMALS: 18, }; -- cgit v1.2.3 From 9c9ce9752537122df51b935bf1f63f128414fc0f Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Wed, 22 Nov 2017 11:08:39 +1100 Subject: Perform the division last to not compound any errors --- packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts index b98ef3240..30f79e786 100644 --- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -74,8 +74,12 @@ export class RemainingFillableCalculator { } // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored. // This can result in a RoundingError being thrown by the Exchange Contract. - const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits.times(orderToFeeRatio).floor(); - const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits.times(orderToFeeRatio).floor(); + const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits + .times(this.signedOrder.makerTokenAmount) + .dividedToIntegerBy(this.signedOrder.makerFee); + const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits + .times(this.signedOrder.makerTokenAmount) + .dividedToIntegerBy(this.signedOrder.makerFee); const partiallyFillableAmount = BigNumber.min(partiallyFillableMakerTokenAmount, partiallyFillableFeeTokenAmount); return partiallyFillableAmount; -- cgit v1.2.3 From cd42ca1bbdb77a25fae0c5f0c290050022c5d113 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Wed, 22 Nov 2017 15:07:34 -0800 Subject: Publish - 0x.js@0.26.1 - @0xproject/connect@0.1.0 --- packages/0x.js/package.json | 2 +- packages/connect/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 26f9273db..afca00fe9 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "0.26.0", + "version": "0.26.1", "description": "A javascript library for interacting with the 0x protocol", "keywords": [ "0x.js", diff --git a/packages/connect/package.json b/packages/connect/package.json index 180a79eea..9131eef14 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/connect", - "version": "0.0.1", + "version": "0.1.0", "description": "A javascript library for interacting with the standard relayer api", "keywords": [ "connect", @@ -36,7 +36,7 @@ }, "homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md", "dependencies": { - "0x.js": "^0.26.0", + "0x.js": "^0.26.1", "@0xproject/assert": "^0.0.5", "@0xproject/json-schemas": "^0.6.8", "bignumber.js": "~4.1.0", -- cgit v1.2.3 From 02aefc40f32e9e2d396b3b7574fdcb7ccb874dca Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Wed, 22 Nov 2017 15:10:50 -0800 Subject: Fix connect CHANGELOG version --- packages/connect/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/connect/CHANGELOG.md b/packages/connect/CHANGELOG.md index a6e30ed4a..ec6727a12 100644 --- a/packages/connect/CHANGELOG.md +++ b/packages/connect/CHANGELOG.md @@ -1,5 +1,5 @@ # CHANGELOG -v0.0.2 - _November 22, 2017_ +v0.1.0 - _November 22, 2017_ ------------------------ * Provide a HttpClient class for interacting with standard relayer api compliant HTTP urls -- cgit v1.2.3 From 924b96ce2af038a9635d5a19802b07698e19b056 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 23 Nov 2017 15:14:33 +1100 Subject: Fix nits --- .../0x.js/src/order_watcher/remaining_fillable_calculator.ts | 9 ++++----- packages/0x.js/test/order_state_watcher_test.ts | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts index 30f79e786..c77d4428c 100644 --- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -51,16 +51,15 @@ export class RemainingFillableCalculator { } } private calculatePartiallyFillableMakerTokenAmount(): BigNumber { - // The number of times the maker can fill the order, if each fill only required the transfer of a single - // baseUnit of fee tokens. // Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1 const orderToFeeRatio = this.signedOrder.makerTokenAmount.dividedBy(this.signedOrder.makerFee); - // Maximum number of times the Maker can fill the order, given the fees + // The number of times the maker can fill the order, if each fill only required the transfer of a single + // baseUnit of fee tokens. // Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2 const fillableTimesInFeeTokenBaseUnits = BigNumber.min(this.transferrableMakerFeeTokenAmount, this.remainingMakerFeeAmount); - // Maximum number of times the Maker can fill the order, given the Maker Token Balance - // Assuming a balance of 150 wei, maker can fill this order 1 time. + // The number of times the Maker can fill the order, given the Maker Token Balance + // Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time. let fillableTimesInMakerTokenUnits = this.transferrableMakerTokenAmount.dividedBy(orderToFeeRatio); if (this.isMakerTokenZRX) { // If ZRX is the maker token, the Fee and the Maker amount need to be removed from the same pool; diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index ab6174f71..4c19a3dc2 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -25,7 +25,7 @@ import {FillScenarios} from './utils/fill_scenarios'; import {DoneCallback} from '../src/types'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; import {reportCallbackErrors} from './utils/report_callback_errors'; -import { constants as constants } from './utils/constants'; +import {constants as constants} from './utils/constants'; const TIMEOUT_MS = 150; -- cgit v1.2.3 From 5a18f43b5100a1274949bd33fab263f591e392cd Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 23 Nov 2017 15:17:11 +1100 Subject: Update to Async call --- packages/0x.js/test/order_state_watcher_test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 4c19a3dc2..834099ef6 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -326,6 +326,7 @@ describe('OrderStateWatcher', () => { await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(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( @@ -352,7 +353,7 @@ describe('OrderStateWatcher', () => { const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals); const transferTokenAmount = makerFee.sub(remainingTokenAmount); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); @@ -382,7 +383,7 @@ describe('OrderStateWatcher', () => { const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals); const transferTokenAmount = makerFee.sub(remainingTokenAmount); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; @@ -407,7 +408,7 @@ describe('OrderStateWatcher', () => { taker, fillableAmount, feeRecipient); const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; -- cgit v1.2.3 From e01468b49265c1cad9a4d81873584a7e89169aa1 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 23 Nov 2017 10:01:23 -0600 Subject: Make DecodedLogEvent contain web3 log under a log subkey --- packages/0x.js/src/contract_wrappers/contract_wrapper.ts | 2 +- packages/0x.js/src/types.ts | 5 ++++- packages/0x.js/test/exchange_wrapper_test.ts | 6 +++--- packages/0x.js/test/token_wrapper_test.ts | 12 +++++++----- 4 files changed, 15 insertions(+), 10 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts index 7997b1647..70548293c 100644 --- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts @@ -100,7 +100,7 @@ export class ContractWrapper { if (filterUtils.matchesFilter(log, filter)) { const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs; const logEvent = { - ...decodedLog, + log: decodedLog, removed, }; this._filterCallbacks[filterToken](null, logEvent); diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index c3aabfd86..d94868d9f 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -40,7 +40,10 @@ export type OrderValues = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber]; export type LogEvent = Web3.LogEntryEvent; -export type DecodedLogEvent = Web3.DecodedLogEntryEvent; +export interface DecodedLogEvent { + removed: boolean; + log: LogWithDecodedArgs; +} export type EventCallback = (err: null|Error, log?: DecodedLogEvent) => void; export type EventWatcherCallback = (log: LogEvent) => void; diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts index add89a3b2..4ea17ec26 100644 --- a/packages/0x.js/test/exchange_wrapper_test.ts +++ b/packages/0x.js/test/exchange_wrapper_test.ts @@ -649,7 +649,7 @@ describe('ExchangeWrapper', () => { (async () => { const callback = (err: Error, logEvent: DecodedLogEvent) => { - expect(logEvent.event).to.be.equal(ExchangeEvents.LogFill); + expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); done(); }; await zeroEx.exchange.subscribeAsync( @@ -665,7 +665,7 @@ describe('ExchangeWrapper', () => { (async () => { const callback = (err: Error, logEvent: DecodedLogEvent) => { - expect(logEvent.event).to.be.equal(ExchangeEvents.LogCancel); + expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel); done(); }; await zeroEx.exchange.subscribeAsync( @@ -688,7 +688,7 @@ describe('ExchangeWrapper', () => { await zeroEx.setProviderAsync(newProvider); const callback = (err: Error, logEvent: DecodedLogEvent) => { - expect(logEvent.event).to.be.equal(ExchangeEvents.LogFill); + expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); done(); }; await zeroEx.exchange.subscribeAsync( diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index 1a7cb9e40..d44bf603c 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -361,10 +361,11 @@ describe('TokenWrapper', () => { (async () => { const callback = (err: Error, logEvent: DecodedLogEvent) => { expect(logEvent).to.not.be.undefined(); - expect(logEvent.logIndex).to.be.equal(0); - expect(logEvent.transactionIndex).to.be.equal(0); - expect(logEvent.blockNumber).to.be.a('number'); - const args = logEvent.args; + expect(logEvent.removed).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); @@ -379,7 +380,8 @@ describe('TokenWrapper', () => { (async () => { const callback = (err: Error, logEvent: DecodedLogEvent) => { expect(logEvent).to.not.be.undefined(); - const args = logEvent.args; + expect(logEvent.removed).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); -- cgit v1.2.3 From 6323badc19f6573af8a5b78e5655169f1127b819 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 23 Nov 2017 10:08:01 -0600 Subject: Add CHANGELOG entry --- packages/0x.js/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'packages') diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index 235a6eedb..f33eab94e 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +vx.x.x +------------------------ + * Make `DecodedLogEvent` contain `LogWithDecodedArgs` under log key instead of merging it in like web3 does (#234) + v0.26.0 ------------------------ * Add post-formatter for logs converting `blockNumber`, `logIndex`, `transactionIndex` from hexes to numbers (#231) -- cgit v1.2.3 From fcd37808d46d162b183b7c6d9aeb58ebc431caba Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 23 Nov 2017 15:12:15 -0600 Subject: Rename removed to isRemoved --- packages/0x.js/src/contract_wrappers/contract_wrapper.ts | 12 ++++++------ packages/0x.js/src/types.ts | 2 +- packages/0x.js/test/token_wrapper_test.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts index 70548293c..c1c95c6db 100644 --- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts @@ -95,13 +95,13 @@ export class ContractWrapper { await this._web3Wrapper.getContractInstanceFromArtifactAsync(artifact, addressIfExists); return contractInstance; } - private _onLogStateChanged(removed: boolean, log: Web3.LogEntry): void { + private _onLogStateChanged(isRemoved: boolean, log: Web3.LogEntry): void { _.forEach(this._filters, (filter: Web3.FilterObject, filterToken: string) => { if (filterUtils.matchesFilter(log, filter)) { const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs; const logEvent = { log: decodedLog, - removed, + isRemoved, }; this._filterCallbacks[filterToken](null, logEvent); } @@ -117,13 +117,13 @@ export class ContractWrapper { this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval( this._reconcileBlockAsync.bind(this), constants.DEFAULT_BLOCK_POLLING_INTERVAL, ); - let removed = false; + let isRemoved = false; this._onLogAddedSubscriptionToken = this._blockAndLogStreamer.subscribeToOnLogAdded( - this._onLogStateChanged.bind(this, removed), + this._onLogStateChanged.bind(this, isRemoved), ); - removed = true; + isRemoved = true; this._onLogRemovedSubscriptionToken = this._blockAndLogStreamer.subscribeToOnLogRemoved( - this._onLogStateChanged.bind(this, removed), + this._onLogStateChanged.bind(this, isRemoved), ); } private _stopBlockAndLogStream(): void { diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index d94868d9f..ac4106d0b 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -41,7 +41,7 @@ export type OrderValues = [BigNumber, BigNumber, BigNumber, export type LogEvent = Web3.LogEntryEvent; export interface DecodedLogEvent { - removed: boolean; + isRemoved: boolean; log: LogWithDecodedArgs; } diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index d44bf603c..882913793 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -361,7 +361,7 @@ describe('TokenWrapper', () => { (async () => { const callback = (err: Error, logEvent: DecodedLogEvent) => { expect(logEvent).to.not.be.undefined(); - expect(logEvent.removed).to.be.false(); + 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'); @@ -380,7 +380,7 @@ describe('TokenWrapper', () => { (async () => { const callback = (err: Error, logEvent: DecodedLogEvent) => { expect(logEvent).to.not.be.undefined(); - expect(logEvent.removed).to.be.false(); + 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); -- cgit v1.2.3 From 5068f1666a9d1dec2140f2a98e96bb880e854105 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Nov 2017 15:20:20 -0600 Subject: Remove `Earliest` from blockParamLiterals since specifying block 0 is trivial and this type can be reused in situations where the options are pending or latest --- packages/0x.js/src/types.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index c3aabfd86..595b90482 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -350,7 +350,6 @@ export interface IndexedFilterValues { export enum BlockParamLiteral { Latest = 'latest', - Earliest = 'earliest', Pending = 'pending', } -- cgit v1.2.3 From b7b1721145f3894ade757a2ad4c366e2b6eadbe9 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Nov 2017 15:21:45 -0600 Subject: Pass 'latest' to ExchangeTransferSimulator when used for validating orders, and pass 'pending' when used in the order watcher. --- .../0x.js/src/contract_wrappers/exchange_wrapper.ts | 17 +++++++++-------- packages/0x.js/src/order_watcher/order_state_watcher.ts | 4 +++- .../src/stores/balance_proxy_allowance_lazy_store.ts | 8 +++++--- packages/0x.js/src/utils/exchange_transfer_simulator.ts | 4 ++-- packages/0x.js/test/exchange_transfer_simulator_test.ts | 2 +- packages/0x.js/test/exchange_wrapper_test.ts | 2 +- packages/0x.js/test/order_validation_test.ts | 4 ++-- packages/0x.js/test/token_wrapper_test.ts | 2 +- 8 files changed, 24 insertions(+), 19 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index 3e631b73e..7c33dc6ec 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -29,6 +29,7 @@ import { EventCallback, ExchangeContractEventArgs, DecodedLogArgs, + BlockParamLiteral, } from '../types'; import {assert} from '../utils/assert'; import {utils} from '../utils/utils'; @@ -178,7 +179,7 @@ export class ExchangeWrapper extends ContractWrapper { orderTransactionOpts.shouldValidate; if (shouldValidate) { const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); } @@ -250,7 +251,7 @@ export class ExchangeWrapper extends ContractWrapper { orderTransactionOpts.shouldValidate; if (shouldValidate) { const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); for (const signedOrder of signedOrders) { await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); @@ -340,7 +341,7 @@ export class ExchangeWrapper extends ContractWrapper { orderTransactionOpts.shouldValidate; if (shouldValidate) { const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); for (const orderFillRequest of orderFillRequests) { await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, @@ -420,7 +421,7 @@ export class ExchangeWrapper extends ContractWrapper { orderTransactionOpts.shouldValidate; if (shouldValidate) { const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); } @@ -484,7 +485,7 @@ export class ExchangeWrapper extends ContractWrapper { orderTransactionOpts.shouldValidate; if (shouldValidate) { const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); for (const orderFillRequest of orderFillRequests) { await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, @@ -721,7 +722,7 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); const zrxTokenAddress = await this.getZRXTokenAddressAsync(); const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined; - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateOrderFillableOrThrowAsync( exchangeTradeEmulator, signedOrder, zrxTokenAddress, expectedFillTakerTokenAmount, ); @@ -741,7 +742,7 @@ export class ExchangeWrapper extends ContractWrapper { assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); } @@ -775,7 +776,7 @@ export class ExchangeWrapper extends ContractWrapper { assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); const zrxTokenAddress = await this.getZRXTokenAddressAsync(); - const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper); + const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress); } diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts index 44a41669d..d02e31160 100644 --- a/packages/0x.js/src/order_watcher/order_state_watcher.ts +++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts @@ -74,7 +74,9 @@ export class OrderStateWatcher { this._web3Wrapper = web3Wrapper; const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs; this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs); - this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(token); + this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( + token, BlockParamLiteral.Pending, + ); this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange); this._orderStateUtils = new OrderStateUtils( this._balanceAndProxyAllowanceLazyStore, this._orderFilledCancelledLazyStore, diff --git a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts index c83e61606..7c94031c3 100644 --- a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts +++ b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts @@ -9,6 +9,7 @@ import {BlockParamLiteral} from '../types'; */ export class BalanceAndProxyAllowanceLazyStore { private token: TokenWrapper; + private defaultBlock: BlockParamLiteral; private balance: { [tokenAddress: string]: { [userAddress: string]: BigNumber, @@ -19,15 +20,16 @@ export class BalanceAndProxyAllowanceLazyStore { [userAddress: string]: BigNumber, }, }; - constructor(token: TokenWrapper) { + constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) { this.token = token; + this.defaultBlock = defaultBlock; this.balance = {}; this.proxyAllowance = {}; } public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise { if (_.isUndefined(this.balance[tokenAddress]) || _.isUndefined(this.balance[tokenAddress][userAddress])) { const methodOpts = { - defaultBlock: BlockParamLiteral.Pending, + defaultBlock: this.defaultBlock, }; const balance = await this.token.getBalanceAsync(tokenAddress, userAddress, methodOpts); this.setBalance(tokenAddress, userAddress, balance); @@ -53,7 +55,7 @@ export class BalanceAndProxyAllowanceLazyStore { if (_.isUndefined(this.proxyAllowance[tokenAddress]) || _.isUndefined(this.proxyAllowance[tokenAddress][userAddress])) { const methodOpts = { - defaultBlock: BlockParamLiteral.Pending, + defaultBlock: this.defaultBlock, }; const proxyAllowance = await this.token.getProxyAllowanceAsync(tokenAddress, userAddress, methodOpts); this.setProxyAllowance(tokenAddress, userAddress, proxyAllowance); diff --git a/packages/0x.js/src/utils/exchange_transfer_simulator.ts b/packages/0x.js/src/utils/exchange_transfer_simulator.ts index 308ef06db..eeb6081cb 100644 --- a/packages/0x.js/src/utils/exchange_transfer_simulator.ts +++ b/packages/0x.js/src/utils/exchange_transfer_simulator.ts @@ -35,8 +35,8 @@ const ERR_MSG_MAPPING = { export class ExchangeTransferSimulator { private store: BalanceAndProxyAllowanceLazyStore; private UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber; - constructor(token: TokenWrapper) { - this.store = new BalanceAndProxyAllowanceLazyStore(token); + constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) { + this.store = new BalanceAndProxyAllowanceLazyStore(token, defaultBlock); this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS = token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; } /** diff --git a/packages/0x.js/test/exchange_transfer_simulator_test.ts b/packages/0x.js/test/exchange_transfer_simulator_test.ts index 99cb7fb4f..ec2c045fc 100644 --- a/packages/0x.js/test/exchange_transfer_simulator_test.ts +++ b/packages/0x.js/test/exchange_transfer_simulator_test.ts @@ -37,7 +37,7 @@ describe('ExchangeTransferSimulator', () => { }); describe('#transferFromAsync', () => { beforeEach(() => { - exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token); + exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest); }); it('throws if the user doesn\'t have enough allowance', async () => { return expect(exchangeTransferSimulator.transferFromAsync( diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts index add89a3b2..b5fa47f8b 100644 --- a/packages/0x.js/test/exchange_wrapper_test.ts +++ b/packages/0x.js/test/exchange_wrapper_test.ts @@ -754,7 +754,7 @@ describe('ExchangeWrapper', () => { const fillableAmount = new BigNumber(5); const shouldThrowOnInsufficientBalanceOrAllowance = true; const subscriptionOpts: SubscriptionOpts = { - fromBlock: BlockParamLiteral.Earliest, + fromBlock: 0, toBlock: BlockParamLiteral.Latest, }; let txHash: string; diff --git a/packages/0x.js/test/order_validation_test.ts b/packages/0x.js/test/order_validation_test.ts index 4f18742d3..d689ef073 100644 --- a/packages/0x.js/test/order_validation_test.ts +++ b/packages/0x.js/test/order_validation_test.ts @@ -5,7 +5,7 @@ import * as Sinon from 'sinon'; import {chaiSetup} from './utils/chai_setup'; import {web3Factory} from './utils/web3_factory'; import {ZeroEx, SignedOrder, Token, ExchangeContractErrs, ZeroExError} from '../src'; -import {TradeSide, TransferType} from '../src/types'; +import {TradeSide, TransferType, BlockParamLiteral} from '../src/types'; import {TokenUtils} from './utils/token_utils'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; import {FillScenarios} from './utils/fill_scenarios'; @@ -215,7 +215,7 @@ describe('OrderValidation', () => { return Sinon.match((value: BigNumber) => value.eq(expected)); }; beforeEach('create exchangeTransferSimulator', async () => { - exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token); + exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest); transferFromAsync = Sinon.spy(); exchangeTransferSimulator.transferFromAsync = transferFromAsync as any; }); diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index 1a7cb9e40..27fe63590 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -426,7 +426,7 @@ describe('TokenWrapper', () => { let tokenAddress: string; let tokenTransferProxyAddress: string; const subscriptionOpts: SubscriptionOpts = { - fromBlock: BlockParamLiteral.Earliest, + fromBlock: 0, toBlock: BlockParamLiteral.Latest, }; let txHash: string; -- cgit v1.2.3 From cee0d2706f29561bfa85603721ae0c800d2a80ca Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Nov 2017 15:32:00 -0600 Subject: Add missing type --- packages/0x.js/test/exchange_transfer_simulator_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages') diff --git a/packages/0x.js/test/exchange_transfer_simulator_test.ts b/packages/0x.js/test/exchange_transfer_simulator_test.ts index ec2c045fc..43a6404a1 100644 --- a/packages/0x.js/test/exchange_transfer_simulator_test.ts +++ b/packages/0x.js/test/exchange_transfer_simulator_test.ts @@ -3,7 +3,7 @@ import BigNumber from 'bignumber.js'; import {chaiSetup} from './utils/chai_setup'; import {web3Factory} from './utils/web3_factory'; import {ZeroEx, ExchangeContractErrs, Token} from '../src'; -import {TradeSide, TransferType} from '../src/types'; +import {TradeSide, TransferType, BlockParamLiteral} from '../src/types'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; import {ExchangeTransferSimulator} from '../src/utils/exchange_transfer_simulator'; -- cgit v1.2.3 From ab78c54d6a6e8592c43b779b651cc7203de2e66e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Nov 2017 15:36:46 -0600 Subject: Add comment about BlockParamLiteral explaining the omission of Earliest --- packages/0x.js/src/types.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'packages') diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index 7d85a54ca..143e2b6b2 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -351,6 +351,9 @@ export interface IndexedFilterValues { [index: string]: ContractEventArg; } +// Earliest is omitted by design. It is simply an alias for the `0` constant and +// is thus not very helpful. Moreover, this type is used in places that only accept +// `latest` or `pending`. export enum BlockParamLiteral { Latest = 'latest', Pending = 'pending', -- cgit v1.2.3 From f0b3ee84b47f1b7548ac688a4e44208be1b2eb1f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Nov 2017 15:56:42 -0600 Subject: Fix tests now that we no longer fire duplicate orderWatcher events --- packages/0x.js/test/order_state_watcher_test.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'packages') diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 834099ef6..e635071b8 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -180,16 +180,12 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); - let eventCount = 0; const callback = reportCallbackErrors(done)((orderState: OrderState) => { - eventCount++; 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); - if (eventCount === 2) { - done(); - } + done(); }); zeroEx.orderStateWatcher.subscribe(callback); @@ -212,9 +208,7 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); - let eventCount = 0; const callback = reportCallbackErrors(done)((orderState: OrderState) => { - eventCount++; expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; expect(validOrderState.orderHash).to.be.equal(orderHash); @@ -226,9 +220,7 @@ describe('OrderStateWatcher', () => { expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( remainingFillable); expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance); - if (eventCount === 2) { - done(); - } + done(); }); zeroEx.orderStateWatcher.subscribe(callback); const shouldThrowOnInsufficientBalanceOrAllowance = true; @@ -267,9 +259,7 @@ describe('OrderStateWatcher', () => { const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals); const orderHash = ZeroEx.getOrderHashHex(signedOrder); await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); - let eventCount = 0; const callback = reportCallbackErrors(done)((orderState: OrderState) => { - eventCount++; expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; expect(validOrderState.orderHash).to.be.equal(orderHash); @@ -278,9 +268,7 @@ describe('OrderStateWatcher', () => { ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals)); expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals)); - if (eventCount === 2) { - done(); - } + done(); }); zeroEx.orderStateWatcher.subscribe(callback); const shouldThrowOnInsufficientBalanceOrAllowance = true; -- cgit v1.2.3 From d3dcb2fd4070c71f408ce8fc0199b4d01091ab20 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Nov 2017 17:05:12 -0600 Subject: Add validation fix to changelog --- packages/0x.js/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) (limited to 'packages') diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index f33eab94e..e1f80b00d 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -3,6 +3,7 @@ vx.x.x ------------------------ * Make `DecodedLogEvent` contain `LogWithDecodedArgs` under log key instead of merging it in like web3 does (#234) + * Modify order validation methods to validate against the `latest` block, not against the `pending` block (#236) v0.26.0 ------------------------ -- cgit v1.2.3