From 6338b5bd3cbbcef149fb3fdf05116e40ea93aa05 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 23 Aug 2018 13:47:24 -0700 Subject: Move sorting phase into its own utils file --- .../forwarder-helper/src/forwarder_helper_impl.ts | 67 +--------------- .../utils/forwarder_helper_impl_config_utils.ts | 92 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 64 deletions(-) create mode 100644 packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts diff --git a/packages/forwarder-helper/src/forwarder_helper_impl.ts b/packages/forwarder-helper/src/forwarder_helper_impl.ts index 83dc1f4b3..a90edb0bb 100644 --- a/packages/forwarder-helper/src/forwarder_helper_impl.ts +++ b/packages/forwarder-helper/src/forwarder_helper_impl.ts @@ -1,17 +1,14 @@ -import { marketUtils, sortingUtils } from '@0xproject/order-utils'; +import { marketUtils } from '@0xproject/order-utils'; import { SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import { constants } from './constants'; import { ForwarderHelper, ForwarderHelperError, MarketBuyOrdersInfo, MarketBuyOrdersInfoRequest } from './types'; +import { forwarderHelperImplConfigUtils } from './utils/forwarder_helper_impl_config_utils'; const SLIPPAGE_PERCENTAGE = new BigNumber(0.2); // 20% slippage protection, possibly move this into request interface -interface SignedOrderWithAmount extends SignedOrder { - remainingFillAmount?: BigNumber; -} - export interface ForwarderHelperImplConfig { orders: SignedOrder[]; feeOrders: SignedOrder[]; @@ -21,66 +18,8 @@ export interface ForwarderHelperImplConfig { export class ForwarderHelperImpl implements ForwarderHelper { public readonly config: ForwarderHelperImplConfig; - private static _createSignedOrderWithAmounts( - orders: SignedOrder[], - amounts?: BigNumber[], - ): SignedOrderWithAmount[] { - const ordersAndAmounts = _.map(orders, (order, index) => { - return { - ...order, - remainingFillAmount: _.nth(amounts, index), - }; - }); - return ordersAndAmounts; - } - private static _unbundleSignedOrderWithAmounts( - signedOrderWithAmounts: SignedOrderWithAmount[], - ): { orders: SignedOrder[]; amounts?: BigNumber[] } { - const orders = _.map(signedOrderWithAmounts, order => { - const { remainingFillAmount, ...rest } = order; - return rest; - }); - const amounts = _.map(signedOrderWithAmounts, order => { - const { remainingFillAmount } = order; - return remainingFillAmount; - }); - const compactAmounts = _.compact(amounts); - return { - orders, - amounts: compactAmounts.length > 0 ? compactAmounts : undefined, - }; - } - private static _sortedConfig(config: ForwarderHelperImplConfig): ForwarderHelperImplConfig { - const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = config; - // Bundle orders together with their remainingFillAmounts so that we can sort them together - const orderWithAmounts = ForwarderHelperImpl._createSignedOrderWithAmounts( - orders, - remainingFillableMakerAssetAmounts, - ); - // TODO: provide a feeRate to the sorting function to more accurately sort based on the current market for ZRX tokens - const sortedOrderWithAmounts = sortingUtils.sortOrdersByFeeAdjustedRate(orderWithAmounts); - // Unbundle after sorting - const unbundledSortedOrderWithAmounts = ForwarderHelperImpl._unbundleSignedOrderWithAmounts( - sortedOrderWithAmounts, - ); - // Do the same bundling + unbundling for feeOrder sorting - const feeOrderWithAmounts = ForwarderHelperImpl._createSignedOrderWithAmounts( - feeOrders, - remainingFillableFeeAmounts, - ); - const sortedFeeOrderWithAmounts = sortingUtils.sortFeeOrdersByFeeAdjustedRate(feeOrderWithAmounts); - const unbundledSortedFeeOrderWithAmounts = ForwarderHelperImpl._unbundleSignedOrderWithAmounts( - sortedFeeOrderWithAmounts, - ); - return { - orders: unbundledSortedOrderWithAmounts.orders, - feeOrders: unbundledSortedFeeOrderWithAmounts.orders, - remainingFillableMakerAssetAmounts: unbundledSortedOrderWithAmounts.amounts, - remainingFillableFeeAmounts: unbundledSortedFeeOrderWithAmounts.amounts, - }; - } constructor(config: ForwarderHelperImplConfig) { - this.config = ForwarderHelperImpl._sortedConfig(config); + this.config = forwarderHelperImplConfigUtils.sortedConfig(config); } public getMarketBuyOrdersInfo(request: MarketBuyOrdersInfoRequest): MarketBuyOrdersInfo { const { makerAssetFillAmount, feePercentage } = request; diff --git a/packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts b/packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts new file mode 100644 index 000000000..253384f65 --- /dev/null +++ b/packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts @@ -0,0 +1,92 @@ +import { sortingUtils } from '@0xproject/order-utils'; +import { SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { ForwarderHelperImplConfig } from '../forwarder_helper_impl'; + +interface SignedOrderWithAmount extends SignedOrder { + remainingFillAmount: BigNumber; +} + +export const forwarderHelperImplConfigUtils = { + sortedConfig(config: ForwarderHelperImplConfig): ForwarderHelperImplConfig { + const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = config; + // TODO: provide a feeRate to the sorting function to more accurately sort based on the current market for ZRX tokens + const orderSorter = (ordersToSort: SignedOrder[]) => { + return sortingUtils.sortOrdersByFeeAdjustedRate(ordersToSort); + }; + const sortOrdersResult = sortOrdersAndRemainingFillAmounts( + orderSorter, + orders, + remainingFillableMakerAssetAmounts, + ); + const feeOrderSorter = (ordersToSort: SignedOrder[]) => { + return sortingUtils.sortFeeOrdersByFeeAdjustedRate(ordersToSort); + }; + const sortFeeOrdersResult = sortOrdersAndRemainingFillAmounts( + feeOrderSorter, + feeOrders, + remainingFillableFeeAmounts, + ); + return { + orders: sortOrdersResult.orders, + feeOrders: sortFeeOrdersResult.orders, + remainingFillableMakerAssetAmounts: sortOrdersResult.remainingFillAmounts, + remainingFillableFeeAmounts: sortFeeOrdersResult.remainingFillAmounts, + }; + }, +}; + +type OrderSorter = (orders: SignedOrder[]) => SignedOrder[]; + +function sortOrdersAndRemainingFillAmounts( + orderSorter: OrderSorter, + orders: SignedOrder[], + remainingFillAmounts?: BigNumber[], +): { orders: SignedOrder[]; remainingFillAmounts?: BigNumber[] } { + if (!_.isUndefined(remainingFillAmounts)) { + // Bundle orders together with their remainingFillAmounts so that we can sort them together + const orderWithAmounts = bundleSignedOrderWithAmounts(orders, remainingFillAmounts); + // Sort + const sortedOrderWithAmounts = orderSorter(orderWithAmounts) as SignedOrderWithAmount[]; + // Unbundle after sorting + const unbundledSortedOrderWithAmounts = unbundleSignedOrderWithAmounts(sortedOrderWithAmounts); + return { + orders: unbundledSortedOrderWithAmounts.orders, + remainingFillAmounts: unbundledSortedOrderWithAmounts.amounts, + }; + } else { + const sortedOrders = orderSorter(orders); + return { + orders: sortedOrders, + }; + } +} + +function bundleSignedOrderWithAmounts(orders: SignedOrder[], amounts: BigNumber[]): SignedOrderWithAmount[] { + const ordersAndAmounts = _.map(orders, (order, index) => { + return { + ...order, + remainingFillAmount: amounts[index], + }; + }); + return ordersAndAmounts; +} + +function unbundleSignedOrderWithAmounts( + signedOrderWithAmounts: SignedOrderWithAmount[], +): { orders: SignedOrder[]; amounts: BigNumber[] } { + const orders = _.map(signedOrderWithAmounts, order => { + const { remainingFillAmount, ...rest } = order; + return rest; + }); + const amounts = _.map(signedOrderWithAmounts, order => { + const { remainingFillAmount } = order; + return remainingFillAmount; + }); + return { + orders, + amounts, + }; +} -- cgit v1.2.3