diff options
author | Leonid Logvinov <logvinov.leon@gmail.com> | 2017-10-31 00:38:10 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2017-10-31 00:49:16 +0800 |
commit | a896904ae7c453f51b1f46de2be3a28416db72d1 (patch) | |
tree | c50c3638b0b9bee982816bb48a4c935de798476a /src/utils | |
parent | 6bfcd253f8e9689ce787899a42f80914b067a4f1 (diff) | |
download | dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.tar dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.tar.gz dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.tar.bz2 dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.tar.lz dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.tar.xz dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.tar.zst dexon-sol-tools-a896904ae7c453f51b1f46de2be3a28416db72d1.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.ts | 99 |
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 + } +} |