diff --git a/package-lock.json b/package-lock.json index 19a0c9e88..dffd5be21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@uniswap/smart-order-router", - "version": "4.7.1", + "version": "4.7.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@uniswap/smart-order-router", - "version": "4.7.1", + "version": "4.7.2", "license": "GPL", "dependencies": { "@eth-optimism/sdk": "^3.2.2", diff --git a/package.json b/package.json index f629f0afc..46b4a3094 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@uniswap/smart-order-router", - "version": "4.7.1", + "version": "4.7.2", "description": "Uniswap Smart Order Router", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/src/routers/alpha-router/alpha-router.ts b/src/routers/alpha-router/alpha-router.ts index f12702d0d..b798c62be 100644 --- a/src/routers/alpha-router/alpha-router.ts +++ b/src/routers/alpha-router/alpha-router.ts @@ -2455,7 +2455,12 @@ export class AlphaRouter ); if (bestSwapRoute) { - this.emitPoolSelectionMetrics(bestSwapRoute, allCandidatePools); + this.emitPoolSelectionMetrics( + bestSwapRoute, + allCandidatePools, + currencyIn, + currencyOut + ); } return bestSwapRoute; @@ -2722,7 +2727,9 @@ export class AlphaRouter routes: RouteWithValidQuote[]; estimatedGasUsed: BigNumber; }, - allPoolsBySelection: CandidatePoolsBySelectionCriteria[] + allPoolsBySelection: CandidatePoolsBySelectionCriteria[], + currencyIn: Currency, + currencyOut: Currency ) { const poolAddressesUsed = new Set(); const { routes: routeAmounts } = swapRouteRaw; @@ -2753,10 +2760,14 @@ export class AlphaRouter ); } + let hasV4Route = false; let hasV3Route = false; let hasV2Route = false; let hasMixedRoute = false; for (const routeAmount of routeAmounts) { + if (routeAmount.protocol === Protocol.V4) { + hasV4Route = true; + } if (routeAmount.protocol === Protocol.V3) { hasV3Route = true; } @@ -2768,40 +2779,62 @@ export class AlphaRouter } } - if (hasMixedRoute && (hasV3Route || hasV2Route)) { - if (hasV3Route && hasV2Route) { + if (hasMixedRoute && (hasV4Route || hasV3Route || hasV2Route)) { + let metricsPrefix = 'Mixed'; + + if (hasV4Route) { + metricsPrefix += 'AndV4'; + } + + if (hasV3Route) { + metricsPrefix += 'AndV3'; + } + + if (hasV2Route) { + metricsPrefix += 'AndV2'; + } + + metric.putMetric(`${metricsPrefix}SplitRoute`, 1, MetricLoggerUnit.Count); + metric.putMetric( + `${metricsPrefix}SplitRouteForChain${this.chainId}`, + 1, + MetricLoggerUnit.Count + ); + + if (hasV4Route && (currencyIn.isNative || currencyOut.isNative)) { + // Keep track of this edge case https://linear.app/uniswap/issue/ROUTE-303/tech-debt-split-route-can-have-different-ethweth-input-or-output#comment-bba53758 metric.putMetric( - `MixedAndV3AndV2SplitRoute`, + `${metricsPrefix}SplitRouteWithNativeToken`, 1, MetricLoggerUnit.Count ); metric.putMetric( - `MixedAndV3AndV2SplitRouteForChain${this.chainId}`, + `${metricsPrefix}SplitRouteWithNativeTokenForChain${this.chainId}`, 1, MetricLoggerUnit.Count ); - } else if (hasV3Route) { - metric.putMetric(`MixedAndV3SplitRoute`, 1, MetricLoggerUnit.Count); + } + } else if (hasV4Route && hasV3Route && hasV2Route) { + metric.putMetric(`V4AndV3AndV2SplitRoute`, 1, MetricLoggerUnit.Count); + metric.putMetric( + `V4AndV3AndV2SplitRouteForChain${this.chainId}`, + 1, + MetricLoggerUnit.Count + ); + + if (currencyIn.isNative || currencyOut.isNative) { + // Keep track of this edge case https://linear.app/uniswap/issue/ROUTE-303/tech-debt-split-route-can-have-different-ethweth-input-or-output#comment-bba53758 metric.putMetric( - `MixedAndV3SplitRouteForChain${this.chainId}`, + `V4AndV3AndV2SplitRouteWithNativeToken`, 1, MetricLoggerUnit.Count ); - } else if (hasV2Route) { - metric.putMetric(`MixedAndV2SplitRoute`, 1, MetricLoggerUnit.Count); metric.putMetric( - `MixedAndV2SplitRouteForChain${this.chainId}`, + `V4AndV3AndV2SplitRouteWithNativeTokenForChain${this.chainId}`, 1, MetricLoggerUnit.Count ); } - } else if (hasV3Route && hasV2Route) { - metric.putMetric(`V3AndV2SplitRoute`, 1, MetricLoggerUnit.Count); - metric.putMetric( - `V3AndV2SplitRouteForChain${this.chainId}`, - 1, - MetricLoggerUnit.Count - ); } else if (hasMixedRoute) { if (routeAmounts.length > 1) { metric.putMetric(`MixedSplitRoute`, 1, MetricLoggerUnit.Count); @@ -2818,6 +2851,15 @@ export class AlphaRouter MetricLoggerUnit.Count ); } + } else if (hasV4Route) { + if (routeAmounts.length > 1) { + metric.putMetric(`V4SplitRoute`, 1, MetricLoggerUnit.Count); + metric.putMetric( + `V4SplitRouteForChain${this.chainId}`, + 1, + MetricLoggerUnit.Count + ); + } } else if (hasV3Route) { if (routeAmounts.length > 1) { metric.putMetric(`V3SplitRoute`, 1, MetricLoggerUnit.Count); diff --git a/src/util/routes.ts b/src/util/routes.ts index bbe7e628f..6884230b0 100644 --- a/src/util/routes.ts +++ b/src/util/routes.ts @@ -1,4 +1,4 @@ -import { ADDRESS_ZERO, Protocol } from '@uniswap/router-sdk'; +import { Protocol } from '@uniswap/router-sdk'; import { Currency, Percent } from '@uniswap/sdk-core'; import { Pair } from '@uniswap/v2-sdk'; import { Pool as V3Pool } from '@uniswap/v3-sdk'; @@ -50,8 +50,8 @@ export const poolToString = (pool: TPool): string => { pool.token0, pool.token1, pool.fee, - 0, - ADDRESS_ZERO + pool.tickSpacing, + pool.hooks )}]`; } else if (pool instanceof V3Pool) { return ` -- ${pool.fee / 10000}% [${V3Pool.getAddress( @@ -95,8 +95,8 @@ export const routeToString = (route: SupportedRoutes): string => { pool.token0, pool.token1, pool.fee, - 0, - ADDRESS_ZERO + pool.tickSpacing, + pool.hooks )}]`; } else { throw new Error(`Unsupported pool ${JSON.stringify(pool)}`); @@ -131,7 +131,7 @@ export const routeAmountsToString = ( const percent = new Percent(portion.numerator, portion.denominator); /// @dev special case for MIXED routes we want to show user friendly V2+V3 instead return `[${ - protocol == Protocol.MIXED ? 'V2 + V3' : protocol + protocol == Protocol.MIXED ? 'V2 + V3 + V4' : protocol }] ${percent.toFixed(2)}% = ${routeToString(route)}`; });