@0x/asset-swapper: compute max quote slippage from the first non-native order in getSwapMinBuyAmount()

This commit is contained in:
Lawrence Forman 2020-09-24 10:54:14 -04:00
parent ac6b03cd4a
commit 4672c72fef

View File

@ -1,12 +1,9 @@
import { BigNumber } from '@0x/utils';
import * as _ from 'lodash';
import { constants } from '../constants';
import { MarketOperation, SwapQuote } from '../types';
import { ERC20BridgeSource } from '../utils/market_operation_utils/types';
const { ZERO_AMOUNT } = constants;
/**
* Compute the mminimum buy token amount for market operations by inferring
* the slippage from the orders in a quote. We cannot rely on
@ -17,23 +14,20 @@ export function getSwapMinBuyAmount(quote: SwapQuote): BigNumber {
if (quote.type === MarketOperation.Buy || quote.isTwoHop) {
return quote.worstCaseQuoteInfo.makerAssetAmount;
}
// Infer the allowed maker asset slippage from the orders.
const totalOrderMakerAssetAmount = BigNumber.sum(...quote.orders.map(o => o.fillableMakerAssetAmount));
// tslint:disable: prefer-conditional-expression
let totalFillMakerAssetAmount = ZERO_AMOUNT;
let slipRatio = new BigNumber(1);
// Infer the allowed maker asset slippage from any non-native order.
for (const o of quote.orders) {
if (o.fills.length === 0 || o.fills[0].source === ERC20BridgeSource.Native) {
// No slippage on natuve orders.
totalFillMakerAssetAmount = totalFillMakerAssetAmount.plus(o.fillableMakerAssetAmount);
} else {
totalFillMakerAssetAmount = totalFillMakerAssetAmount.plus(BigNumber.sum(...o.fills.map(f => f.output)));
// No slippage on native orders.
continue;
}
const totalFillMakerAssetAmount = BigNumber.sum(...o.fills.map(f => f.output));
slipRatio = o.fillableMakerAssetAmount.div(totalFillMakerAssetAmount);
break;
}
// tslint:enable: prefer-conditional-expression
if (totalOrderMakerAssetAmount.eq(totalFillMakerAssetAmount)) {
if (slipRatio.gte(1)) {
// No slippage allowed across all orders.
return quote.bestCaseQuoteInfo.makerAssetAmount;
}
const slipRatio = totalOrderMakerAssetAmount.div(totalFillMakerAssetAmount);
return quote.bestCaseQuoteInfo.makerAssetAmount.times(slipRatio).integerValue(BigNumber.ROUND_DOWN);
}