diff --git a/src/hooks/useAutoSlippageTolerance.ts b/src/hooks/useAutoSlippageTolerance.ts index 75905cf993f..b34f78e86df 100644 --- a/src/hooks/useAutoSlippageTolerance.ts +++ b/src/hooks/useAutoSlippageTolerance.ts @@ -1,69 +1,13 @@ -import { MixedRoute, partitionMixedRouteByProtocol, Protocol, Trade } from '@uniswap/router-sdk' -import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core' -import { Pair } from '@uniswap/v2-sdk' -import { Pool } from '@uniswap/v3-sdk' +import { Percent } from '@uniswap/sdk-core' import { useWeb3React } from '@web3-react/core' -import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains' import { L2_CHAIN_IDS } from 'constants/chains' -import JSBI from 'jsbi' -import useNativeCurrency from 'lib/hooks/useNativeCurrency' import { useMemo } from 'react' import { ClassicTrade } from 'state/routing/types' -import useGasPrice from './useGasPrice' -import useStablecoinPrice, { useStablecoinAmountFromFiatValue, useStablecoinValue } from './useStablecoinPrice' +import { useStablecoinAmountFromFiatValue, useStablecoinValue } from './useStablecoinPrice' const DEFAULT_AUTO_SLIPPAGE = new Percent(5, 1000) // 0.5% -// Base costs regardless of how many hops in the route -const V3_SWAP_BASE_GAS_ESTIMATE = 100_000 -const V2_SWAP_BASE_GAS_ESTIMATE = 135_000 - -// Extra cost per hop in the route -const V3_SWAP_HOP_GAS_ESTIMATE = 70_000 -const V2_SWAP_HOP_GAS_ESTIMATE = 50_000 - -/** - * Return a guess of the gas cost used in computing slippage tolerance for a given trade - * @param trade the trade for which to _guess_ the amount of gas it would cost to execute - * - * V3 logic is inspired by: - * https://github.com/Uniswap/smart-order-router/blob/main/src/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.ts - * V2 logic is inspired by: - * https://github.com/Uniswap/smart-order-router/blob/main/src/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.ts - */ -function guesstimateGas(trade: Trade | undefined): number | undefined { - if (trade) { - let gas = 0 - for (const { route } of trade.swaps) { - if (route.protocol === Protocol.V2) { - gas += V2_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V2_SWAP_HOP_GAS_ESTIMATE - } else if (route.protocol === Protocol.V3) { - // V3 gas costs scale on initialized ticks being crossed, but we don't have that data here. - // We bake in some tick crossings into the base 100k cost. - gas += V3_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V3_SWAP_HOP_GAS_ESTIMATE - } else if (route.protocol === Protocol.MIXED) { - const sections = partitionMixedRouteByProtocol(route as MixedRoute) - gas += sections.reduce((gas, section) => { - if (section.every((pool) => pool instanceof Pool)) { - return gas + V3_SWAP_BASE_GAS_ESTIMATE + section.length * V3_SWAP_HOP_GAS_ESTIMATE - } else if (section.every((pool) => pool instanceof Pair)) { - return gas + V2_SWAP_BASE_GAS_ESTIMATE + (section.length - 1) * V2_SWAP_HOP_GAS_ESTIMATE - } else { - console.warn('Invalid section') - return gas - } - }, 0) - } else { - // fallback general gas estimation - gas += V3_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V3_SWAP_HOP_GAS_ESTIMATE - } - } - return gas - } - return undefined -} - const MIN_AUTO_SLIPPAGE_TOLERANCE = DEFAULT_AUTO_SLIPPAGE // assuming normal gas speeds, most swaps complete within 3 blocks and // there's rarely price movement >5% in that time period @@ -77,35 +21,16 @@ export default function useClassicAutoSlippageTolerance(trade?: ClassicTrade): P const { chainId } = useWeb3React() const onL2 = chainId && L2_CHAIN_IDS.includes(chainId) const outputDollarValue = useStablecoinValue(trade?.outputAmount) - const nativeGasPrice = useGasPrice() - const gasEstimate = guesstimateGas(trade) const gasEstimateUSD = useStablecoinAmountFromFiatValue(trade?.gasUseEstimateUSD) ?? null - const nativeCurrency = useNativeCurrency(chainId) - const nativeCurrencyPrice = useStablecoinPrice((trade && nativeCurrency) ?? undefined) return useMemo(() => { if (!trade || onL2) return DEFAULT_AUTO_SLIPPAGE - const nativeGasCost = - nativeGasPrice && typeof gasEstimate === 'number' - ? JSBI.multiply(nativeGasPrice, JSBI.BigInt(gasEstimate)) - : undefined - const dollarGasCost = - nativeCurrency && nativeGasCost && nativeCurrencyPrice - ? nativeCurrencyPrice.quote(CurrencyAmount.fromRawAmount(nativeCurrency, nativeGasCost)) - : undefined - - // if valid estimate from api and using api trade, use gas estimate from api - // NOTE - dont use gas estimate for L2s yet - need to verify accuracy - // if not, use local heuristic - const dollarCostToUse = - chainId && SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId) && gasEstimateUSD ? gasEstimateUSD : dollarGasCost - - if (outputDollarValue && dollarCostToUse) { + if (outputDollarValue && gasEstimateUSD) { // optimize for highest possible slippage without getting MEV'd // so set slippage % such that the difference between expected amount out and minimum amount out < gas fee to sandwich the trade - const fraction = dollarCostToUse.asFraction.divide(outputDollarValue.asFraction) + const fraction = gasEstimateUSD.asFraction.divide(outputDollarValue.asFraction) const result = new Percent(fraction.numerator, fraction.denominator) if (result.greaterThan(MAX_AUTO_SLIPPAGE_TOLERANCE)) { return MAX_AUTO_SLIPPAGE_TOLERANCE @@ -119,15 +44,5 @@ export default function useClassicAutoSlippageTolerance(trade?: ClassicTrade): P } return DEFAULT_AUTO_SLIPPAGE - }, [ - trade, - onL2, - nativeGasPrice, - gasEstimate, - nativeCurrency, - nativeCurrencyPrice, - chainId, - gasEstimateUSD, - outputDollarValue, - ]) + }, [trade, onL2, gasEstimateUSD, outputDollarValue]) } diff --git a/src/hooks/useCurrentBlockTimestamp.ts b/src/hooks/useCurrentBlockTimestamp.ts index 26696befccc..b45c95719fb 100644 --- a/src/hooks/useCurrentBlockTimestamp.ts +++ b/src/hooks/useCurrentBlockTimestamp.ts @@ -1,15 +1,5 @@ import { BigNumber } from '@ethersproject/bignumber' -import { useSingleCallResult } from 'lib/hooks/multicall' -import { useMemo } from 'react' - -import { useInterfaceMulticall } from './useContract' - // gets the current timestamp from the blockchain -export default function useCurrentBlockTimestamp(): BigNumber | undefined { - const multicall = useInterfaceMulticall() - const resultStr: string | undefined = useSingleCallResult( - multicall, - 'getCurrentBlockTimestamp' - )?.result?.[0]?.toString() - return useMemo(() => (typeof resultStr === 'string' ? BigNumber.from(resultStr) : undefined), [resultStr]) +export default function useCurrentBlockTimestamp(): BigNumber { + return BigNumber.from(BigInt(Math.floor(Date.now() / 1000))) } diff --git a/src/hooks/useGasPrice.ts b/src/hooks/useGasPrice.ts deleted file mode 100644 index d25287a37fa..00000000000 --- a/src/hooks/useGasPrice.ts +++ /dev/null @@ -1,27 +0,0 @@ -import JSBI from 'jsbi' -import { useSingleCallResult } from 'lib/hooks/multicall' -import { useMemo } from 'react' - -import { useContract } from './useContract' -import useENSAddress from './useENSAddress' - -const CHAIN_DATA_ABI = [ - { - inputs: [], - name: 'latestAnswer', - outputs: [{ internalType: 'int256', name: '', type: 'int256' }], - stateMutability: 'view', - type: 'function', - }, -] - -/** - * Returns the price of 1 gas in WEI for the currently selected network using the chainlink fast gas price oracle - */ -export default function useGasPrice(): JSBI | undefined { - const { address } = useENSAddress('fast-gas-gwei.data.eth') - const contract = useContract(address ?? undefined, CHAIN_DATA_ABI, false) - - const resultStr = useSingleCallResult(contract, 'latestAnswer').result?.[0]?.toString() - return useMemo(() => (typeof resultStr === 'string' ? JSBI.BigInt(resultStr) : undefined), [resultStr]) -} diff --git a/src/hooks/useUSDPrice.ts b/src/hooks/useUSDPrice.ts index e2284840092..867d7ddad7d 100644 --- a/src/hooks/useUSDPrice.ts +++ b/src/hooks/useUSDPrice.ts @@ -3,17 +3,12 @@ import { useMemo } from 'react' import useStablecoinPrice from './useStablecoinPrice' -export function useUSDPrice( - currencyAmount?: CurrencyAmount, - prefetchCurrency?: Currency -): { +export function useUSDPrice(currencyAmount?: CurrencyAmount): { data?: number isLoading: boolean } { - const currency = currencyAmount?.currency ?? prefetchCurrency - // Use USDC-based pricing for chains. - const stablecoinPrice = useStablecoinPrice(currency) + const stablecoinPrice = useStablecoinPrice(currencyAmount?.currency) return useMemo(() => { if (currencyAmount && stablecoinPrice) { diff --git a/src/pages/Swap/index.tsx b/src/pages/Swap/index.tsx index 348ba463899..687f86edcd7 100644 --- a/src/pages/Swap/index.tsx +++ b/src/pages/Swap/index.tsx @@ -313,18 +313,12 @@ function Swap({ const showFiatValueInput = Boolean(parsedAmounts[Field.INPUT]) const showFiatValueOutput = Boolean(parsedAmounts[Field.OUTPUT]) - const getSingleUnitAmount = (currency?: Currency) => { - if (!currency) return - return CurrencyAmount.fromRawAmount(currency, JSBI.BigInt(10 ** currency.decimals)) - } const fiatValueInput = useUSDPrice( - parsedAmounts[Field.INPUT] ?? getSingleUnitAmount(currencies[Field.INPUT]), - currencies[Field.INPUT] + parsedAmounts[Field.INPUT] && showFiatValueInput ? parsedAmounts[Field.INPUT] : undefined ) const fiatValueOutput = useUSDPrice( - parsedAmounts[Field.OUTPUT] ?? getSingleUnitAmount(currencies[Field.OUTPUT]), - currencies[Field.OUTPUT] + parsedAmounts[Field.OUTPUT] && showFiatValueOutput ? parsedAmounts[Field.OUTPUT] : undefined ) const [routeNotFound, routeIsLoading, routeIsSyncing] = useMemo(