diff options
Diffstat (limited to 'packages/asset-buyer/src/utils/order_provider_response_processor.ts')
-rw-r--r-- | packages/asset-buyer/src/utils/order_provider_response_processor.ts | 171 |
1 files changed, 0 insertions, 171 deletions
diff --git a/packages/asset-buyer/src/utils/order_provider_response_processor.ts b/packages/asset-buyer/src/utils/order_provider_response_processor.ts deleted file mode 100644 index f08cd6150..000000000 --- a/packages/asset-buyer/src/utils/order_provider_response_processor.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { OrderAndTraderInfo, OrderStatus, OrderValidatorWrapper } from '@0x/contract-wrappers'; -import { sortingUtils } from '@0x/order-utils'; -import { RemainingFillableCalculator } from '@0x/order-utils/lib/src/remaining_fillable_calculator'; -import { SignedOrder } from '@0x/types'; -import { BigNumber } from '@0x/utils'; -import * as _ from 'lodash'; - -import { constants } from '../constants'; -import { - AssetBuyerError, - OrderProviderRequest, - OrderProviderResponse, - OrdersAndFillableAmounts, - SignedOrderWithRemainingFillableMakerAssetAmount, -} from '../types'; - -import { orderUtils } from './order_utils'; - -export const orderProviderResponseProcessor = { - throwIfInvalidResponse(response: OrderProviderResponse, request: OrderProviderRequest): void { - const { makerAssetData, takerAssetData } = request; - _.forEach(response.orders, order => { - if (order.makerAssetData !== makerAssetData || order.takerAssetData !== takerAssetData) { - throw new Error(AssetBuyerError.InvalidOrderProviderResponse); - } - }); - }, - /** - * Take the responses for the target orders to buy and fee orders and process them. - * Processing includes: - * - Drop orders that are expired or not open orders (null taker address) - * - If shouldValidateOnChain, attempt to grab fillable amounts from on-chain otherwise assume completely fillable - * - Sort by rate - */ - async processAsync( - orderProviderResponse: OrderProviderResponse, - isMakerAssetZrxToken: boolean, - expiryBufferSeconds: number, - orderValidator?: OrderValidatorWrapper, - ): Promise<OrdersAndFillableAmounts> { - // drop orders that are expired or not open - const filteredOrders = filterOutExpiredAndNonOpenOrders(orderProviderResponse.orders, expiryBufferSeconds); - // set the orders to be sorted equal to the filtered orders - let unsortedOrders = filteredOrders; - // if an orderValidator is provided, use on chain information to calculate remaining fillable makerAsset amounts - if (!_.isUndefined(orderValidator)) { - const takerAddresses = _.map(filteredOrders, () => constants.NULL_ADDRESS); - try { - const ordersAndTradersInfo = await orderValidator.getOrdersAndTradersInfoAsync( - filteredOrders, - takerAddresses, - ); - // take orders + on chain information and find the valid orders and remaining fillable maker asset amounts - unsortedOrders = getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain( - filteredOrders, - ordersAndTradersInfo, - isMakerAssetZrxToken, - ); - } catch (err) { - // Sometimes we observe this call to orderValidator fail with response `0x` - // Because of differences in Parity / Geth implementations, its very hard to tell if this response is a "system error" - // or a revert. In this case we just swallow these errors and fallback to partial fill information from the SRA. - // TODO(bmillman): report these errors so we have an idea of how often we're getting these failures. - } - } - // sort orders by rate - // TODO(bmillman): optimization - // provide a feeRate to the sorting function to more accurately sort based on the current market for ZRX tokens - const sortedOrders = isMakerAssetZrxToken - ? sortingUtils.sortFeeOrdersByFeeAdjustedRate(unsortedOrders) - : sortingUtils.sortOrdersByFeeAdjustedRate(unsortedOrders); - // unbundle orders and fillable amounts and compile final result - const result = unbundleOrdersWithAmounts(sortedOrders); - return result; - }, -}; - -/** - * Given an array of orders, return a new array with expired and non open orders filtered out. - */ -function filterOutExpiredAndNonOpenOrders( - orders: SignedOrderWithRemainingFillableMakerAssetAmount[], - expiryBufferSeconds: number, -): SignedOrderWithRemainingFillableMakerAssetAmount[] { - const result = _.filter(orders, order => { - return orderUtils.isOpenOrder(order) && !orderUtils.willOrderExpire(order, expiryBufferSeconds); - }); - return result; -} - -/** - * Given an array of orders and corresponding on-chain infos, return a subset of the orders - * that are still fillable orders with their corresponding remainingFillableMakerAssetAmounts. - */ -function getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain( - inputOrders: SignedOrder[], - ordersAndTradersInfo: OrderAndTraderInfo[], - isMakerAssetZrxToken: boolean, -): SignedOrderWithRemainingFillableMakerAssetAmount[] { - // iterate through the input orders and find the ones that are still fillable - // for the orders that are still fillable, calculate the remaining fillable maker asset amount - const result = _.reduce( - inputOrders, - (accOrders, order, index) => { - // get corresponding on-chain state for the order - const { orderInfo, traderInfo } = ordersAndTradersInfo[index]; - // if the order IS NOT fillable, do not add anything to the accumulations and continue iterating - if (orderInfo.orderStatus !== OrderStatus.Fillable) { - return accOrders; - } - // if the order IS fillable, add the order and calculate the remaining fillable amount - const transferrableAssetAmount = BigNumber.min(traderInfo.makerAllowance, traderInfo.makerBalance); - const transferrableFeeAssetAmount = BigNumber.min(traderInfo.makerZrxAllowance, traderInfo.makerZrxBalance); - const remainingTakerAssetAmount = order.takerAssetAmount.minus(orderInfo.orderTakerAssetFilledAmount); - const remainingMakerAssetAmount = orderUtils.getRemainingMakerAmount(order, remainingTakerAssetAmount); - const remainingFillableCalculator = new RemainingFillableCalculator( - order.makerFee, - order.makerAssetAmount, - isMakerAssetZrxToken, - transferrableAssetAmount, - transferrableFeeAssetAmount, - remainingMakerAssetAmount, - ); - const remainingFillableAmount = remainingFillableCalculator.computeRemainingFillable(); - // if the order does not have any remaining fillable makerAsset, do not add anything to the accumulations and continue iterating - if (remainingFillableAmount.lte(constants.ZERO_AMOUNT)) { - return accOrders; - } - const orderWithRemainingFillableMakerAssetAmount = { - ...order, - remainingFillableMakerAssetAmount: remainingFillableAmount, - }; - const newAccOrders = _.concat(accOrders, orderWithRemainingFillableMakerAssetAmount); - return newAccOrders; - }, - [] as SignedOrderWithRemainingFillableMakerAssetAmount[], - ); - return result; -} - -/** - * Given an array of orders with remaining fillable maker asset amounts. Unbundle into an instance of OrdersAndRemainingFillableMakerAssetAmounts. - * If an order is missing a corresponding remainingFillableMakerAssetAmount, assume it is completely fillable. - */ -function unbundleOrdersWithAmounts( - ordersWithAmounts: SignedOrderWithRemainingFillableMakerAssetAmount[], -): OrdersAndFillableAmounts { - const result = _.reduce( - ordersWithAmounts, - (acc, orderWithAmount) => { - const { orders, remainingFillableMakerAssetAmounts } = acc; - const { remainingFillableMakerAssetAmount, ...order } = orderWithAmount; - // if we are still missing a remainingFillableMakerAssetAmount, assume the order is completely fillable - const newRemainingAmount = remainingFillableMakerAssetAmount || order.makerAssetAmount; - // if remaining amount is less than or equal to zero, do not add it - if (newRemainingAmount.lte(constants.ZERO_AMOUNT)) { - return acc; - } - const newAcc = { - orders: _.concat(orders, order), - remainingFillableMakerAssetAmounts: _.concat(remainingFillableMakerAssetAmounts, newRemainingAmount), - }; - return newAcc; - }, - { - orders: [] as SignedOrder[], - remainingFillableMakerAssetAmounts: [] as BigNumber[], - }, - ); - return result; -} |