@0x/asset-swapper: Handle native orders in getSwapMinBuyAmount()
This commit is contained in:
@@ -2,6 +2,10 @@ import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { MarketOperation, SwapQuote } from '../types';
|
||||
import { ERC20BridgeSource } from '../utils/market_operation_utils/types';
|
||||
import { constants } from '../constants';
|
||||
|
||||
const { ZERO_AMOUNT } = constants;
|
||||
|
||||
/**
|
||||
* Compute the mminimum buy token amount for market operations by inferring
|
||||
@@ -10,19 +14,25 @@ import { MarketOperation, SwapQuote } from '../types';
|
||||
* maximum slippage.
|
||||
*/
|
||||
export function getSwapMinBuyAmount(quote: SwapQuote): BigNumber {
|
||||
// Infer the allowed maker asset slippage from the orders.
|
||||
const totalOrderMakerAssetAmount = BigNumber.sum(...quote.orders.map(o => o.makerAssetAmount));
|
||||
const totalFillMakerAssetAmount =
|
||||
quote.type === MarketOperation.Sell
|
||||
? BigNumber.sum(...quote.orders.map(o => BigNumber.sum(0, ...o.fills.map(f => f.output))))
|
||||
: BigNumber.sum(...quote.orders.map(o => BigNumber.sum(0, ...o.fills.map(f => f.input))));
|
||||
if (quote.isTwoHop || totalFillMakerAssetAmount.eq(0)) {
|
||||
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));
|
||||
let totalFillMakerAssetAmount = ZERO_AMOUNT;
|
||||
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)));
|
||||
}
|
||||
}
|
||||
if (totalOrderMakerAssetAmount.eq(totalFillMakerAssetAmount)) {
|
||||
// No slippage allowed on bought tokens.
|
||||
// No slippage allowed across all orders.
|
||||
return quote.bestCaseQuoteInfo.makerAssetAmount;
|
||||
}
|
||||
const slipRatio = totalOrderMakerAssetAmount.div(totalFillMakerAssetAmount);
|
||||
console.log(slipRatio);
|
||||
return quote.bestCaseQuoteInfo.makerAssetAmount.times(slipRatio).integerValue(BigNumber.ROUND_DOWN);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ function createBridgeOrder(
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
makerToken,
|
||||
bridgeAddress,
|
||||
createBalancerBridgeData(takerToken, balancerFillData.poolAddress),
|
||||
createBalancerBridgeData(takerToken, makerToken),
|
||||
);
|
||||
break;
|
||||
case ERC20BridgeSource.Bancor:
|
||||
|
||||
@@ -18,6 +18,7 @@ import 'mocha';
|
||||
|
||||
import { constants } from '../src/constants';
|
||||
import { ExchangeProxySwapQuoteConsumer } from '../src/quote_consumers/exchange_proxy_swap_quote_consumer';
|
||||
import { getSwapMinBuyAmount } from '../src/quote_consumers/utils';
|
||||
import { MarketBuySwapQuote, MarketOperation, MarketSellSwapQuote } from '../src/types';
|
||||
import { OptimizedMarketOrder } from '../src/utils/market_operation_utils/types';
|
||||
|
||||
@@ -191,7 +192,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
|
||||
expect(callArgs.inputToken).to.eq(TAKER_TOKEN);
|
||||
expect(callArgs.outputToken).to.eq(MAKER_TOKEN);
|
||||
expect(callArgs.inputTokenAmount).to.bignumber.eq(quote.worstCaseQuoteInfo.totalTakerAssetAmount);
|
||||
expect(callArgs.minOutputTokenAmount).to.bignumber.eq(quote.worstCaseQuoteInfo.makerAssetAmount);
|
||||
expect(callArgs.minOutputTokenAmount).to.bignumber.eq(getSwapMinBuyAmount(quote));
|
||||
expect(callArgs.transformations).to.be.length(2);
|
||||
expect(
|
||||
callArgs.transformations[0].deploymentNonce.toNumber() ===
|
||||
@@ -220,7 +221,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
|
||||
expect(callArgs.inputToken).to.eq(TAKER_TOKEN);
|
||||
expect(callArgs.outputToken).to.eq(MAKER_TOKEN);
|
||||
expect(callArgs.inputTokenAmount).to.bignumber.eq(quote.worstCaseQuoteInfo.totalTakerAssetAmount);
|
||||
expect(callArgs.minOutputTokenAmount).to.bignumber.eq(quote.worstCaseQuoteInfo.makerAssetAmount);
|
||||
expect(callArgs.minOutputTokenAmount).to.bignumber.eq(getSwapMinBuyAmount(quote));
|
||||
expect(callArgs.transformations).to.be.length(2);
|
||||
expect(
|
||||
callArgs.transformations[0].deploymentNonce.toNumber() ===
|
||||
@@ -318,7 +319,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
|
||||
expect(callArgs.inputToken).to.eq(TAKER_TOKEN);
|
||||
expect(callArgs.outputToken).to.eq(MAKER_TOKEN);
|
||||
expect(callArgs.inputTokenAmount).to.bignumber.eq(quote.worstCaseQuoteInfo.totalTakerAssetAmount);
|
||||
expect(callArgs.minOutputTokenAmount).to.bignumber.eq(quote.worstCaseQuoteInfo.makerAssetAmount);
|
||||
expect(callArgs.minOutputTokenAmount).to.bignumber.eq(getSwapMinBuyAmount(quote));
|
||||
expect(callArgs.transformations).to.be.length(3);
|
||||
expect(
|
||||
callArgs.transformations[0].deploymentNonce.toNumber() ===
|
||||
|
||||
Reference in New Issue
Block a user