import { Currency, CurrencyAmount, Price, Token } from '@uniswap/sdk-core' import { useMemo } from 'react' import { SupportedChainId } from '../constants/chains' import { DAI_OPTIMISM, USDC, USDC_ARBITRUM } from '../constants/tokens' import { useV2TradeExactOut } from './useV2Trade' import { useClientSideV3TradeExactOut } from './useClientSideV3Trade' import { useActiveWeb3React } from './web3' // Stablecoin amounts used when calculating spot price for a given currency. // The amount is large enough to filter low liquidity pairs. const STABLECOIN_AMOUNT_OUT: { [chainId: number]: CurrencyAmount } = { [SupportedChainId.MAINNET]: CurrencyAmount.fromRawAmount(USDC, 100_000e6), [SupportedChainId.ARBITRUM_ONE]: CurrencyAmount.fromRawAmount(USDC_ARBITRUM, 10_000e6), [SupportedChainId.OPTIMISM]: CurrencyAmount.fromRawAmount(DAI_OPTIMISM, 10_000e18), } /** * Returns the price in USDC of the input currency * @param currency currency to compute the USDC price of */ export default function useUSDCPrice(currency?: Currency): Price | undefined { const { chainId } = useActiveWeb3React() const amountOut = chainId ? STABLECOIN_AMOUNT_OUT[chainId] : undefined const stablecoin = amountOut?.currency const v2USDCTrade = useV2TradeExactOut(currency, amountOut, { maxHops: 2, }) const v3USDCTrade = useClientSideV3TradeExactOut(currency, amountOut) return useMemo(() => { if (!currency || !stablecoin) { return undefined } // handle usdc if (currency?.wrapped.equals(stablecoin)) { return new Price(stablecoin, stablecoin, '1', '1') } // use v2 price if available, v3 as fallback if (v2USDCTrade) { const { numerator, denominator } = v2USDCTrade.route.midPrice return new Price(currency, stablecoin, denominator, numerator) } else if (v3USDCTrade.trade) { const { numerator, denominator } = v3USDCTrade.trade.route.midPrice return new Price(currency, stablecoin, denominator, numerator) } return undefined }, [currency, stablecoin, v2USDCTrade, v3USDCTrade.trade]) } export function useUSDCValue(currencyAmount: CurrencyAmount | undefined | null) { const price = useUSDCPrice(currencyAmount?.currency) return useMemo(() => { if (!price || !currencyAmount) return null try { return price.quote(currencyAmount) } catch (error) { return null } }, [currencyAmount, price]) }