Skip to content

Commit

Permalink
chore: bump sor to 4.17.7 - fix: mixed route support ETH <-> WETH (#819)
Browse files Browse the repository at this point in the history
* chore: bump sor to 4.17.7 - fix: mixed route support ETH <-> WETH

* 4.17.7

* chore: bump sor to 4.17.7 - fix: mixed route support ETH <-> WETH

* add more comments

* add unit test

* routeString skip fake v4 pool

* standard route string separator

* export pool
  • Loading branch information
jsy1218 authored Feb 7, 2025
1 parent e53239a commit c0caf26
Show file tree
Hide file tree
Showing 12 changed files with 445 additions and 47 deletions.
58 changes: 29 additions & 29 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@uniswap/smart-order-router",
"version": "4.17.6",
"version": "4.17.7",
"description": "Uniswap Smart Order Router",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down Expand Up @@ -37,15 +37,15 @@
"@types/brotli": "^1.3.4",
"@uniswap/default-token-list": "^11.13.0",
"@uniswap/permit2-sdk": "^1.3.0",
"@uniswap/router-sdk": "^1.21.0",
"@uniswap/router-sdk": "^1.22.1",
"@uniswap/sdk-core": "^7.5.0",
"@uniswap/swap-router-contracts": "^1.3.1",
"@uniswap/token-lists": "^1.0.0-beta.31",
"@uniswap/universal-router": "^1.6.0",
"@uniswap/universal-router-sdk": "^4.14.0",
"@uniswap/universal-router-sdk": "^4.17.0",
"@uniswap/v2-sdk": "^4.13.0",
"@uniswap/v3-sdk": "^3.24.0",
"@uniswap/v4-sdk": "^1.18.0",
"@uniswap/v4-sdk": "^1.18.1",
"async-retry": "^1.3.1",
"await-timeout": "^1.1.1",
"axios": "^0.21.1",
Expand Down
3 changes: 2 additions & 1 deletion src/providers/on-chain-quote-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,9 +483,10 @@ export class OnChainQuoteProvider implements IOnChainQuoteProvider {
// Hence in case of V2 or mixed, we explicitly encode into mixed routes.
case Protocol.V2:
case Protocol.MIXED:
// we need to retain the fake pool data for the mixed route
return encodeMixedRouteToPath(
route instanceof V2Route
? new MixedRouteSDK(route.pairs, route.input, route.output)
? new MixedRouteSDK(route.pairs, route.input, route.output, true)
: route
) as TPath;
default:
Expand Down
52 changes: 44 additions & 8 deletions src/routers/alpha-router/functions/compute-all-routes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { TPool } from '@uniswap/router-sdk/dist/utils/TPool';
import { Currency, Token } from '@uniswap/sdk-core';
import { ChainId, Currency, Token } from '@uniswap/sdk-core';
import { Pair } from '@uniswap/v2-sdk';
import { Pool as V3Pool } from '@uniswap/v3-sdk';
import { Pool as V4Pool } from '@uniswap/v4-sdk';

import { getAddressLowerCase } from '../../../util';
import { getAddressLowerCase, nativeOnChain } from '../../../util';
import { log } from '../../../util/log';
import { V4_ETH_WETH_FAKE_POOL } from '../../../util/pool';
import { poolToString, routeToString } from '../../../util/routes';
import {
MixedRoute,
Expand Down Expand Up @@ -75,17 +76,35 @@ export function computeAllMixedRoutes(
parts: TPool[],
maxHops: number
): MixedRoute[] {
// only add fake v4 pool, if we see there's a native v4 pool in the candidate pool
const containsV4NativePools =
parts.filter(
(pool) =>
pool instanceof V4Pool &&
pool.v4InvolvesToken(nativeOnChain(currencyIn.chainId))
).length > 0;
const amendedPools = containsV4NativePools
? parts.concat(V4_ETH_WETH_FAKE_POOL[currencyIn.chainId as ChainId])
: parts;
// NOTE: we added a fake v4 pool, in order for mixed route to connect the v3 weth pool with v4 eth pool
const routesRaw = computeAllRoutes<TPool, MixedRoute, Currency>(
currencyIn,
currencyOut,
(route: TPool[], currencyIn: Currency, currencyOut: Currency) => {
return new MixedRoute(route, currencyIn, currencyOut);
// we only retake the fake v4 pool if the route contains a native v4 pool
return new MixedRoute(
route,
currencyIn,
currencyOut,
containsV4NativePools
);
},
(pool: TPool, currency: Currency) =>
currency.isNative
(pool: TPool, currency: Currency) => {
return currency.isNative
? (pool as V4Pool).involvesToken(currency)
: pool.involvesToken(currency),
parts,
: pool.involvesToken(currency);
},
amendedPools,
maxHops
);
/// filter out pure v4 and v3 and v2 routes
Expand Down Expand Up @@ -125,7 +144,24 @@ export function computeAllRoutes<
tokensVisited: Set<string>,
_previousTokenOut?: TCurrency
) => {
if (currentRoute.length > maxHops) {
const currentRouteContainsFakeV4Pool =
currentRoute.filter(
(pool) =>
pool instanceof V4Pool &&
pool.tickSpacing ===
V4_ETH_WETH_FAKE_POOL[tokenIn.chainId as ChainId].tickSpacing
).length > 0;
const amendedMaxHops = currentRouteContainsFakeV4Pool
? maxHops + 1
: maxHops;

// amendedMaxHops is the maxHops + 1 if the current route contains a fake v4 pool
// b/c we want to allow the route to go through the fake v4 pool
// also gas wise, if a route goes through the fake v4 pool, mixed quoter will add the wrap/unwrap gas cost:
// https://github.com/Uniswap/mixed-quoter/pull/41/files#diff-a4d1289f264d1da22aac20cc55a9d01c8ba9cccd76ce1af8f952ec9034e7e1aaR189
// and SOR will use the gas cost from the mixed quoter:
// https://github.com/Uniswap/smart-order-router/blob/17da523f1af050e6430afb866d96681346c8fb8b/src/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.ts#L222
if (currentRoute.length > amendedMaxHops) {
return;
}

Expand Down
13 changes: 9 additions & 4 deletions src/routers/alpha-router/functions/get-candidate-pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,7 @@ export async function getMixedRouteCandidatePools({
v4PoolProvider,
v3poolProvider,
v2poolProvider,
chainId,
}: MixedRouteGetCandidatePoolsParams): Promise<MixedCandidatePools> {
const beforeSubgraphPools = Date.now();
const [
Expand Down Expand Up @@ -2076,10 +2077,15 @@ export async function getMixedRouteCandidatePools({

const V4tokenPairsRaw = _.map<
V4SubgraphPool,
[Token, Token, number, number, string] | undefined
[Currency, Currency, number, number, string] | undefined
>(V4sortedPools, (subgraphPool) => {
const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
// native currency is not erc20 token, therefore there's no way to retrieve native currency metadata as the erc20 token.
const tokenA = isNativeCurrency(subgraphPool.token0.id)
? nativeOnChain(chainId)
: tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
const tokenB = isNativeCurrency(subgraphPool.token1.id)
? nativeOnChain(chainId)
: tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
let fee: FeeAmount;
try {
fee = Number(subgraphPool.feeTier);
Expand All @@ -2090,7 +2096,6 @@ export async function getMixedRouteCandidatePools({
);
return undefined;
}

if (!tokenA || !tokenB) {
log.info(
`Dropping candidate pool for ${subgraphPool.token0.id}/${
Expand Down
2 changes: 2 additions & 0 deletions src/util/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,14 @@ export const MIXED_ROUTE_QUOTER_V1_ADDRESSES: AddressMap = {
CHAIN_TO_ADDRESSES_MAP[ChainId.MAINNET].mixedRouteQuoterV1Address,
[ChainId.GOERLI]:
CHAIN_TO_ADDRESSES_MAP[ChainId.GOERLI].mixedRouteQuoterV1Address,
[ChainId.BASE]: '0xc7A3b85D43fF66AD98A895dE0EaE4b9e24C932D7',
};

export const MIXED_ROUTE_QUOTER_V2_ADDRESSES: AddressMap = {
[ChainId.SEPOLIA]:
CHAIN_TO_ADDRESSES_MAP[ChainId.SEPOLIA].mixedRouteQuoterV2Address,
[ChainId.MAINNET]: '0xE63C5F5005909E96b5aA9CE10744CCE70eC16CC3',
[ChainId.BASE]: '0xc7A3b85D43fF66AD98A895dE0EaE4b9e24C932D7',
};

export const UNISWAP_MULTICALL_ADDRESSES: AddressMap = {
Expand Down
1 change: 1 addition & 0 deletions src/util/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const MIXED_SUPPORTED = [
ChainId.MAINNET,
ChainId.SEPOLIA,
ChainId.GOERLI,
ChainId.BASE,
];

export const HAS_L1_FEE = [
Expand Down
1 change: 1 addition & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export * from './chains';
export * from './intent';
export * from './log';
export * from './metric';
export * from './pool';
export * from './protocols';
export * from './routes';
2 changes: 2 additions & 0 deletions src/util/methodParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ export function buildTrade<TTradeType extends TradeType>(
quote.denominator
);

// we cannot retain fake pools for mixed routes,
// when we generate the ur swap calldata
const routeRaw = new MixedRouteSDK(
route.pools,
amountCurrency.currency,
Expand Down
Loading

0 comments on commit c0caf26

Please sign in to comment.