@0x/asset-swapper
: respect max slippage in EP consumer
This commit is contained in:
parent
a57cf68ee4
commit
6138955f93
@ -129,6 +129,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Fix Balancer sampling",
|
"note": "Fix Balancer sampling",
|
||||||
"pr": 2711
|
"pr": 2711
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Respect max slippage in EP consumer",
|
||||||
|
"pr": 2712
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -30,6 +30,8 @@ import { assert } from '../utils/assert';
|
|||||||
import { ERC20BridgeSource, UniswapV2FillData } from '../utils/market_operation_utils/types';
|
import { ERC20BridgeSource, UniswapV2FillData } from '../utils/market_operation_utils/types';
|
||||||
import { getTokenFromAssetData } from '../utils/utils';
|
import { getTokenFromAssetData } from '../utils/utils';
|
||||||
|
|
||||||
|
import { getMinBuyAmount } from './utils';
|
||||||
|
|
||||||
// tslint:disable-next-line:custom-no-magic-numbers
|
// tslint:disable-next-line:custom-no-magic-numbers
|
||||||
const MAX_UINT256 = new BigNumber(2).pow(256).minus(1);
|
const MAX_UINT256 = new BigNumber(2).pow(256).minus(1);
|
||||||
const { NULL_ADDRESS, ZERO_AMOUNT } = constants;
|
const { NULL_ADDRESS, ZERO_AMOUNT } = constants;
|
||||||
@ -93,6 +95,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
const sellToken = getTokenFromAssetData(quote.takerAssetData);
|
const sellToken = getTokenFromAssetData(quote.takerAssetData);
|
||||||
const buyToken = getTokenFromAssetData(quote.makerAssetData);
|
const buyToken = getTokenFromAssetData(quote.makerAssetData);
|
||||||
const sellAmount = quote.worstCaseQuoteInfo.totalTakerAssetAmount;
|
const sellAmount = quote.worstCaseQuoteInfo.totalTakerAssetAmount;
|
||||||
|
const minBuyAmount = getMinBuyAmount(quote);
|
||||||
|
|
||||||
// VIP routes.
|
// VIP routes.
|
||||||
if (isDirectUniswapCompatible(quote, optsWithDefaults)) {
|
if (isDirectUniswapCompatible(quote, optsWithDefaults)) {
|
||||||
@ -111,7 +114,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
return a;
|
return a;
|
||||||
}),
|
}),
|
||||||
sellAmount,
|
sellAmount,
|
||||||
quote.worstCaseQuoteInfo.makerAssetAmount,
|
minBuyAmount,
|
||||||
source === ERC20BridgeSource.SushiSwap,
|
source === ERC20BridgeSource.SushiSwap,
|
||||||
)
|
)
|
||||||
.getABIEncodedTransactionData(),
|
.getABIEncodedTransactionData(),
|
||||||
@ -225,7 +228,6 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const minBuyAmount = BigNumber.max(0, quote.worstCaseQuoteInfo.makerAssetAmount.minus(buyTokenFeeAmount));
|
|
||||||
const calldataHexString = this._exchangeProxy
|
const calldataHexString = this._exchangeProxy
|
||||||
.transformERC20(
|
.transformERC20(
|
||||||
isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
|
isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
|
||||||
|
28
packages/asset-swapper/src/quote_consumers/utils.ts
Normal file
28
packages/asset-swapper/src/quote_consumers/utils.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { BigNumber } from '@0x/utils';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { MarketOperation, SwapQuote } from '../types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the mminimum buy token amount for market operations by inferring
|
||||||
|
* the slippage from the orders in a quote. We cannot rely on
|
||||||
|
* `worstCaseQuoteInfo.makerAssetAmount` because that does not stop at
|
||||||
|
* maximum slippage.
|
||||||
|
*/
|
||||||
|
export function getMinBuyAmount(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 (totalFillMakerAssetAmount.eq(0)) {
|
||||||
|
return quote.worstCaseQuoteInfo.makerAssetAmount;
|
||||||
|
}
|
||||||
|
if (totalOrderMakerAssetAmount.eq(totalFillMakerAssetAmount)) {
|
||||||
|
// No slippage allowed on bought tokens.
|
||||||
|
return quote.bestCaseQuoteInfo.makerAssetAmount;
|
||||||
|
}
|
||||||
|
const slipRatio = totalOrderMakerAssetAmount.div(totalFillMakerAssetAmount);
|
||||||
|
return quote.bestCaseQuoteInfo.makerAssetAmount.times(slipRatio).integerValue(BigNumber.ROUND_DOWN);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user