continue rebase

This commit is contained in:
Lawrence Forman
2022-02-23 02:44:38 -07:00
parent 7d5e4ed685
commit 29c77059a0
3 changed files with 80 additions and 52 deletions

View File

@@ -8,6 +8,7 @@ import {
Address,
AssetSwapperContractAddresses,
MarketOperation,
SamplerMetrics,
SignedNativeOrder,
SignedRfqOrder,
} from '../../types';
@@ -104,6 +105,7 @@ export class MarketOperationUtils {
quoteRequestor: opts.quoteRequestor,
});
}
private static _computePriceComparisonsReport(
quoteRequestor: QuoteRequestor | undefined,
marketSideLiquidity: MarketSideLiquidity,
@@ -134,8 +136,6 @@ export class MarketOperationUtils {
constructor(
private readonly _sampler: Sampler,
private readonly contractAddresses: AssetSwapperContractAddresses,
private readonly _orderDomain: OrderDomain,
) {
this._buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[_sampler.chainId];
this._sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[_sampler.chainId];
@@ -510,6 +510,8 @@ export class MarketOperationUtils {
gasPrice: opts.gasPrice,
runLimit: opts.runLimit,
maxFallbackSlippage: opts.maxFallbackSlippage,
neonRouterNumSamples: opts.neonRouterNumSamples,
samplerMetrics: opts.samplerMetrics,
},
);
if (!bestHopRoute) {
@@ -548,6 +550,7 @@ export class MarketOperationUtils {
allowFallback: _opts.allowFallback,
exchangeProxyOverhead: _opts.exchangeProxyOverhead,
gasPrice: _opts.gasPrice,
neonRouterNumSamples: _opts.ne
};
if (nativeOrders.length === 0) {
@@ -710,6 +713,8 @@ export class MarketOperationUtils {
exchangeProxyOverhead: ExchangeProxyOverhead;
runLimit?: number;
maxFallbackSlippage: number;
neonRouterNumSamples: number;
samplerMetrics?: SamplerMetrics;
}): Promise<OptimizedHop | null> {
let path = await this._findOptimalPathFromSamples({
@@ -722,6 +727,8 @@ export class MarketOperationUtils {
gasPrice: opts.gasPrice,
runLimit: opts.runLimit,
exchangeProxyOverhead: opts.exchangeProxyOverhead,
neonRouterNumSamples: opts.neonRouterNumSamples,
samplerMetrics: opts.samplerMetrics,
});
// Convert native orders and dex quotes into `Fill` objects.
if (!path) {
@@ -740,6 +747,8 @@ export class MarketOperationUtils {
runLimit: opts.runLimit,
maxFallbackSlippage: opts.maxFallbackSlippage,
exchangeProxyOverhead: opts.exchangeProxyOverhead,
neonRouterNumSamples: opts.neonRouterNumSamples,
samplerMetrics: opts.samplerMetrics,
});
}
@@ -770,6 +779,8 @@ export class MarketOperationUtils {
gasPrice: BigNumber;
exchangeProxyOverhead: ExchangeProxyOverhead;
runLimit?: number;
neonRouterNumSamples: number;
samplerMetrics?: SamplerMetrics;
}): Promise<Path | undefined | null> {
// Find the optimal path.
const penaltyOpts: PathPenaltyOpts = {
@@ -789,6 +800,8 @@ export class MarketOperationUtils {
penaltyOpts,
opts.gasPrice,
this._sampler.chainId,
opts.neonRouterNumSamples,
opts.samplerMetrics,
);
};
@@ -801,7 +814,7 @@ export class MarketOperationUtils {
inputAmountPerEth: opts.inputAmountPerEth,
gasPrice: opts.gasPrice,
});
return findOptimalPathJSAsync(opts.side, fills, opts.inputAmount, opts.runLimit, penaltyOpts);
return findOptimalPathJSAsync(opts.side, fills, opts.inputAmount, opts.runLimit, opts.samplerMetrics, penaltyOpts);
}
private async _addFallbackToPath(opts: {
@@ -815,6 +828,8 @@ export class MarketOperationUtils {
exchangeProxyOverhead: ExchangeProxyOverhead;
runLimit?: number;
maxFallbackSlippage: number;
neonRouterNumSamples: number;
samplerMetrics?: SamplerMetrics;
}): Promise<Path> {
const { path } = opts;
const pathRate = path ? path.adjustedRate() : ZERO_AMOUNT;
@@ -838,6 +853,8 @@ export class MarketOperationUtils {
runLimit: opts.runLimit,
exchangeProxyOverhead: (sourceFlags: bigint) =>
opts.exchangeProxyOverhead(sourceFlags | path.sourceFlags),
neonRouterNumSamples: opts.neonRouterNumSamples,
samplerMetrics: opts.samplerMetrics,
});
// Calculate the slippage of on-chain sources compared to the most optimal path
// if within an acceptable threshold we enable a fallback to prevent reverts
@@ -864,7 +881,9 @@ export class MarketOperationUtils {
gasPrice?: BigNumber,
runLimit?: number,
maxFallbackSlippage?: number,
} = {},
neonRouterNumSamples: number;
samplerMetrics?: SamplerMetrics;
},
): Promise<OptimizedHop[] | undefined> {
const findRoutes = (firstHop: RawHopQuotes, _hopQuotes: RawHopQuotes[] = hopQuotes): RawHopQuotes[][] => {
if (firstHop.inputToken === inputToken && firstHop.outputToken === outputToken) {
@@ -910,6 +929,8 @@ export class MarketOperationUtils {
outputToken: routeHop.outputToken,
inputAmountPerEth: tokenAmountPerEth[routeHop.inputToken] || ZERO_AMOUNT,
outputAmountPerEth: tokenAmountPerEth[routeHop.outputToken] || ZERO_AMOUNT,
neonRouterNumSamples: opts.neonRouterNumSamples,
samplerMetrics: opts.samplerMetrics,
});
if (!hop) {
// This hop could not satisfy the input amount so the

View File

@@ -550,6 +550,8 @@ export interface GenerateOptimizedOrdersOpts {
allowFallback?: boolean;
shouldBatchBridgeOrders?: boolean;
gasPrice: BigNumber;
neonRouterNumSamples: number;
samplerMetrics?: SamplerMetrics;
}
export interface ComparisonPrice {

View File

@@ -184,8 +184,8 @@ export function generateQuoteReport(opts: {
* swap quote, the sources ultimately included in the computed quote. This
* extende version incudes all considered quotes, not only native liquidity.
*/
export function generateExtendedQuoteReportSources(
marketOperation: MarketOperation,
export function generateExtendedQuoteReportSources(opts: {
side: MarketOperation,
inputToken: Address,
outputToken: Address,
rawHopQuotes: RawHopQuotes[],
@@ -193,40 +193,32 @@ export function generateExtendedQuoteReportSources(
amount: BigNumber,
comparisonPrice?: BigNumber | undefined,
quoteRequestor?: QuoteRequestor,
): ExtendedQuoteReportSources {
}): ExtendedQuoteReportSources {
const { inputToken, outputToken, side } = opts;
const directHops = opts.rawHopQuotes
.filter(h => h.inputToken === inputToken && h.outputToken === outputToken)
.flat(1)
.reduce((a, q) => ({ ...a, dexQuotes: a.dexQuotes.concat(q.dexQuotes), nativeOrders: a.nativeOrders.concat(q.nativeOrders)}));
const sourcesConsidered: ExtendedQuoteReportEntry[] = [];
// NativeOrders
// Native orders.
sourcesConsidered.push(
...quotes.nativeOrders.map(order =>
nativeOrderToReportEntry(
order.type,
order as any,
order.fillableTakerAmount,
comparisonPrice,
quoteRequestor,
),
),
...directHops.nativeOrders
.filter(o => o.type === FillQuoteTransformerOrderType.Rfq)
.map(o => nativeOrderToReportEntry(side, o, opts.comparisonPrice, opts.quoteRequestor)),
);
// IndicativeQuotes
// Dex quotes.
sourcesConsidered.push(
...quotes.rfqtIndicativeQuotes.map(order => indicativeQuoteToReportEntry(order, comparisonPrice)),
// Only add the last sample that can satisfy the full input amount.
...directHops.dexQuotes.map(samples => samples[samples.length - 1])
.flat(1)
.filter(s => s.input.gte(opts.amount))
.map(s => dexSampleToReportSource(side, s)),
);
// MultiHop
sourcesConsidered.push(...quotes.twoHopQuotes.map(quote => multiHopSampleToReportSource(quote, marketOperation)));
// TODO: MultiHop
// Dex Quotes
sourcesConsidered.push(
..._.flatten(
quotes.dexQuotes.map(dex =>
dex
.filter(quote => isDexSampleForTotalAmount(quote, marketOperation, amount))
.map(quote => dexSampleToReportSource(quote, marketOperation)),
),
),
);
const sourcesConsideredIndexed = sourcesConsidered.map(
(quote, index): ExtendedQuoteReportIndexedEntry => {
return {
@@ -236,32 +228,45 @@ export function generateExtendedQuoteReportSources(
};
},
);
let sourcesDelivered;
if (Array.isArray(liquidityDelivered)) {
// create easy way to look up fillable amounts
const nativeOrderSignaturesToFillableAmounts = _.fromPairs(
quotes.nativeOrders.map(o => {
return [_nativeDataToId(o), o.fillableTakerAmount];
}),
);
// map sources delivered
sourcesDelivered = liquidityDelivered.map(collapsedFill => {
if (_isNativeOrderFromCollapsedFill(collapsedFill)) {
return nativeOrderToReportEntry(
collapsedFill.type,
collapsedFill.fillData,
nativeOrderSignaturesToFillableAmounts[_nativeDataToId(collapsedFill.fillData)],
comparisonPrice,
quoteRequestor,
);
} else {
return dexSampleToReportSource(collapsedFill, marketOperation);
if (opts.hops.length === 1) {
// Single-hop.
const [hop] = opts.hops;
sourcesDelivered = hop.orders.map(o => {
switch (o.type) {
default: {
const [makerAmount, takerAmount] = side === MarketOperation.Sell
? [o.outputAmount, o.inputAmount]
: [o.inputAmount, o.outputAmount];
return {
makerAmount,
takerAmount,
liquiditySource: o.source,
fillData: {}, // Does this matter?
} as BridgeQuoteReportEntry;
}
case FillQuoteTransformerOrderType.Limit:
case FillQuoteTransformerOrderType.Rfq: {
return nativeOrderToReportEntry(side, o, opts.comparisonPrice, opts.quoteRequestor);
}
}
});
} else {
// Multi-hop.
const firstHop = opts.hops[0];
const lastHop = opts.hops[opts.hops.length - 1];
const [makerAmount, takerAmount] = side === MarketOperation.Sell
? [lastHop.outputAmount, firstHop.inputAmount]
: [firstHop.inputAmount, lastHop.outputAmount];
sourcesDelivered = [
// tslint:disable-next-line: no-unnecessary-type-assertion
multiHopSampleToReportSource(liquidityDelivered as DexSample<MultiHopFillData>, marketOperation),
{
makerAmount,
takerAmount,
liquiditySource: ERC20BridgeSource.MultiHop,
fillData: {},
hopSources: opts.hops.map(h => h.orders.map(o => o.source)).flat(1),
} as MultiHopQuoteReportEntry,
];
}
const sourcesDeliveredIndexed = sourcesDelivered.map(