@0x/asset-swapper
: Clean up source breakdown code a bit.
`@0x/asset-swapper`: Allow Kyber conflicts in fallback path.
This commit is contained in:
@@ -260,23 +260,23 @@ export function collapsePath(side: MarketOperation, path: Fill[]): CollapsedFill
|
||||
}
|
||||
|
||||
export function getFallbackSourcePaths(optimalPath: Fill[], allPaths: Fill[][]): Fill[][] {
|
||||
let optimalPathFlags = 0;
|
||||
const optimalSources: ERC20BridgeSource[] = [];
|
||||
for (const fill of optimalPath) {
|
||||
optimalPathFlags |= fill.flags;
|
||||
if (!optimalSources.includes(fill.source)) {
|
||||
optimalSources.push(fill.source);
|
||||
}
|
||||
}
|
||||
const conflictFlags = FillFlags.Kyber | FillFlags.ConflictsWithKyber;
|
||||
const fallbackPaths: Fill[][] = [];
|
||||
for (const path of allPaths) {
|
||||
if (((optimalPathFlags | path[0].flags) & conflictFlags) === conflictFlags) {
|
||||
continue;
|
||||
}
|
||||
if (optimalSources.includes(path[0].source)) {
|
||||
continue;
|
||||
}
|
||||
// HACK(dorothy-zbornak): We *should* be filtering out paths that
|
||||
// conflict with the optimal path (i.e., Kyber conflicts), but in
|
||||
// practice we often end up not being able to find a fallback path
|
||||
// because we've lost 2 major liquiduty sources. The end result is
|
||||
// we end up with many more reverts than what would be actually caused
|
||||
// by conflicts.
|
||||
fallbackPaths.push(path);
|
||||
}
|
||||
return fallbackPaths;
|
||||
|
@@ -285,10 +285,10 @@ export class MarketOperationUtils {
|
||||
let fallbackPath: Fill[] = [];
|
||||
const nativeSubPath = optimalPath.filter(f => f.source === ERC20BridgeSource.Native);
|
||||
if (opts.allowFallback && nativeSubPath.length !== 0) {
|
||||
// The fallback path is only as large as the native path.
|
||||
const [nativeInputAmount] = getPathSize(nativeSubPath, inputAmount);
|
||||
// The fallback path is, at most, as large as the native path.
|
||||
const fallbackInputAmount = BigNumber.min(inputAmount, getPathSize(nativeSubPath, inputAmount)[0]);
|
||||
fallbackPath =
|
||||
findOptimalPath(side, getFallbackSourcePaths(optimalPath, paths), nativeInputAmount, opts.runLimit) ||
|
||||
findOptimalPath(side, getFallbackSourcePaths(optimalPath, paths), fallbackInputAmount, opts.runLimit) ||
|
||||
[];
|
||||
}
|
||||
return createOrdersFromPath([...optimalPath, ...fallbackPath], {
|
||||
|
@@ -198,7 +198,7 @@ export class SwapQuoteCalculator {
|
||||
true,
|
||||
);
|
||||
|
||||
const breakdown = this._getSwapQuoteOrdersBreakdown(resultOrders, operation);
|
||||
const breakdown = getSwapQuoteOrdersBreakdown(resultOrders, operation);
|
||||
|
||||
const quoteBase: SwapQuoteBase = {
|
||||
takerAssetData,
|
||||
@@ -427,36 +427,27 @@ export class SwapQuoteCalculator {
|
||||
gas: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: prefer-function-over-method
|
||||
private _getSwapQuoteOrdersBreakdown(
|
||||
orders: OptimizedMarketOrder[],
|
||||
operation: MarketOperation,
|
||||
): SwapQuoteOrdersBreakdown {
|
||||
// HACK: to shut up linter
|
||||
const breakdown: SwapQuoteOrdersBreakdown = {};
|
||||
|
||||
// total asset amount (accounting for slippage protection)
|
||||
const totalAssetAmount = BigNumber.sum(
|
||||
...[
|
||||
constants.ZERO_AMOUNT,
|
||||
...orders.map(o => (operation === MarketOperation.Buy ? o.makerAssetAmount : o.takerAssetAmount)),
|
||||
],
|
||||
);
|
||||
|
||||
return orders.reduce((acc: SwapQuoteOrdersBreakdown, order: OptimizedMarketOrder): SwapQuoteOrdersBreakdown => {
|
||||
const assetAmount = operation === MarketOperation.Buy ? order.makerAssetAmount : order.takerAssetAmount;
|
||||
const { source } = order.fill;
|
||||
return {
|
||||
...acc,
|
||||
...{
|
||||
[source]: !!acc[source]
|
||||
? acc[source].plus(assetAmount.dividedBy(totalAssetAmount))
|
||||
: assetAmount.dividedBy(totalAssetAmount),
|
||||
},
|
||||
};
|
||||
}, breakdown);
|
||||
function getSwapQuoteOrdersBreakdown(
|
||||
orders: OptimizedMarketOrder[],
|
||||
operation: MarketOperation,
|
||||
): SwapQuoteOrdersBreakdown {
|
||||
const orderAmounts =
|
||||
operation === MarketOperation.Buy
|
||||
? orders.map(o => o.fill.totalMakerAssetAmount)
|
||||
: orders.map(o => o.fill.totalTakerAssetAmount);
|
||||
const amountsBySource: SwapQuoteOrdersBreakdown = {};
|
||||
orders.forEach((o, i) => {
|
||||
const source = o.fill.source;
|
||||
amountsBySource[source] = orderAmounts[i].plus(amountsBySource[source] || 0);
|
||||
});
|
||||
const totalAmount = BigNumber.sum(0, ...orderAmounts);
|
||||
const breakdown: SwapQuoteOrdersBreakdown = {};
|
||||
for (const [source, amount] of Object.entries(amountsBySource)) {
|
||||
breakdown[source] = amount.div(totalAmount);
|
||||
}
|
||||
return breakdown;
|
||||
}
|
||||
|
||||
function getTakerAssetAmountBreakDown(
|
||||
|
Reference in New Issue
Block a user