@uniswap/smart-order-router
Version:
Uniswap Smart Order Router
100 lines • 12.2 kB
JavaScript
import { Pair } from '@uniswap/v2-sdk';
import { Pool as V3Pool } from '@uniswap/v3-sdk';
import { Pool as V4Pool } from '@uniswap/v4-sdk';
import { getAddressLowerCase, nativeOnChain, V4_ETH_WETH_FAKE_POOL, } from '../../../util';
import { log } from '../../../util/log';
import { poolToString, routeToString } from '../../../util/routes';
import { MixedRoute, V2Route, V3Route, V4Route, } from '../../router';
export function computeAllV4Routes(currencyIn, currencyOut, pools, maxHops) {
return computeAllRoutes(currencyIn, currencyOut, (route, currencyIn, currencyOut) => {
return new V4Route(route, currencyIn, currencyOut);
}, (pool, currency) => pool.involvesToken(currency), pools, maxHops);
}
export function computeAllV3Routes(tokenIn, tokenOut, pools, maxHops) {
return computeAllRoutes(tokenIn, tokenOut, (route, tokenIn, tokenOut) => {
return new V3Route(route, tokenIn, tokenOut);
}, (pool, token) => pool.involvesToken(token), pools, maxHops);
}
export function computeAllV2Routes(tokenIn, tokenOut, pools, maxHops) {
return computeAllRoutes(tokenIn, tokenOut, (route, tokenIn, tokenOut) => {
return new V2Route(route, tokenIn, tokenOut);
}, (pool, token) => pool.involvesToken(token), pools, maxHops);
}
export function computeAllMixedRoutes(currencyIn, currencyOut, parts, maxHops, shouldEnableMixedRouteEthWeth) {
// 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 && shouldEnableMixedRouteEthWeth
? parts.concat(V4_ETH_WETH_FAKE_POOL[currencyIn.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(currencyIn, currencyOut, (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, currency) => currency.isNative
? pool.involvesToken(currency)
: pool.involvesToken(currency), amendedPools, maxHops);
/// filter out pure v4 and v3 and v2 routes
return routesRaw.filter((route) => {
return (!route.pools.every((pool) => pool instanceof V4Pool) &&
!route.pools.every((pool) => pool instanceof V3Pool) &&
!route.pools.every((pool) => pool instanceof Pair));
});
}
export function computeAllRoutes(tokenIn, tokenOut, buildRoute, involvesToken, pools, maxHops) {
var _a;
const poolsUsed = Array(pools.length).fill(false);
const routes = [];
const computeRoutes = (tokenIn, tokenOut, currentRoute, poolsUsed, tokensVisited, _previousTokenOut) => {
const currentRouteContainsFakeV4Pool = currentRoute.filter((pool) => pool instanceof V4Pool &&
pool.tickSpacing ===
V4_ETH_WETH_FAKE_POOL[tokenIn.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;
}
if (currentRoute.length > 0 &&
involvesToken(currentRoute[currentRoute.length - 1], tokenOut)) {
routes.push(buildRoute([...currentRoute], tokenIn, tokenOut));
return;
}
for (let i = 0; i < pools.length; i++) {
if (poolsUsed[i]) {
continue;
}
const curPool = pools[i];
const previousTokenOut = _previousTokenOut ? _previousTokenOut : tokenIn;
if (!involvesToken(curPool, previousTokenOut)) {
continue;
}
const currentTokenOut = curPool.token0.equals(previousTokenOut)
? curPool.token1
: curPool.token0;
if (tokensVisited.has(getAddressLowerCase(currentTokenOut))) {
continue;
}
tokensVisited.add(getAddressLowerCase(currentTokenOut));
currentRoute.push(curPool);
poolsUsed[i] = true;
computeRoutes(tokenIn, tokenOut, currentRoute, poolsUsed, tokensVisited, currentTokenOut);
poolsUsed[i] = false;
currentRoute.pop();
tokensVisited.delete(getAddressLowerCase(currentTokenOut));
}
};
computeRoutes(tokenIn, tokenOut, [], poolsUsed, new Set([getAddressLowerCase(tokenIn)]));
log.info({
routes: routes.map(routeToString),
pools: pools.map(poolToString),
}, `Computed ${routes.length} possible routes for type ${(_a = routes[0]) === null || _a === void 0 ? void 0 : _a.protocol}.`);
return routes;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZS1hbGwtcm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3JvdXRlcnMvYWxwaGEtcm91dGVyL2Z1bmN0aW9ucy9jb21wdXRlLWFsbC1yb3V0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVqRCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGFBQWEsRUFDYixxQkFBcUIsR0FDdEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbkUsT0FBTyxFQUNMLFVBQVUsRUFFVixPQUFPLEVBQ1AsT0FBTyxFQUNQLE9BQU8sR0FDUixNQUFNLGNBQWMsQ0FBQztBQUV0QixNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLFVBQW9CLEVBQ3BCLFdBQXFCLEVBQ3JCLEtBQWUsRUFDZixPQUFlO0lBRWYsT0FBTyxnQkFBZ0IsQ0FDckIsVUFBVSxFQUNWLFdBQVcsRUFDWCxDQUFDLEtBQWUsRUFBRSxVQUFvQixFQUFFLFdBQXFCLEVBQUUsRUFBRTtRQUMvRCxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDckQsQ0FBQyxFQUNELENBQUMsSUFBWSxFQUFFLFFBQWtCLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEVBQ2xFLEtBQUssRUFDTCxPQUFPLENBQ1IsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVB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