diff options
Diffstat (limited to 'packages/0x.js/src/order_watcher')
4 files changed, 115 insertions, 100 deletions
diff --git a/packages/0x.js/src/order_watcher/event_watcher.ts b/packages/0x.js/src/order_watcher/event_watcher.ts index 197dfae65..fc0b9264c 100644 --- a/packages/0x.js/src/order_watcher/event_watcher.ts +++ b/packages/0x.js/src/order_watcher/event_watcher.ts @@ -1,14 +1,10 @@ -import {intervalUtils} from '@0xproject/utils'; -import {Web3Wrapper} from '@0xproject/web3-wrapper'; +import { intervalUtils } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import * as Web3 from 'web3'; -import { - BlockParamLiteral, - EventWatcherCallback, - ZeroExError, -} from '../types'; -import {assert} from '../utils/assert'; +import { BlockParamLiteral, EventWatcherCallback, ZeroExError } from '../types'; +import { assert } from '../utils/assert'; const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200; @@ -26,11 +22,11 @@ export class EventWatcher { private _pollingIntervalMs: number; private _intervalIdIfExists?: NodeJS.Timer; private _lastEvents: Web3.LogEntry[] = []; - constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined|number) { + constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) { this._web3Wrapper = web3Wrapper; - this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ? - DEFAULT_EVENT_POLLING_INTERVAL_MS : - pollingIntervalIfExistsMs; + this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) + ? DEFAULT_EVENT_POLLING_INTERVAL_MS + : pollingIntervalIfExistsMs; } public subscribe(callback: EventWatcherCallback): void { assert.isFunction('callback', callback); @@ -38,7 +34,8 @@ export class EventWatcher { throw new Error(ZeroExError.SubscriptionAlreadyPresent); } this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval( - this._pollForBlockchainEventsAsync.bind(this, callback), this._pollingIntervalMs, + this._pollForBlockchainEventsAsync.bind(this, callback), + this._pollingIntervalMs, ); } public unsubscribe(): void { @@ -71,7 +68,9 @@ export class EventWatcher { return events; } private async _emitDifferencesAsync( - logs: Web3.LogEntry[], logEventState: LogEventState, callback: EventWatcherCallback, + logs: Web3.LogEntry[], + logEventState: LogEventState, + callback: EventWatcherCallback, ): Promise<void> { for (const log of logs) { const logEvent = { diff --git a/packages/0x.js/src/order_watcher/expiration_watcher.ts b/packages/0x.js/src/order_watcher/expiration_watcher.ts index e71f11129..47e03dd38 100644 --- a/packages/0x.js/src/order_watcher/expiration_watcher.ts +++ b/packages/0x.js/src/order_watcher/expiration_watcher.ts @@ -1,10 +1,10 @@ -import {intervalUtils} from '@0xproject/utils'; -import {BigNumber} from 'bignumber.js'; -import {RBTree} from 'bintrees'; +import { intervalUtils } from '@0xproject/utils'; +import { BigNumber } from 'bignumber.js'; +import { RBTree } from 'bintrees'; import * as _ from 'lodash'; -import {ZeroExError} from '../types'; -import {utils} from '../utils/utils'; +import { ZeroExError } from '../types'; +import { utils } from '../utils/utils'; const DEFAULT_EXPIRATION_MARGIN_MS = 0; const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50; @@ -15,16 +15,14 @@ const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50; */ export class ExpirationWatcher { private _orderHashByExpirationRBTree: RBTree<string>; - private _expiration: {[orderHash: string]: BigNumber} = {}; + private _expiration: { [orderHash: string]: BigNumber } = {}; private _orderExpirationCheckingIntervalMs: number; private _expirationMarginMs: number; private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer; - constructor(expirationMarginIfExistsMs?: number, - orderExpirationCheckingIntervalIfExistsMs?: number) { - this._expirationMarginMs = expirationMarginIfExistsMs || - DEFAULT_EXPIRATION_MARGIN_MS; - this._orderExpirationCheckingIntervalMs = expirationMarginIfExistsMs || - DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS; + constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) { + this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS; + this._orderExpirationCheckingIntervalMs = + expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS; const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber(); const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs); this._orderHashByExpirationRBTree = new RBTree(comparator); @@ -34,7 +32,8 @@ export class ExpirationWatcher { throw new Error(ZeroExError.SubscriptionAlreadyPresent); } this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval( - this._pruneExpiredOrders.bind(this, callback), this._orderExpirationCheckingIntervalMs, + this._pruneExpiredOrders.bind(this, callback), + this._orderExpirationCheckingIntervalMs, ); } public unsubscribe(): void { 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 9d5c96b0e..9d7a733d8 100644 --- a/packages/0x.js/src/order_watcher/order_state_watcher.ts +++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts @@ -1,13 +1,13 @@ -import {schemas} from '@0xproject/json-schemas'; -import {intervalUtils} from '@0xproject/utils'; -import {Web3Wrapper} from '@0xproject/web3-wrapper'; +import { schemas } from '@0xproject/json-schemas'; +import { intervalUtils } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; -import {ZeroEx} from '../0x'; -import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper'; -import {TokenWrapper} from '../contract_wrappers/token_wrapper'; -import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store'; -import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store'; +import { ZeroEx } from '../0x'; +import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper'; +import { TokenWrapper } from '../contract_wrappers/token_wrapper'; +import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store'; +import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store'; import { ApprovalContractEventArgs, BlockParamLiteral, @@ -29,13 +29,13 @@ import { WithdrawalContractEventArgs, ZeroExError, } from '../types'; -import {AbiDecoder} from '../utils/abi_decoder'; -import {assert} from '../utils/assert'; -import {OrderStateUtils} from '../utils/order_state_utils'; -import {utils} from '../utils/utils'; +import { AbiDecoder } from '../utils/abi_decoder'; +import { assert } from '../utils/assert'; +import { OrderStateUtils } from '../utils/order_state_utils'; +import { utils } from '../utils/utils'; -import {EventWatcher} from './event_watcher'; -import {ExpirationWatcher} from './expiration_watcher'; +import { EventWatcher } from './event_watcher'; +import { ExpirationWatcher } from './expiration_watcher'; interface DependentOrderHashes { [makerAddress: string]: { @@ -74,7 +74,10 @@ export class OrderStateWatcher { private _cleanupJobInterval: number; private _cleanupJobIntervalIdIfExists?: NodeJS.Timer; constructor( - web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper, + web3Wrapper: Web3Wrapper, + abiDecoder: AbiDecoder, + token: TokenWrapper, + exchange: ExchangeWrapper, config?: OrderStateWatcherConfig, ) { this._abiDecoder = abiDecoder; @@ -82,24 +85,26 @@ export class OrderStateWatcher { const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs; this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs); this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore( - token, BlockParamLiteral.Pending, + token, + BlockParamLiteral.Pending, ); this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange); this._orderStateUtils = new OrderStateUtils( - this._balanceAndProxyAllowanceLazyStore, this._orderFilledCancelledLazyStore, + this._balanceAndProxyAllowanceLazyStore, + this._orderFilledCancelledLazyStore, ); - const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config) ? - undefined : - config.orderExpirationCheckingIntervalMs; - const expirationMarginIfExistsMs = _.isUndefined(config) ? - undefined : - config.expirationMarginMs; + const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config) + ? undefined + : config.orderExpirationCheckingIntervalMs; + const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs; this._expirationWatcher = new ExpirationWatcher( - expirationMarginIfExistsMs, orderExpirationCheckingIntervalMsIfExists, + expirationMarginIfExistsMs, + orderExpirationCheckingIntervalMsIfExists, ); - this._cleanupJobInterval = _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs) ? - DEFAULT_CLEANUP_JOB_INTERVAL_MS : - config.cleanupJobIntervalMs; + this._cleanupJobInterval = + _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs) + ? DEFAULT_CLEANUP_JOB_INTERVAL_MS + : config.cleanupJobIntervalMs; } /** * Add an order to the orderStateWatcher. Before the order is added, it's @@ -148,7 +153,8 @@ export class OrderStateWatcher { this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this)); this._expirationWatcher.subscribe(this._onOrderExpired.bind(this)); this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval( - this._cleanupAsync.bind(this), this._cleanupJobInterval, + this._cleanupAsync.bind(this), + this._cleanupJobInterval, ); } /** @@ -215,23 +221,23 @@ export class OrderStateWatcher { let makerToken: string; let makerAddress: string; switch (decodedLog.event) { - case TokenEvents.Approval: - { + case TokenEvents.Approval: { // Invalidate cache const args = decodedLog.args as ApprovalContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; makerAddress = args._owner; - if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) && - !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) { + if ( + !_.isUndefined(this._dependentOrderHashes[makerAddress]) && + !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken]) + ) { const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]); await this._emitRevalidateOrdersAsync(orderHashes); } break; } - case TokenEvents.Transfer: - { + case TokenEvents.Transfer: { // Invalidate cache const args = decodedLog.args as TransferContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from); @@ -239,45 +245,48 @@ export class OrderStateWatcher { // Revalidate orders makerToken = decodedLog.address; makerAddress = args._from; - if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) && - !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) { + if ( + !_.isUndefined(this._dependentOrderHashes[makerAddress]) && + !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken]) + ) { const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]); await this._emitRevalidateOrdersAsync(orderHashes); } break; } - case EtherTokenEvents.Deposit: - { + case EtherTokenEvents.Deposit: { // Invalidate cache const args = decodedLog.args as DepositContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; makerAddress = args._owner; - if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) && - !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) { + if ( + !_.isUndefined(this._dependentOrderHashes[makerAddress]) && + !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken]) + ) { const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]); await this._emitRevalidateOrdersAsync(orderHashes); } break; } - case EtherTokenEvents.Withdrawal: - { + case EtherTokenEvents.Withdrawal: { // Invalidate cache const args = decodedLog.args as WithdrawalContractEventArgs; this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner); // Revalidate orders makerToken = decodedLog.address; makerAddress = args._owner; - if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) && - !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) { + if ( + !_.isUndefined(this._dependentOrderHashes[makerAddress]) && + !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken]) + ) { const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]); await this._emitRevalidateOrdersAsync(orderHashes); } break; } - case ExchangeEvents.LogFill: - { + case ExchangeEvents.LogFill: { // Invalidate cache const args = decodedLog.args as LogFillContractEventArgs; this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash); @@ -289,8 +298,7 @@ export class OrderStateWatcher { } break; } - case ExchangeEvents.LogCancel: - { + case ExchangeEvents.LogCancel: { // Invalidate cache const args = decodedLog.args as LogCancelContractEventArgs; this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash); 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 ddf3b763b..2200be0cb 100644 --- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts +++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts @@ -1,6 +1,6 @@ -import {BigNumber} from 'bignumber.js'; +import { BigNumber } from 'bignumber.js'; -import {SignedOrder} from '../types'; +import { SignedOrder } from '../types'; export class RemainingFillableCalculator { private _signedOrder: SignedOrder; @@ -10,18 +10,21 @@ export class RemainingFillableCalculator { private _transferrableMakerFeeTokenAmount: BigNumber; private _remainingMakerTokenAmount: BigNumber; private _remainingMakerFeeAmount: BigNumber; - constructor(signedOrder: SignedOrder, - isMakerTokenZRX: boolean, - transferrableMakerTokenAmount: BigNumber, - transferrableMakerFeeTokenAmount: BigNumber, - remainingMakerTokenAmount: 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._remainingMakerFeeAmount = remainingMakerTokenAmount + .times(signedOrder.makerFee) + .dividedToIntegerBy(signedOrder.makerTokenAmount); } public computeRemainingMakerFillable(): BigNumber { if (this._hasSufficientFundsForFeeAndTransferAmount()) { @@ -33,20 +36,24 @@ export class RemainingFillableCalculator { 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); const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo( - totalZRXTransferAmountRequired); + totalZRXTransferAmountRequired, + ); return hasSufficientFunds; } else { const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo( - this._remainingMakerTokenAmount); + this._remainingMakerTokenAmount, + ); const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo( - this._remainingMakerFeeAmount); + this._remainingMakerFeeAmount, + ); const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount; return hasSufficientFunds; } @@ -57,8 +64,10 @@ export class RemainingFillableCalculator { // 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); + const fillableTimesInFeeTokenBaseUnits = BigNumber.min( + this._transferrableMakerFeeTokenAmount, + this._remainingMakerFeeAmount, + ); // 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); @@ -68,20 +77,20 @@ export class RemainingFillableCalculator { 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.dividedBy( - orderToFeeRatio.plus(new BigNumber(1))); - + fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1))); } // 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(this._signedOrder.makerTokenAmount) - .dividedToIntegerBy(this._signedOrder.makerFee); + .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); + .times(this._signedOrder.makerTokenAmount) + .dividedToIntegerBy(this._signedOrder.makerFee); + const partiallyFillableAmount = BigNumber.min( + partiallyFillableMakerTokenAmount, + partiallyFillableFeeTokenAmount, + ); return partiallyFillableAmount; } } |