aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Evans <jacob@dekz.net>2017-11-21 07:30:29 +0800
committerJacob Evans <jacob@dekz.net>2017-11-21 07:30:29 +0800
commit4bd5789203aa9f75cc7834aa0e29412ba3abba4f (patch)
treed762846731daf41bd34ddcabf94f5cea905610a4
parentfb812d59b0f0c11f50669899ffb6818d5ddeec1f (diff)
downloaddexon-0x-contracts-4bd5789203aa9f75cc7834aa0e29412ba3abba4f.tar.gz
dexon-0x-contracts-4bd5789203aa9f75cc7834aa0e29412ba3abba4f.tar.zst
dexon-0x-contracts-4bd5789203aa9f75cc7834aa0e29412ba3abba4f.zip
Refactor into a calculator class
-rw-r--r--packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts68
-rw-r--r--packages/0x.js/src/utils/order_state_utils.ts101
2 files changed, 76 insertions, 93 deletions
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,