diff --git a/package.json b/package.json index 0e3b891b47..c3d7684700 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@uniswap/v2-sdk": "^1.0.8", "@uniswap/v3-core": "^1.0.0-rc.2", "@uniswap/v3-periphery": "^1.0.0-beta.20", - "@uniswap/v3-sdk": "^1.0.0-alpha.20", + "@uniswap/v3-sdk": "^1.0.0-alpha.21", "@web3-react/core": "^6.0.9", "@web3-react/fortmatic-connector": "^6.0.9", "@web3-react/injected-connector": "^6.0.7", diff --git a/src/constants/index.ts b/src/constants/index.ts index 8da415520d..c4838a2703 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -18,7 +18,7 @@ export const MULTICALL2_ADDRESSES: { [chainId in ChainId]: string } = { [ChainId.GĂ–RLI]: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', } -export const ROUTER_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D' +export const V2_ROUTER_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D' export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' diff --git a/src/hooks/useAllV3Routes.ts b/src/hooks/useAllV3Routes.ts index ec4497bf63..b32d7179e9 100644 --- a/src/hooks/useAllV3Routes.ts +++ b/src/hooks/useAllV3Routes.ts @@ -50,13 +50,14 @@ function computeAllRoutes( * @param currencyIn the input currency * @param currencyOut the output currency */ -export function useAllV3Routes(currencyIn?: Currency, currencyOut?: Currency): Route[] { +export function useAllV3Routes(currencyIn?: Currency, currencyOut?: Currency): { loading: boolean; routes: Route[] } { const { chainId } = useActiveWeb3React() - const { pools } = useV3SwapPools(currencyIn, currencyOut) + const { pools, loading: poolsLoading } = useV3SwapPools(currencyIn, currencyOut) return useMemo(() => { - if (!chainId || !pools || !currencyIn || !currencyOut) return [] + if (poolsLoading || !chainId || !pools || !currencyIn || !currencyOut) return { loading: true, routes: [] } - return computeAllRoutes(currencyIn, currencyOut, pools, chainId) - }, [chainId, currencyIn, currencyOut, pools]) + const routes = computeAllRoutes(currencyIn, currencyOut, pools, chainId) + return { loading: false, routes } + }, [chainId, currencyIn, currencyOut, pools, poolsLoading]) } diff --git a/src/hooks/useApproveCallback.ts b/src/hooks/useApproveCallback.ts index 88ae00172e..e27dbaa0bc 100644 --- a/src/hooks/useApproveCallback.ts +++ b/src/hooks/useApproveCallback.ts @@ -1,9 +1,10 @@ import { MaxUint256 } from '@ethersproject/constants' import { TransactionResponse } from '@ethersproject/providers' -import { TokenAmount, CurrencyAmount, ETHER } from '@uniswap/sdk-core' -import { Trade } from '@uniswap/v2-sdk' +import { TokenAmount, CurrencyAmount, ETHER, ChainId } from '@uniswap/sdk-core' +import { Trade as V2Trade } from '@uniswap/v2-sdk' +import { SWAP_ROUTER_ADDRESS, Trade as V3Trade } from '@uniswap/v3-sdk' import { useCallback, useMemo } from 'react' -import { ROUTER_ADDRESS } from '../constants' +import { V2_ROUTER_ADDRESS } from '../constants' import { Field } from '../state/swap/actions' import { useTransactionAdder, useHasPendingApproval } from '../state/transactions/hooks' import { computeSlippageAdjustedAmounts } from '../utils/prices' @@ -99,10 +100,12 @@ export function useApproveCallback( } // wraps useApproveCallback in the context of a swap -export function useApproveCallbackFromTrade(trade?: Trade, allowedSlippage = 0) { +export function useApproveCallbackFromTrade(trade?: V2Trade | V3Trade, allowedSlippage = 0) { + const { chainId } = useActiveWeb3React() + const swapRouterAddress = SWAP_ROUTER_ADDRESS[chainId as ChainId] const amountToApprove = useMemo( () => (trade ? computeSlippageAdjustedAmounts(trade, allowedSlippage)[Field.INPUT] : undefined), [trade, allowedSlippage] ) - return useApproveCallback(amountToApprove, ROUTER_ADDRESS) + return useApproveCallback(amountToApprove, trade instanceof V2Trade ? V2_ROUTER_ADDRESS : swapRouterAddress) } diff --git a/src/hooks/useBestV3Route.ts b/src/hooks/useBestV3Route.ts deleted file mode 100644 index 3436f20a02..0000000000 --- a/src/hooks/useBestV3Route.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Token, Currency, CurrencyAmount, TokenAmount } from '@uniswap/sdk-core' -import { encodeRouteToPath, Route } from '@uniswap/v3-sdk' -import { useMemo } from 'react' -import { useSingleContractMultipleData } from '../state/multicall/hooks' -import { useActiveWeb3React } from './index' -import { useAllV3Routes } from './useAllV3Routes' -import { useV3Quoter } from './useContract' -import { BigNumber } from 'ethers' - -/** - * Returns the best route for a given exact input swap, and the amount received for it - * @param amountIn the amount to swap in - * @param currencyOut the desired output currency - */ -export function useBestV3RouteExactIn( - amountIn?: CurrencyAmount, - currencyOut?: Currency -): { route: Route; amountOut: CurrencyAmount } | null { - const { chainId } = useActiveWeb3React() - const quoter = useV3Quoter() - const routes = useAllV3Routes(amountIn?.currency, currencyOut) - const paths = useMemo(() => { - if (!chainId) return [] - return routes.map((route) => encodeRouteToPath(route, false)) - }, [chainId, routes]) - - const quoteExactInInputs = useMemo(() => { - return paths.map((path) => [path, amountIn ? `0x${amountIn.raw.toString(16)}` : undefined]) - }, [amountIn, paths]) - - const quotesResults = useSingleContractMultipleData(quoter, 'quoteExactInput', quoteExactInInputs) - - return useMemo(() => { - const { bestRoute, amountOut } = quotesResults.reduce( - (best: { bestRoute: Route | null; amountOut: BigNumber | null }, { valid, loading, result }, i) => { - if (loading || !valid || !result) return best - - if (best.amountOut === null) { - return { - bestRoute: routes[i], - amountOut: result.amountOut, - } - } else if (best.amountOut.lt(result.amountOut)) { - return { - bestRoute: routes[i], - amountOut: result.amountOut, - } - } - - return best - }, - { - bestRoute: null, - amountOut: null, - } - ) - if (!bestRoute || !amountOut) return null - return { - route: bestRoute, - amountOut: - currencyOut instanceof Token - ? new TokenAmount(currencyOut, amountOut.toString()) - : CurrencyAmount.ether(amountOut.toString()), - } - }, [currencyOut, quotesResults, routes]) -} - -/** - * Returns the best route for a given exact output swap, and the amount required for it - * @param currencyIn the current to swap in - * @param amountOut the desired amount out - */ -export function useBestV3RouteExactOut( - currencyIn?: Currency, - amountOut?: CurrencyAmount -): { route: Route; amountIn: CurrencyAmount } | null { - const { chainId } = useActiveWeb3React() - const quoter = useV3Quoter() - const routes = useAllV3Routes(currencyIn, amountOut?.currency) - - const paths = useMemo(() => { - if (!chainId) return [] - return routes.map((route) => encodeRouteToPath(route, true)) - }, [chainId, routes]) - - const quoteExactOutInputs = useMemo(() => { - const amountOutEncoded = amountOut ? `0x${amountOut.raw.toString(16)}` : undefined - return paths.map((path) => [path, amountOutEncoded]) - }, [amountOut, paths]) - - const quotesResults = useSingleContractMultipleData(quoter, 'quoteExactInput', quoteExactOutInputs) - - return useMemo(() => { - const { bestRoute, amountIn } = quotesResults.reduce( - (best: { bestRoute: Route | null; amountIn: BigNumber | null }, { valid, loading, result }, i) => { - if (loading || !valid || !result) return best - - if (best.amountIn === null) { - return { - bestRoute: routes[i], - amountIn: result.amountIn, - } - } else if (best.amountIn.gt(result.amountIn)) { - return { - bestRoute: routes[i], - amountIn: result.amountIn, - } - } - - return best - }, - { - bestRoute: null, - amountIn: null, - } - ) - if (!bestRoute || !amountIn) return null - return { - route: bestRoute, - amountIn: - currencyIn instanceof Token - ? new TokenAmount(currencyIn, amountIn.toString()) - : CurrencyAmount.ether(amountIn.toString()), - } - }, [currencyIn, quotesResults, routes]) -} diff --git a/src/hooks/useBestV3Trade.ts b/src/hooks/useBestV3Trade.ts new file mode 100644 index 0000000000..1aa64e822d --- /dev/null +++ b/src/hooks/useBestV3Trade.ts @@ -0,0 +1,179 @@ +import { Token, Currency, CurrencyAmount, TokenAmount, TradeType } from '@uniswap/sdk-core' +import { encodeRouteToPath, Route, Trade } from '@uniswap/v3-sdk' +import { BigNumber } from 'ethers' +import { useMemo } from 'react' +import { useSingleContractMultipleData } from '../state/multicall/hooks' +import { useAllV3Routes } from './useAllV3Routes' +import { useV3Quoter } from './useContract' + +enum V3TradeState { + LOADING, + INVALID, + NO_ROUTE_FOUND, + VALID, + SYNCING, +} + +/** + * Returns the best v3 trade for a desired exact input swap + * @param amountIn the amount to swap in + * @param currencyOut the desired output currency + */ +export function useBestV3TradeExactIn( + amountIn?: CurrencyAmount, + currencyOut?: Currency +): { state: V3TradeState; trade: Trade | null } { + const quoter = useV3Quoter() + const { routes, loading: routesLoading } = useAllV3Routes(amountIn?.currency, currencyOut) + + const quoteExactInInputs = useMemo(() => { + return routes.map((route) => [ + encodeRouteToPath(route, false), + amountIn ? `0x${amountIn.raw.toString(16)}` : undefined, + ]) + }, [amountIn, routes]) + + const quotesResults = useSingleContractMultipleData(quoter, 'quoteExactInput', quoteExactInInputs) + + return useMemo(() => { + if (!amountIn || !currencyOut || quotesResults.some(({ valid }) => !valid)) { + return { + state: V3TradeState.INVALID, + trade: null, + } + } + + if (routesLoading || quotesResults.some(({ loading }) => loading)) { + return { + state: V3TradeState.LOADING, + trade: null, + } + } + + const { bestRoute, amountOut } = quotesResults.reduce( + (currentBest: { bestRoute: Route | null; amountOut: BigNumber | null }, { result }, i) => { + if (!result) return currentBest + + if (currentBest.amountOut === null) { + return { + bestRoute: routes[i], + amountOut: result.amountOut, + } + } else if (currentBest.amountOut.lt(result.amountOut)) { + return { + bestRoute: routes[i], + amountOut: result.amountOut, + } + } + + return currentBest + }, + { + bestRoute: null, + amountOut: null, + } + ) + + if (!bestRoute || !amountOut) { + return { + state: V3TradeState.NO_ROUTE_FOUND, + trade: null, + } + } + + return { + state: V3TradeState.VALID, + trade: Trade.createUncheckedTrade({ + route: bestRoute, + tradeType: TradeType.EXACT_INPUT, + inputAmount: amountIn, + outputAmount: + currencyOut instanceof Token + ? new TokenAmount(currencyOut, amountOut.toString()) + : CurrencyAmount.ether(amountOut.toString()), + }), + } + }, [amountIn, currencyOut, quotesResults, routes, routesLoading]) +} + +/** + * Returns the best v3 trade for a desired exact output swap + * @param currencyIn the desired input currency + * @param amountOut the amount to swap out + */ +export function useBestV3TradeExactOut( + currencyIn?: Currency, + amountOut?: CurrencyAmount +): { state: V3TradeState; trade: Trade | null } { + const quoter = useV3Quoter() + const { routes, loading: routesLoading } = useAllV3Routes(currencyIn, amountOut?.currency) + + const quoteExactOutInputs = useMemo(() => { + return routes.map((route) => [ + encodeRouteToPath(route, true), + amountOut ? `0x${amountOut.raw.toString(16)}` : undefined, + ]) + }, [amountOut, routes]) + + const quotesResults = useSingleContractMultipleData(quoter, 'quoteExactInput', quoteExactOutInputs) + + return useMemo(() => { + if (!amountOut || !currencyIn || quotesResults.some(({ valid }) => !valid)) { + return { + state: V3TradeState.INVALID, + trade: null, + } + } + + if (routesLoading || quotesResults.some(({ loading }) => loading)) { + return { + state: V3TradeState.LOADING, + trade: null, + } + } + + const { bestRoute, amountIn } = quotesResults.reduce( + (currentBest: { bestRoute: Route | null; amountIn: BigNumber | null }, { result }, i) => { + if (!result) return currentBest + + if (currentBest.amountIn === null) { + return { + bestRoute: routes[i], + amountIn: result.amountIn, + } + } else if (currentBest.amountIn.gt(result.amountIn)) { + return { + bestRoute: routes[i], + amountIn: result.amountIn, + } + } + + return currentBest + }, + { + bestRoute: null, + amountIn: null, + } + ) + + if (!bestRoute || !amountIn) { + return { + state: V3TradeState.NO_ROUTE_FOUND, + trade: null, + } + } + + return { + state: V3TradeState.VALID, + trade: Trade.createUncheckedTrade({ + route: bestRoute, + tradeType: TradeType.EXACT_INPUT, + inputAmount: + currencyIn instanceof Token + ? new TokenAmount(currencyIn, amountIn.toString()) + : CurrencyAmount.ether(amountIn.toString()), + outputAmount: amountOut, + }), + } + }, [amountOut, currencyIn, quotesResults, routes, routesLoading]) +} diff --git a/src/hooks/useToggledVersion.ts b/src/hooks/useToggledVersion.ts index e5442638f3..9f110bb976 100644 --- a/src/hooks/useToggledVersion.ts +++ b/src/hooks/useToggledVersion.ts @@ -5,12 +5,19 @@ export enum Version { v3 = 'v3', } -export const DEFAULT_VERSION: Version = Version.v2 +export const DEFAULT_VERSION: Version = Version.v3 export default function useToggledVersion(): Version { const { use } = useParsedQueryString() if (typeof use !== 'string') { return DEFAULT_VERSION } - return DEFAULT_VERSION + switch (use.toLowerCase()) { + case 'v2': + return Version.v2 + case 'v3': + return Version.v3 + default: + return Version.v3 + } } diff --git a/src/pages/AddLiquidityV2/index.tsx b/src/pages/AddLiquidityV2/index.tsx index de3ba77e9b..eded695169 100644 --- a/src/pages/AddLiquidityV2/index.tsx +++ b/src/pages/AddLiquidityV2/index.tsx @@ -17,7 +17,7 @@ import { AddRemoveTabs } from '../../components/NavigationTabs' import { MinimalPositionCard } from '../../components/PositionCard' import Row, { RowBetween, RowFlat } from '../../components/Row' -import { ROUTER_ADDRESS } from '../../constants' +import { V2_ROUTER_ADDRESS } from '../../constants' import { PairState } from '../../hooks/useV2Pairs' import { useActiveWeb3React } from '../../hooks' import { useCurrency } from '../../hooks/Tokens' @@ -121,8 +121,8 @@ export default function AddLiquidity({ ) // check whether the user has approved the router on the tokens - const [approvalA, approveACallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_A], ROUTER_ADDRESS) - const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], ROUTER_ADDRESS) + const [approvalA, approveACallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_A], V2_ROUTER_ADDRESS) + const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], V2_ROUTER_ADDRESS) const addTransaction = useTransactionAdder() diff --git a/src/pages/RemoveLiquidity/index.tsx b/src/pages/RemoveLiquidity/index.tsx index e68a8fd971..1bc57f74fb 100644 --- a/src/pages/RemoveLiquidity/index.tsx +++ b/src/pages/RemoveLiquidity/index.tsx @@ -20,7 +20,7 @@ import Row, { RowBetween, RowFixed } from '../../components/Row' import Slider from '../../components/Slider' import CurrencyLogo from '../../components/CurrencyLogo' -import { ROUTER_ADDRESS } from '../../constants' +import { V2_ROUTER_ADDRESS } from '../../constants' import { useActiveWeb3React } from '../../hooks' import { useCurrency } from '../../hooks/Tokens' import { usePairContract } from '../../hooks/useContract' @@ -100,7 +100,7 @@ export default function RemoveLiquidity({ // allowance handling const [signatureData, setSignatureData] = useState<{ v: number; r: string; s: string; deadline: number } | null>(null) - const [approval, approveCallback] = useApproveCallback(parsedAmounts[Field.LIQUIDITY], ROUTER_ADDRESS) + const [approval, approveCallback] = useApproveCallback(parsedAmounts[Field.LIQUIDITY], V2_ROUTER_ADDRESS) const isArgentWallet = useIsArgentWallet() @@ -137,7 +137,7 @@ export default function RemoveLiquidity({ ] const message = { owner: account, - spender: ROUTER_ADDRESS, + spender: V2_ROUTER_ADDRESS, value: liquidityAmount.raw.toString(), nonce: nonce.toHexString(), deadline: deadline.toNumber(), diff --git a/src/pages/Swap/index.tsx b/src/pages/Swap/index.tsx index e9e7d1c387..a94f148f98 100644 --- a/src/pages/Swap/index.tsx +++ b/src/pages/Swap/index.tsx @@ -29,7 +29,6 @@ import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useAppro import useENSAddress from '../../hooks/useENSAddress' import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported' import { useV2SwapCallback } from '../../hooks/useV2SwapCallback' -import useToggledVersion, { Version } from '../../hooks/useToggledVersion' import useWrapCallback, { WrapType } from '../../hooks/useWrapCallback' import { useToggleSettingsMenu, useWalletModalToggle } from '../../state/application/hooks' import { Field } from '../../state/swap/actions' @@ -89,7 +88,14 @@ export default function Swap({ history }: RouteComponentProps) { // swap state const { independentField, typedValue, recipient } = useSwapState() - const { v2Trade, currencyBalances, parsedAmount, currencies, inputError: swapInputError } = useDerivedSwapInfo() + const { + v2Trade, + currencyBalances, + parsedAmount, + currencies, + inputError: swapInputError, + // v3Trade, + } = useDerivedSwapInfo() const { wrapType, execute: onWrap, inputError: wrapInputError } = useWrapCallback( currencies[Field.INPUT], @@ -98,12 +104,13 @@ export default function Swap({ history }: RouteComponentProps) { ) const showWrap: boolean = wrapType !== WrapType.NOT_APPLICABLE const { address: recipientAddress } = useENSAddress(recipient) - const toggledVersion = useToggledVersion() - const tradesByVersion = { - [Version.v2]: v2Trade, - [Version.v3]: undefined, - } - const trade = showWrap ? undefined : tradesByVersion[toggledVersion] + // const toggledVersion = useToggledVersion() + const trade = showWrap + ? undefined + : v2Trade /*{ + [Version.v2]: v2Trade, + [Version.v3]: v3Trade, + }[toggledVersion]*/ const parsedAmounts = showWrap ? { diff --git a/src/state/swap/hooks.ts b/src/state/swap/hooks.ts index 6acc212b62..7602745241 100644 --- a/src/state/swap/hooks.ts +++ b/src/state/swap/hooks.ts @@ -1,9 +1,9 @@ -import { Route } from '@uniswap/v3-sdk' -import { useBestV3RouteExactIn, useBestV3RouteExactOut } from '../../hooks/useBestV3Route' +import { Trade as V3Trade } from '@uniswap/v3-sdk' +import { useBestV3TradeExactIn, useBestV3TradeExactOut } from '../../hooks/useBestV3Trade' import useENS from '../../hooks/useENS' import { parseUnits } from '@ethersproject/units' import { Currency, CurrencyAmount, ETHER, Token, TokenAmount } from '@uniswap/sdk-core' -import { JSBI, Trade } from '@uniswap/v2-sdk' +import { JSBI, Trade as V2Trade } from '@uniswap/v2-sdk' import { ParsedQs } from 'qs' import { useCallback, useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' @@ -99,10 +99,13 @@ const BAD_RECIPIENT_ADDRESSES: { [address: string]: true } = { * @param trade to check for the given address * @param checksummedAddress address to check in the pairs and tokens */ -function involvesAddress(trade: Trade, checksummedAddress: string): boolean { +function involvesAddress(trade: V2Trade | V3Trade, checksummedAddress: string): boolean { + const path = trade instanceof V2Trade ? trade.route.path : trade.route.tokenPath return ( - trade.route.path.some((token) => token.address === checksummedAddress) || - trade.route.pairs.some((pair) => pair.liquidityToken.address === checksummedAddress) + path.some((token) => token.address === checksummedAddress) || + (trade instanceof V2Trade + ? trade.route.pairs.some((pair) => pair.liquidityToken.address === checksummedAddress) + : false) ) } @@ -111,18 +114,9 @@ export function useDerivedSwapInfo(): { currencies: { [field in Field]?: Currency } currencyBalances: { [field in Field]?: CurrencyAmount } parsedAmount: CurrencyAmount | undefined - v2Trade: Trade | undefined + v2Trade: V2Trade | undefined inputError?: string - v3Route: - | { - route: Route - amountIn: CurrencyAmount - } - | { - route: Route - amountOut: CurrencyAmount - } - | undefined + v3Trade: V3Trade | undefined } { const { account } = useActiveWeb3React() @@ -147,14 +141,14 @@ export function useDerivedSwapInfo(): { const isExactIn: boolean = independentField === Field.INPUT const parsedAmount = tryParseAmount(typedValue, (isExactIn ? inputCurrency : outputCurrency) ?? undefined) - const bestTradeExactIn = useV2TradeExactIn(isExactIn ? parsedAmount : undefined, outputCurrency ?? undefined) - const bestTradeExactOut = useV2TradeExactOut(inputCurrency ?? undefined, !isExactIn ? parsedAmount : undefined) + const bestV2TradeExactIn = useV2TradeExactIn(isExactIn ? parsedAmount : undefined, outputCurrency ?? undefined) + const bestV2TradeExactOut = useV2TradeExactOut(inputCurrency ?? undefined, !isExactIn ? parsedAmount : undefined) - const bestRouteExactInV3 = useBestV3RouteExactIn(isExactIn ? parsedAmount : undefined, outputCurrency ?? undefined) - const bestRouteExactOutV3 = useBestV3RouteExactOut(inputCurrency ?? undefined, !isExactIn ? parsedAmount : undefined) + const bestV3TradeExactIn = useBestV3TradeExactIn(isExactIn ? parsedAmount : undefined, outputCurrency ?? undefined) + const bestV3TradeExactOut = useBestV3TradeExactOut(inputCurrency ?? undefined, !isExactIn ? parsedAmount : undefined) - const v2Trade = isExactIn ? bestTradeExactIn : bestTradeExactOut - const v3Route = (isExactIn ? bestRouteExactInV3 : bestRouteExactOutV3) ?? undefined + const v2Trade = isExactIn ? bestV2TradeExactIn : bestV2TradeExactOut + const v3Trade = (isExactIn ? bestV3TradeExactIn : bestV3TradeExactOut) ?? undefined const currencyBalances = { [Field.INPUT]: relevantTokenBalances[0], @@ -185,8 +179,8 @@ export function useDerivedSwapInfo(): { } else { if ( BAD_RECIPIENT_ADDRESSES[formattedTo] || - (bestTradeExactIn && involvesAddress(bestTradeExactIn, formattedTo)) || - (bestTradeExactOut && involvesAddress(bestTradeExactOut, formattedTo)) + (bestV2TradeExactIn && involvesAddress(bestV2TradeExactIn, formattedTo)) || + (bestV2TradeExactOut && involvesAddress(bestV2TradeExactOut, formattedTo)) ) { inputError = inputError ?? 'Invalid recipient' } @@ -212,7 +206,7 @@ export function useDerivedSwapInfo(): { parsedAmount, v2Trade: v2Trade ?? undefined, inputError, - v3Route, + v3Trade: v3Trade.trade ?? undefined, } } diff --git a/src/utils/getTokenList.ts b/src/utils/getTokenList.ts index 00865dafc5..2293096449 100644 --- a/src/utils/getTokenList.ts +++ b/src/utils/getTokenList.ts @@ -42,7 +42,7 @@ export default async function getTokenList( const isLast = i === urls.length - 1 let response try { - response = await fetch(url) + response = await fetch(url, { credentials: 'omit' }) } catch (error) { console.debug('Failed to fetch list', listUrl, error) if (isLast) throw new Error(`Failed to download list ${listUrl}`) diff --git a/src/utils/index.ts b/src/utils/index.ts index b9025285f6..7d871e44bf 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -6,7 +6,7 @@ import { JsonRpcSigner, Web3Provider } from '@ethersproject/providers' import { BigNumber } from '@ethersproject/bignumber' import { abi as IUniswapV2Router02ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router02.json' -import { ROUTER_ADDRESS } from '../constants' +import { V2_ROUTER_ADDRESS } from '../constants' import { ChainId, Percent, Token, CurrencyAmount, Currency, ETHER } from '@uniswap/sdk-core' import { JSBI } from '@uniswap/v2-sdk' import { TokenAddressMap } from '../state/lists/hooks' @@ -102,7 +102,7 @@ export function getContract(address: string, ABI: any, library: Web3Provider, ac // account is optional export function getRouterContract(_: number, library: Web3Provider, account?: string): Contract { - return getContract(ROUTER_ADDRESS, IUniswapV2Router02ABI, library, account) + return getContract(V2_ROUTER_ADDRESS, IUniswapV2Router02ABI, library, account) } export function escapeRegExp(string: string): string { diff --git a/src/utils/prices.ts b/src/utils/prices.ts index 5984206485..3f20b89b9f 100644 --- a/src/utils/prices.ts +++ b/src/utils/prices.ts @@ -1,6 +1,8 @@ +import JSBI from 'jsbi' import { BLOCKED_PRICE_IMPACT_NON_EXPERT } from '../constants' import { CurrencyAmount, Fraction, Percent, TokenAmount } from '@uniswap/sdk-core' -import { JSBI, Trade } from '@uniswap/v2-sdk' +import { Trade as V2Trade } from '@uniswap/v2-sdk' +import { Trade as V3Trade } from '@uniswap/v3-sdk' import { ALLOWED_PRICE_IMPACT_HIGH, ALLOWED_PRICE_IMPACT_LOW, ALLOWED_PRICE_IMPACT_MEDIUM } from '../constants' import { Field } from '../state/swap/actions' @@ -12,7 +14,7 @@ const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE) // computes price breakdown for the trade export function computeTradePriceBreakdown( - trade?: Trade | null + trade?: V2Trade | null ): { priceImpactWithoutFee: Percent | undefined; realizedLPFee: CurrencyAmount | undefined | null } { // for each hop in our trade, take away the x*y=k price impact from 0.3% fees // e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03)) @@ -46,7 +48,7 @@ export function computeTradePriceBreakdown( // computes the minimum amount out and maximum amount in for a trade given a user specified allowed slippage in bips export function computeSlippageAdjustedAmounts( - trade: Trade | undefined, + trade: V2Trade | V3Trade | undefined, allowedSlippage: number ): { [field in Field]?: CurrencyAmount } { const pct = basisPointsToPercent(allowedSlippage) @@ -64,7 +66,7 @@ export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3 return 0 } -export function formatExecutionPrice(trade?: Trade, inverted?: boolean): string { +export function formatExecutionPrice(trade: V2Trade | V3Trade | undefined, inverted: boolean | undefined): string { if (!trade) { return '' } diff --git a/yarn.lock b/yarn.lock index 09188d113d..6235cc723e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4158,10 +4158,10 @@ "@uniswap/v2-core" "1.0.1" "@uniswap/v3-core" "1.0.0-rc.2" -"@uniswap/v3-sdk@^1.0.0-alpha.20": - version "1.0.0-alpha.20" - resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-1.0.0-alpha.20.tgz#4f58fac3cd89060f6523a56e8de950493527b48f" - integrity sha512-a3kzKA32XC/HhXYV2moMMPJkoQJw8mnBKza4aFTvFCSjn281+GzNjdydao8aLJIEjU+wkQWy5GYZ/kAkU45xuQ== +"@uniswap/v3-sdk@^1.0.0-alpha.21": + version "1.0.0-alpha.21" + resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-1.0.0-alpha.21.tgz#f035f96f922680f92b3af71bbe6bec3d9966c0a2" + integrity sha512-hhsJZwn0pooyjajKPZ0O5AR4asXZUVDwqqwXlWWvxFZtvetwhZ/AXxIllYcLUXoc3cJOQvfGzjkhXq0be35RDA== dependencies: "@ethersproject/abi" "^5.0.12" "@ethersproject/solidity" "^5.0.9"