2021-05-04 00:29:45 +03:00
|
|
|
import { ChainId, Currency, CurrencyAmount, currencyEquals, Price, Token, WETH9 } from '@uniswap/sdk-core'
|
2021-05-12 16:52:17 +03:00
|
|
|
import JSBI from 'jsbi'
|
2020-08-17 16:36:38 +03:00
|
|
|
import { useMemo } from 'react'
|
|
|
|
import { USDC } from '../constants'
|
2021-04-24 01:57:48 +03:00
|
|
|
import { PairState, useV2Pairs } from './useV2Pairs'
|
2020-08-17 16:36:38 +03:00
|
|
|
import { useActiveWeb3React } from '../hooks'
|
2021-04-14 17:12:35 +03:00
|
|
|
import { wrappedCurrency } from '../utils/wrappedCurrency'
|
2020-08-17 16:36:38 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the price in USDC of the input currency
|
|
|
|
* @param currency currency to compute the USDC price of
|
|
|
|
*/
|
2021-05-12 16:52:17 +03:00
|
|
|
export default function useUSDCPrice(currency?: Currency): Price<Currency, Token> | undefined {
|
2020-08-17 16:36:38 +03:00
|
|
|
const { chainId } = useActiveWeb3React()
|
|
|
|
const wrapped = wrappedCurrency(currency, chainId)
|
2021-04-29 03:44:10 +03:00
|
|
|
const weth = WETH9[chainId as ChainId]
|
|
|
|
|
2020-08-17 16:36:38 +03:00
|
|
|
const tokenPairs: [Currency | undefined, Currency | undefined][] = useMemo(
|
|
|
|
() => [
|
2021-04-29 03:44:10 +03:00
|
|
|
[chainId && wrapped && currencyEquals(weth, wrapped) ? undefined : currency, chainId ? weth : undefined],
|
2020-08-17 16:36:38 +03:00
|
|
|
[wrapped?.equals(USDC) ? undefined : wrapped, chainId === ChainId.MAINNET ? USDC : undefined],
|
2021-04-29 03:44:10 +03:00
|
|
|
[chainId ? weth : undefined, chainId === ChainId.MAINNET ? USDC : undefined],
|
2020-08-17 16:36:38 +03:00
|
|
|
],
|
2021-04-29 03:44:10 +03:00
|
|
|
[chainId, currency, weth, wrapped]
|
2020-08-17 16:36:38 +03:00
|
|
|
)
|
2021-04-24 01:57:48 +03:00
|
|
|
const [[ethPairState, ethPair], [usdcPairState, usdcPair], [usdcEthPairState, usdcEthPair]] = useV2Pairs(tokenPairs)
|
2020-08-17 16:36:38 +03:00
|
|
|
|
|
|
|
return useMemo(() => {
|
|
|
|
if (!currency || !wrapped || !chainId) {
|
2020-08-27 20:05:09 +03:00
|
|
|
return undefined
|
2020-08-17 16:36:38 +03:00
|
|
|
}
|
2021-04-29 03:44:10 +03:00
|
|
|
// return some fake price data for non-mainnet
|
|
|
|
if (chainId !== ChainId.MAINNET) {
|
|
|
|
const fakeUSDC = new Token(chainId, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'fUSDC', 'Fake USDC')
|
|
|
|
return new Price(
|
|
|
|
currency,
|
|
|
|
fakeUSDC,
|
|
|
|
10 ** Math.max(0, currency.decimals - 6),
|
|
|
|
15 * 10 ** Math.max(6 - currency.decimals, 0)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-08-17 16:36:38 +03:00
|
|
|
// handle weth/eth
|
2021-04-29 03:44:10 +03:00
|
|
|
if (wrapped.equals(weth)) {
|
2020-08-17 16:36:38 +03:00
|
|
|
if (usdcPair) {
|
2021-04-29 03:44:10 +03:00
|
|
|
const price = usdcPair.priceOf(weth)
|
2020-08-17 16:36:38 +03:00
|
|
|
return new Price(currency, USDC, price.denominator, price.numerator)
|
|
|
|
} else {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// handle usdc
|
|
|
|
if (wrapped.equals(USDC)) {
|
|
|
|
return new Price(USDC, USDC, '1', '1')
|
|
|
|
}
|
|
|
|
|
2021-04-29 03:44:10 +03:00
|
|
|
const ethPairETHAmount = ethPair?.reserveOf(weth)
|
2020-08-17 16:36:38 +03:00
|
|
|
const ethPairETHUSDCValue: JSBI =
|
2021-05-12 16:52:17 +03:00
|
|
|
ethPairETHAmount && usdcEthPair ? usdcEthPair.priceOf(weth).quote(ethPairETHAmount).quotient : JSBI.BigInt(0)
|
2020-08-17 16:36:38 +03:00
|
|
|
|
|
|
|
// all other tokens
|
|
|
|
// first try the usdc pair
|
|
|
|
if (usdcPairState === PairState.EXISTS && usdcPair && usdcPair.reserveOf(USDC).greaterThan(ethPairETHUSDCValue)) {
|
|
|
|
const price = usdcPair.priceOf(wrapped)
|
|
|
|
return new Price(currency, USDC, price.denominator, price.numerator)
|
|
|
|
}
|
|
|
|
if (ethPairState === PairState.EXISTS && ethPair && usdcEthPairState === PairState.EXISTS && usdcEthPair) {
|
2021-04-29 03:44:10 +03:00
|
|
|
if (usdcEthPair.reserveOf(USDC).greaterThan('0') && ethPair.reserveOf(weth).greaterThan('0')) {
|
2020-08-17 16:36:38 +03:00
|
|
|
const ethUsdcPrice = usdcEthPair.priceOf(USDC)
|
2021-04-29 03:44:10 +03:00
|
|
|
const currencyEthPrice = ethPair.priceOf(weth)
|
2020-08-17 16:36:38 +03:00
|
|
|
const usdcPrice = ethUsdcPrice.multiply(currencyEthPrice).invert()
|
|
|
|
return new Price(currency, USDC, usdcPrice.denominator, usdcPrice.numerator)
|
|
|
|
}
|
|
|
|
}
|
2020-08-27 20:05:09 +03:00
|
|
|
return undefined
|
2021-04-29 03:44:10 +03:00
|
|
|
}, [chainId, currency, ethPair, ethPairState, usdcEthPair, usdcEthPairState, usdcPair, usdcPairState, weth, wrapped])
|
2020-08-17 16:36:38 +03:00
|
|
|
}
|
2021-05-04 00:29:45 +03:00
|
|
|
|
2021-05-12 16:52:17 +03:00
|
|
|
export function useUSDCValue(currencyAmount: CurrencyAmount<Currency> | undefined | null) {
|
2021-05-04 00:29:45 +03:00
|
|
|
const price = useUSDCPrice(currencyAmount?.currency)
|
|
|
|
|
|
|
|
return useMemo(() => {
|
|
|
|
if (!price || !currencyAmount) return null
|
|
|
|
return price.quote(currencyAmount)
|
|
|
|
}, [currencyAmount, price])
|
|
|
|
}
|