aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2017-10-31 00:38:10 +0800
committerLeonid Logvinov <logvinov.leon@gmail.com>2017-11-10 03:11:46 +0800
commitbb5474660c5fa90080cc5950a21eb65e1896f9c4 (patch)
tree20daa7f67df04ed7ae66000c10f2adcea84cb8ea /src/utils
parent63f16b5f99cd7ca0d71dd822c0e2ecd0eb3f7762 (diff)
downloaddexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.tar
dexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.tar.gz
dexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.tar.bz2
dexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.tar.lz
dexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.tar.xz
dexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.tar.zst
dexon-sol-tools-bb5474660c5fa90080cc5950a21eb65e1896f9c4.zip
Add naive order state watcher implementation
Revalidate all orders upon event received and emit order states even if not changed
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/order_state_utils.ts99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/utils/order_state_utils.ts b/src/utils/order_state_utils.ts
new file mode 100644
index 000000000..2a5becf9a
--- /dev/null
+++ b/src/utils/order_state_utils.ts
@@ -0,0 +1,99 @@
+import * as _ from 'lodash';
+import BigNumber from 'bignumber.js';
+import {
+ ExchangeContractErrs,
+ SignedOrder,
+ OrderRelevantState,
+ MethodOpts,
+ OrderState,
+ OrderStateValid,
+ OrderStateInvalid,
+} from '../types';
+import {ZeroEx} from '../0x';
+import {TokenWrapper} from '../contract_wrappers/token_wrapper';
+import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper';
+import {utils} from '../utils/utils';
+import {constants} from '../utils/constants';
+
+export class OrderStateUtils {
+ private tokenWrapper: TokenWrapper;
+ private exchangeWrapper: ExchangeWrapper;
+ constructor(tokenWrapper: TokenWrapper, exchangeWrapper: ExchangeWrapper) {
+ this.tokenWrapper = tokenWrapper;
+ this.exchangeWrapper = exchangeWrapper;
+ }
+ public async getOrderStateAsync(signedOrder: SignedOrder, methodOpts?: MethodOpts): Promise<OrderState> {
+ const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder, methodOpts);
+ const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+ try {
+ this.validateIfOrderIsValid(signedOrder, orderRelevantState);
+ const orderState: OrderStateValid = {
+ isValid: true,
+ orderHash,
+ orderRelevantState,
+ };
+ return orderState;
+ } catch (err) {
+ const orderState: OrderStateInvalid = {
+ isValid: false,
+ orderHash,
+ error: err.message,
+ };
+ return orderState;
+ }
+ }
+ public async getOrderRelevantStateAsync(
+ signedOrder: SignedOrder, methodOpts?: MethodOpts): Promise<OrderRelevantState> {
+ const zrxTokenAddress = await this.exchangeWrapper.getZRXTokenAddressAsync();
+ const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+ const makerBalance = await this.tokenWrapper.getBalanceAsync(
+ signedOrder.makerTokenAddress, signedOrder.maker, methodOpts,
+ );
+ const makerProxyAllowance = await this.tokenWrapper.getProxyAllowanceAsync(
+ signedOrder.makerTokenAddress, signedOrder.maker, methodOpts,
+ );
+ const makerFeeBalance = await this.tokenWrapper.getBalanceAsync(
+ zrxTokenAddress, signedOrder.maker, methodOpts,
+ );
+ const makerFeeProxyAllowance = await this.tokenWrapper.getProxyAllowanceAsync(
+ zrxTokenAddress, signedOrder.maker, methodOpts,
+ );
+ const filledTakerTokenAmount = await this.exchangeWrapper.getFilledTakerAmountAsync(orderHash, methodOpts);
+ const canceledTakerTokenAmount = await this.exchangeWrapper.getCanceledTakerAmountAsync(orderHash, methodOpts);
+ const orderRelevantState = {
+ makerBalance,
+ makerProxyAllowance,
+ makerFeeBalance,
+ makerFeeProxyAllowance,
+ filledTakerTokenAmount,
+ canceledTakerTokenAmount,
+ };
+ return orderRelevantState;
+ }
+ private validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void {
+ const unavailableTakerTokenAmount = orderRelevantState.canceledTakerTokenAmount.add(
+ orderRelevantState.filledTakerTokenAmount,
+ );
+ const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
+ if (availableTakerTokenAmount.eq(0)) {
+ throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
+ }
+
+ if (orderRelevantState.makerBalance.eq(0)) {
+ throw new Error(ExchangeContractErrs.InsufficientMakerBalance);
+ }
+ if (orderRelevantState.makerProxyAllowance.eq(0)) {
+ throw new Error(ExchangeContractErrs.InsufficientMakerAllowance);
+ }
+ if (!signedOrder.makerFee.eq(0)) {
+ if (orderRelevantState.makerFeeBalance.eq(0)) {
+ throw new Error(ExchangeContractErrs.InsufficientMakerFeeBalance);
+ }
+ if (orderRelevantState.makerFeeProxyAllowance.eq(0)) {
+ throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance);
+ }
+ }
+ // TODO Add linear function solver when maker token is ZRX #badass
+ // Return the max amount that's fillable
+ }
+}