Skip to content

Commit

Permalink
feat: part 1 native currency routing support by removing .wrapped in …
Browse files Browse the repository at this point in the history
…implementation classes (Uniswap#723)
  • Loading branch information
jsy1218 authored Sep 30, 2024
1 parent 3243864 commit 2f1226c
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 26 deletions.
16 changes: 7 additions & 9 deletions src/providers/caching/route/model/cached-route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Protocol } from '@uniswap/router-sdk';
import { Token } from '@uniswap/sdk-core';
import { Currency } 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';
Expand All @@ -11,6 +11,7 @@ import {
V3Route,
V4Route,
} from '../../../../routers';
import { getAddress } from '../../../../util';

interface CachedRouteParams<Route extends SupportedRoutes> {
route: Route;
Expand Down Expand Up @@ -44,24 +45,21 @@ export class CachedRoute<Route extends SupportedRoutes> {
return this.route.protocol;
}

// TODO: ROUTE-217 - Support native currency routing in V4
public get tokenIn(): Token {
return this.route.input.wrapped;
public get currencyIn(): Currency {
return this.route.input;
}

// TODO: ROUTE-217 - Support native currency routing in V4
public get tokenOut(): Token {
return this.route.output.wrapped;
public get currencyOut(): Currency {
return this.route.output;
}

public get routePath(): string {
switch (this.protocol) {
case Protocol.V4:
// TODO: ROUTE-217 - Support native currency routing in V4
return (this.route as V4Route).pools
.map(
(pool) =>
`[V4]${pool.token0.wrapped.address}/${pool.token1.wrapped.address}`
`[V4]${getAddress(pool.token0)}/${getAddress(pool.token1)}`
)
.join('->');
case Protocol.V3:
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 @@ -29,6 +29,7 @@ import { MixedRouteQuoterV2__factory } from '../types/other/factories/MixedRoute
import { V4Quoter__factory } from '../types/other/factories/V4Quoter__factory';
import { IQuoterV2__factory } from '../types/v3/factories/IQuoterV2__factory';
import {
getAddress,
ID_TO_NETWORK_NAME,
metric,
MetricLoggerUnit,
Expand Down Expand Up @@ -643,7 +644,7 @@ export class OnChainQuoteProvider implements IOnChainQuoteProvider {
case Protocol.V4:
return [
{
exactCurrency: amount.currency.wrapped.address,
exactCurrency: getAddress(amount.currency),
path: encodedRoute as PathKey[],
exactAmount: amount.quotient.toString(),
},
Expand Down
11 changes: 3 additions & 8 deletions src/providers/v4/pool-provider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ADDRESS_ZERO } from '@uniswap/router-sdk';
import { ChainId, Currency } from '@uniswap/sdk-core';
import { Pool } from '@uniswap/v4-sdk';
import retry, { Options as RetryOptions } from 'async-retry';
import { log, STATE_VIEW_ADDRESSES } from '../../util';
import { getAddress, log, STATE_VIEW_ADDRESSES } from '../../util';
import { IMulticallProvider, Result } from '../multicall-provider';
import { ProviderConfig } from '../provider';

Expand Down Expand Up @@ -154,12 +153,8 @@ export class V4PoolProvider
const [currency0, currency1] = sortsBefore(currencyA, currencyB)
? [currencyA, currencyB]
: [currencyB, currencyA];
const currency0Addr = currency0.isNative
? ADDRESS_ZERO
: currency0.wrapped.address;
const currency1Addr = currency1.isNative
? ADDRESS_ZERO
: currency1.wrapped.address;
const currency0Addr = getAddress(currency0);
const currency1Addr = getAddress(currency1);

const cacheKey = `${this.chainId}/${currency0Addr}/${currency1Addr}/${fee}/${tickSpacing}/${hooks}`;

Expand Down
6 changes: 3 additions & 3 deletions src/providers/v4/static-subgraph-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ADDRESS_ZERO, FeeAmount } from '@uniswap/v3-sdk';
import { Pool } from '@uniswap/v4-sdk';
import _ from 'lodash';

import { log, unparseFeeAmount } from '../../util';
import { getAddress, log, unparseFeeAmount } from '../../util';
import { BASES_TO_CHECK_TRADES_AGAINST } from '../caching-subgraph-provider';

import JSBI from 'jsbi';
Expand Down Expand Up @@ -93,10 +93,10 @@ export class StaticV4SubgraphProvider implements IV4SubgraphProvider {
hooks: hooks,
liquidity: liquidity.toString(),
token0: {
id: token0.wrapped.address,
id: getAddress(token0),
},
token1: {
id: token1.wrapped.address,
id: getAddress(token1),
},
// As a very rough proxy we just use liquidity for TVL.
tvlETH: liquidityNumber,
Expand Down
2 changes: 0 additions & 2 deletions src/routers/alpha-router/functions/compute-all-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export function computeAllV4Routes(
pools: V4Pool[],
maxHops: number
): V4Route[] {
// TODO: ROUTE-217 - Support native currency routing in V4
return computeAllRoutes<V4Pool, V4Route, Currency>(
currencyIn,
currencyOut,
Expand Down Expand Up @@ -154,7 +153,6 @@ export function computeAllRoutes<
? curPool.token1
: curPool.token0;

// TODO: ROUTE-217 - Support native currency routing in V4
if (tokensVisited.has(getAddressLowerCase(currentTokenOut))) {
continue;
}
Expand Down
69 changes: 66 additions & 3 deletions test/unit/routers/alpha-router/alpha-router.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { BigNumber } from '@ethersproject/bignumber';
import { BaseProvider } from '@ethersproject/providers';
import { Protocol, SwapRouter } from '@uniswap/router-sdk';
import { ChainId, Fraction, Percent, TradeType } from '@uniswap/sdk-core';
import {
ChainId,
Ether,
Fraction,
Percent,
TradeType
} from '@uniswap/sdk-core';
import { Pair } from '@uniswap/v2-sdk';
import { encodeSqrtRatioX96, Pool as V3Pool, Position } from '@uniswap/v3-sdk';
import { Pool as V4Pool } from '@uniswap/v4-sdk';
Expand Down Expand Up @@ -78,14 +84,14 @@ import {
DAI_USDT,
DAI_USDT_LOW,
DAI_USDT_MEDIUM,
DAI_USDT_V4_LOW,
DAI_USDT_V4_LOW, ETH_USDT_V4_LOW,
MOCK_ZERO_DEC_TOKEN,
mockBlock,
mockBlockBN,
mockGasPriceWeiBN,
pairToV2SubgraphPool,
poolToV3SubgraphPool,
poolToV4SubgraphPool,
poolToV4SubgraphPool, UNI_ETH_V4_MEDIUM,
USDC_DAI,
USDC_DAI_LOW,
USDC_DAI_MEDIUM,
Expand Down Expand Up @@ -226,6 +232,8 @@ describe('alpha router', () => {
WETH9_USDT_V4_LOW,
DAI_USDT_V4_LOW,
USDC_USDT_V4_MEDIUM,
ETH_USDT_V4_LOW,
UNI_ETH_V4_MEDIUM,
];
mockV4PoolProvider.getPools.resolves(buildMockV4PoolAccessor(v4MockPools));
mockV4PoolProvider.getPoolId.callsFake((cA, cB, fee, tickSpacing, hooks) => ({
Expand Down Expand Up @@ -485,6 +493,7 @@ describe('alpha router', () => {
multicall2Provider: mockMulticallProvider as any,
v4SubgraphProvider: mockV4SubgraphProvider,
v4PoolProvider: mockV4PoolProvider,
v4GasModelFactory: mockV4GasModelFactory,
v3SubgraphProvider: mockV3SubgraphProvider,
v3PoolProvider: mockV3PoolProvider,
onChainQuoteProvider: mockOnChainQuoteProvider,
Expand Down Expand Up @@ -1103,6 +1112,60 @@ describe('alpha router', () => {
expect(swapTo).toBeDefined();
});

test('succeeds to route on mixed only', async () => {
const amount = CurrencyAmount.fromRawAmount(USDC, 10000);
const swap = await alphaRouter.route(
amount,
Ether.onChain(ChainId.MAINNET),
TradeType.EXACT_INPUT,
undefined,
{ ...ROUTING_CONFIG, protocols: [Protocol.MIXED] }
)
expect(swap).toBeDefined();

expect(mockFallbackTenderlySimulator.simulate.called).toBeFalsy();
expect(mockProvider.getBlockNumber.called).toBeTruthy();
expect(mockGasPriceProvider.getGasPrice.called).toBeTruthy();

sinon.assert.calledWith(
mockOnChainQuoteProvider.getQuotesManyExactIn,
sinon.match((value) => {
return value instanceof Array && value.length == 4;
}),
sinon.match.array,
sinon.match({ blockNumber: sinon.match.defined })
);
/// Should not be calling onChainQuoteProvider for mixedRoutes
sinon.assert.callCount(mockOnChainQuoteProvider.getQuotesManyExactIn, 1);

expect(
swap!.quote.currency.equals(WRAPPED_NATIVE_CURRENCY[ChainId.MAINNET])
).toBeTruthy();
expect(
swap!.quoteGasAdjusted.currency.equals(WRAPPED_NATIVE_CURRENCY[ChainId.MAINNET])
).toBeTruthy();

expect(swap!.quote.greaterThan(swap!.quoteGasAdjusted)).toBeTruthy();
expect(swap!.estimatedGasUsed.toString()).toEqual('10000');
expect(
swap!.estimatedGasUsedQuoteToken.currency.equals(
WRAPPED_NATIVE_CURRENCY[ChainId.MAINNET]
)
).toBeTruthy();
expect(
swap!.estimatedGasUsedUSD.currency.equals(USDC) ||
swap!.estimatedGasUsedUSD.currency.equals(USDT) ||
swap!.estimatedGasUsedUSD.currency.equals(DAI)
).toBeTruthy();
expect(swap!.gasPriceWei.toString()).toEqual(
mockGasPriceWeiBN.toString()
);
expect(swap!.route).toHaveLength(1);
expect(swap!.trade).toBeDefined();
expect(swap!.methodParameters).not.toBeDefined();
expect(swap!.blockNumber.toString()).toEqual(mockBlockBN.toString());
});

test('succeeds to route on v3 only', async () => {
const amount = CurrencyAmount.fromRawAmount(USDC, 10000);
const swap = await alphaRouter.route(
Expand Down

0 comments on commit 2f1226c

Please sign in to comment.