diff options
Diffstat (limited to 'packages/forwarder-helper/src')
-rw-r--r-- | packages/forwarder-helper/src/forwarder_helper_impl.ts | 94 |
1 files changed, 75 insertions, 19 deletions
diff --git a/packages/forwarder-helper/src/forwarder_helper_impl.ts b/packages/forwarder-helper/src/forwarder_helper_impl.ts index 0d03c9f76..8f4ec1c02 100644 --- a/packages/forwarder-helper/src/forwarder_helper_impl.ts +++ b/packages/forwarder-helper/src/forwarder_helper_impl.ts @@ -1,37 +1,93 @@ -import { marketUtils } from '@0xproject/order-utils'; +import { marketUtils, sortingUtils } 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'; 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[]; + remainingFillableMakerAssetAmounts?: BigNumber[]; + remainingFillableFeeAmounts?: BigNumber[]; +} + export class ForwarderHelperImpl implements ForwarderHelper { - private _orders: SignedOrder[]; - private _feeOrders: SignedOrder[]; - private _remainingFillableMakerAssetAmountsIfExists?: BigNumber[]; - private _remainingFillableFeeAmountsIfExists?: BigNumber[]; - constructor( + private _config: ForwarderHelperImplConfig; + private static _createSignedOrderWithAmounts( orders: SignedOrder[], - feeOrders: SignedOrder[] = [] as SignedOrder[], - remainingFillableMakerAssetAmounts?: BigNumber[], - remainingFillableFeeAmounts?: BigNumber[], - ) { - this._orders = orders; - this._feeOrders = feeOrders; - this._remainingFillableMakerAssetAmountsIfExists = remainingFillableMakerAssetAmounts; - this._remainingFillableFeeAmountsIfExists = remainingFillableFeeAmounts; + 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, ...rest } = order; + return remainingFillAmount; + }); + const compactAmounts = _.compact(amounts); + return { + orders, + amounts: compactAmounts.length > 0 ? compactAmounts : undefined, + }; + } + private static _sortConfig(opts: ForwarderHelperImplConfig): ForwarderHelperImplConfig { + const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = opts; + const orderWithAmounts = ForwarderHelperImpl._createSignedOrderWithAmounts( + orders, + remainingFillableMakerAssetAmounts, + ); + const sortedOrderWithAmounts = sortingUtils.sortOrdersByFeeAdjustedRate(orderWithAmounts); + const unbundledSortedOrderWithAmounts = ForwarderHelperImpl._unbundleSignedOrderWithAmounts( + sortedOrderWithAmounts, + ); + 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(opts: ForwarderHelperImplConfig) { + this._config = ForwarderHelperImpl._sortConfig(opts); } public getMarketBuyOrdersInfo(request: MarketBuyOrdersInfoRequest): MarketBuyOrdersInfo { const { makerAssetFillAmount, feePercentage } = request; + const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = this._config; // TODO: make the slippage percentage customizable const slippageBufferAmount = makerAssetFillAmount.mul(SLIPPAGE_PERCENTAGE); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( - this._orders, + orders, makerAssetFillAmount, { - remainingFillableMakerAssetAmounts: this._remainingFillableMakerAssetAmountsIfExists, + remainingFillableMakerAssetAmounts, slippageBufferAmount, }, ); @@ -42,10 +98,10 @@ export class ForwarderHelperImpl implements ForwarderHelper { // finding order that cover all fees, this will help with estimating ETH and minimizing gas usage const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( resultOrders, - this._feeOrders, + feeOrders, { - remainingFillableMakerAssetAmounts: this._remainingFillableMakerAssetAmountsIfExists, - remainingFillableFeeAmounts: this._remainingFillableFeeAmountsIfExists, + remainingFillableMakerAssetAmounts, + remainingFillableFeeAmounts, }, ); if (remainingFeeAmount.gt(constants.ZERO_AMOUNT)) { |