Commit 0dd5e6b3 authored by Noah Zinsmeister's avatar Noah Zinsmeister

Merge remote-tracking branch 'refs/remotes/origin/main'

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