From 3e2a614eb9a4f1219e2f11ea29c8a7cd59dd74dd Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 11:28:01 -0500 Subject: Calculate the remaining order amount in maker units --- src/types.ts | 1 + src/utils/order_state_utils.ts | 16 ++++++++++++++++ test/order_state_watcher_test.ts | 2 ++ 3 files changed, 19 insertions(+) diff --git a/src/types.ts b/src/types.ts index 160b71fda..a366fc31e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -493,6 +493,7 @@ export interface OrderRelevantState { makerFeeProxyAllowance: BigNumber; filledTakerTokenAmount: BigNumber; canceledTakerTokenAmount: BigNumber; + remainingFillableMakerTokenAmount: BigNumber; } export interface OrderStateValid { diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts index 2a5becf9a..ff5c1880d 100644 --- a/src/utils/order_state_utils.ts +++ b/src/utils/order_state_utils.ts @@ -60,6 +60,21 @@ export class OrderStateUtils { ); const filledTakerTokenAmount = await this.exchangeWrapper.getFilledTakerAmountAsync(orderHash, methodOpts); const canceledTakerTokenAmount = await this.exchangeWrapper.getCanceledTakerAmountAsync(orderHash, methodOpts); + const unavailableTakerTokenAmount = + await this.exchangeWrapper.getUnavailableTakerAmountAsync(orderHash, methodOpts); + const totalMakerTokenAmount = signedOrder.makerTokenAmount; + const totalTakerTokenAmount = signedOrder.takerTokenAmount; + const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); + // 200 in order, 100 unavailable = 100 remaning, 0.5 remaning proportion + const remainingTakerProportion = remainingTakerTokenAmount.dividedBy(totalTakerTokenAmount); + const remainingMakerTokenAmount = remainingTakerProportion.times(totalMakerTokenAmount); + // min allowance, balance in account of maker + const fillableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); + // min ^, remaining order maker token amount + const remainingFillableMakerTokenAmount = BigNumber.min(fillableMakerTokenAmount, remainingMakerTokenAmount); + // TODO + // edge case when maker token is ZRX + // rounding issues, check if its fillabae const orderRelevantState = { makerBalance, makerProxyAllowance, @@ -67,6 +82,7 @@ export class OrderStateUtils { makerFeeProxyAllowance, filledTakerTokenAmount, canceledTakerTokenAmount, + remainingFillableMakerTokenAmount, }; return orderRelevantState; } diff --git a/test/order_state_watcher_test.ts b/test/order_state_watcher_test.ts index 3421353e3..039bcef18 100644 --- a/test/order_state_watcher_test.ts +++ b/test/order_state_watcher_test.ts @@ -189,6 +189,8 @@ describe('OrderStateWatcher', () => { expect(validOrderState.orderHash).to.be.equal(orderHash); const orderRelevantState = validOrderState.orderRelevantState; const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits); + const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits); + expect(remainingFillable).to.be.bignumber.equal(fillableAmount.minus(fillAmountInBaseUnits)); expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance); if (eventCount === 2) { done(); -- cgit From fdb3fa6801e07972f53a05c312c2ee933809f823 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 17:24:31 -0500 Subject: Added specs for allowance and balance changes --- src/utils/order_state_utils.ts | 2 - test/order_state_watcher_test.ts | 79 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts index ff5c1880d..fde7a7e02 100644 --- a/src/utils/order_state_utils.ts +++ b/src/utils/order_state_utils.ts @@ -72,9 +72,7 @@ export class OrderStateUtils { const fillableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); // min ^, remaining order maker token amount const remainingFillableMakerTokenAmount = BigNumber.min(fillableMakerTokenAmount, remainingMakerTokenAmount); - // TODO // edge case when maker token is ZRX - // rounding issues, check if its fillabae const orderRelevantState = { makerBalance, makerProxyAllowance, diff --git a/test/order_state_watcher_test.ts b/test/order_state_watcher_test.ts index 039bcef18..43340aadf 100644 --- a/test/order_state_watcher_test.ts +++ b/test/order_state_watcher_test.ts @@ -203,6 +203,85 @@ describe('OrderStateWatcher', () => { ); })().catch(done); }); + describe('remainingFillableMakerTokenAmount', () => { + it.only('should calculate correct reamining fillable', (done: DoneCallback) => { + (async () => { + const takerFillableAmount = new BigNumber(10); + const makerFillableAmount = new BigNumber(20); + 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 = new BigNumber(2); + const orderHash = ZeroEx.getOrderHashHex(signedOrder); + zeroEx.orderStateWatcher.addOrder(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); + const orderRelevantState = validOrderState.orderRelevantState; + expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( + new BigNumber(16)); + if (eventCount === 2) { + done(); + } + }); + zeroEx.orderStateWatcher.subscribe(callback); + const shouldThrowOnInsufficientBalanceOrAllowance = true; + await zeroEx.exchange.fillOrderAsync( + signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker, + ); + })().catch(done); + }); + it.only('should emit approved amount when approved amount is lower', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerToken.address, takerToken.address, maker, taker, fillableAmount, + ); + + const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); + + const changedMakerApprovalAmount = new BigNumber(3); + 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( + changedMakerApprovalAmount); + done(); + }); + zeroEx.orderStateWatcher.subscribe(callback); + await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount); + })().catch(done); + }); + it.only('should emit balance amount when balance amount is lower', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerToken.address, takerToken.address, maker, taker, fillableAmount, + ); + + const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); + + const transferAmount = new BigNumber(1); + 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( + transferAmount); + done(); + }); + zeroEx.orderStateWatcher.subscribe(callback); + await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, + makerBalance.minus(transferAmount)); + })().catch(done); + }); + }); it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( -- cgit From e06539e76d91898af544f321c70aa0aa1d9388f9 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 17:25:42 -0500 Subject: remove only --- test/order_state_watcher_test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/order_state_watcher_test.ts b/test/order_state_watcher_test.ts index 43340aadf..307da4780 100644 --- a/test/order_state_watcher_test.ts +++ b/test/order_state_watcher_test.ts @@ -204,7 +204,7 @@ describe('OrderStateWatcher', () => { })().catch(done); }); describe('remainingFillableMakerTokenAmount', () => { - it.only('should calculate correct reamining fillable', (done: DoneCallback) => { + it('should calculate correct reamining fillable', (done: DoneCallback) => { (async () => { const takerFillableAmount = new BigNumber(10); const makerFillableAmount = new BigNumber(20); @@ -235,7 +235,7 @@ describe('OrderStateWatcher', () => { ); })().catch(done); }); - it.only('should emit approved amount when approved amount is lower', (done: DoneCallback) => { + it('should emit approved amount when approved amount is lower', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( makerToken.address, takerToken.address, maker, taker, fillableAmount, @@ -257,7 +257,7 @@ describe('OrderStateWatcher', () => { await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount); })().catch(done); }); - it.only('should emit balance amount when balance amount is lower', (done: DoneCallback) => { + it('should emit balance amount when balance amount is lower', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( makerToken.address, takerToken.address, maker, taker, fillableAmount, -- cgit From 1b3f84c9ad4d13f49041ed7f56a2a126f9c40f38 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 17:28:34 -0500 Subject: text description update --- test/order_state_watcher_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/order_state_watcher_test.ts b/test/order_state_watcher_test.ts index 307da4780..07d18ae61 100644 --- a/test/order_state_watcher_test.ts +++ b/test/order_state_watcher_test.ts @@ -235,7 +235,7 @@ describe('OrderStateWatcher', () => { ); })().catch(done); }); - it('should emit approved amount when approved amount is lower', (done: DoneCallback) => { + it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( makerToken.address, takerToken.address, maker, taker, fillableAmount, @@ -257,7 +257,7 @@ describe('OrderStateWatcher', () => { await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount); })().catch(done); }); - it('should emit balance amount when balance amount is lower', (done: DoneCallback) => { + it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( makerToken.address, takerToken.address, maker, taker, fillableAmount, -- cgit From 5e77e8809abd96136fb11ebdc84a2aefa32d4cea Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 17:30:57 -0500 Subject: Update comment --- src/utils/order_state_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts index fde7a7e02..4f57de9fe 100644 --- a/src/utils/order_state_utils.ts +++ b/src/utils/order_state_utils.ts @@ -65,7 +65,7 @@ export class OrderStateUtils { const totalMakerTokenAmount = signedOrder.makerTokenAmount; const totalTakerTokenAmount = signedOrder.takerTokenAmount; const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); - // 200 in order, 100 unavailable = 100 remaning, 0.5 remaning proportion + // 200 in order, 100 unavailable = 100 remaning, 0.5 remaining in taker proportion const remainingTakerProportion = remainingTakerTokenAmount.dividedBy(totalTakerTokenAmount); const remainingMakerTokenAmount = remainingTakerProportion.times(totalMakerTokenAmount); // min allowance, balance in account of maker -- cgit From 42e3ab91a794f61d65008d969b3d48080b5035d7 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 19:17:27 -0500 Subject: Perform the division after multiplication to reduce compounding the rounding errors --- src/utils/order_state_utils.ts | 6 +++--- test/order_state_watcher_test.ts | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts index 4f57de9fe..7c10a5480 100644 --- a/src/utils/order_state_utils.ts +++ b/src/utils/order_state_utils.ts @@ -66,13 +66,13 @@ export class OrderStateUtils { const totalTakerTokenAmount = signedOrder.takerTokenAmount; const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); // 200 in order, 100 unavailable = 100 remaning, 0.5 remaining in taker proportion - const remainingTakerProportion = remainingTakerTokenAmount.dividedBy(totalTakerTokenAmount); - const remainingMakerTokenAmount = remainingTakerProportion.times(totalMakerTokenAmount); + const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount) + .dividedToIntegerBy(totalTakerTokenAmount); // min allowance, balance in account of maker const fillableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); // min ^, remaining order maker token amount const remainingFillableMakerTokenAmount = BigNumber.min(fillableMakerTokenAmount, remainingMakerTokenAmount); - // edge case when maker token is ZRX + // TODO: Handle edge case where maker token is ZRX with fee const orderRelevantState = { makerBalance, makerProxyAllowance, diff --git a/test/order_state_watcher_test.ts b/test/order_state_watcher_test.ts index 07d18ae61..924e54772 100644 --- a/test/order_state_watcher_test.ts +++ b/test/order_state_watcher_test.ts @@ -190,7 +190,8 @@ describe('OrderStateWatcher', () => { const orderRelevantState = validOrderState.orderRelevantState; const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits); const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits); - expect(remainingFillable).to.be.bignumber.equal(fillableAmount.minus(fillAmountInBaseUnits)); + expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( + remainingFillable); expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance); if (eventCount === 2) { done(); @@ -204,7 +205,7 @@ describe('OrderStateWatcher', () => { })().catch(done); }); describe('remainingFillableMakerTokenAmount', () => { - it('should calculate correct reamining fillable', (done: DoneCallback) => { + it('should calculate correct remaining fillable', (done: DoneCallback) => { (async () => { const takerFillableAmount = new BigNumber(10); const makerFillableAmount = new BigNumber(20); @@ -265,20 +266,20 @@ describe('OrderStateWatcher', () => { const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); - const transferAmount = new BigNumber(1); + const remainingAmount = new BigNumber(1); + const transferAmount = makerBalance.sub(remainingAmount); 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( - transferAmount); + remainingAmount); done(); }); zeroEx.orderStateWatcher.subscribe(callback); - await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, - makerBalance.minus(transferAmount)); + await zeroEx.token.transferAsync( + makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount); })().catch(done); }); }); -- cgit From 32246fd26bc71b09818491d513a380a8bd85fdec Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Sun, 12 Nov 2017 19:37:03 -0500 Subject: remove comments --- src/utils/order_state_utils.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts index 7c10a5480..36a4b68d6 100644 --- a/src/utils/order_state_utils.ts +++ b/src/utils/order_state_utils.ts @@ -65,12 +65,9 @@ export class OrderStateUtils { const totalMakerTokenAmount = signedOrder.makerTokenAmount; const totalTakerTokenAmount = signedOrder.takerTokenAmount; const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount); - // 200 in order, 100 unavailable = 100 remaning, 0.5 remaining in taker proportion const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount) .dividedToIntegerBy(totalTakerTokenAmount); - // min allowance, balance in account of maker const fillableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]); - // min ^, remaining order maker token amount const remainingFillableMakerTokenAmount = BigNumber.min(fillableMakerTokenAmount, remainingMakerTokenAmount); // TODO: Handle edge case where maker token is ZRX with fee const orderRelevantState = { -- cgit