From 2ab0da38e8793e8647bcd68fd196782416c196f7 Mon Sep 17 00:00:00 2001 From: Xiaolei-Shawn Date: Wed, 17 Aug 2022 22:13:11 +0300 Subject: [PATCH 1/3] Resolve rate from coinGecko if exchange rate is not found and fix a bug in rate calculation --- hooks/useExchange.ts | 26 ++++++++++++++++++++------ pages/exchange.tsx | 4 ++-- utils/currencies.ts | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/hooks/useExchange.ts b/hooks/useExchange.ts index 0868fd4636..3a1ebb3abf 100644 --- a/hooks/useExchange.ts +++ b/hooks/useExchange.ts @@ -1,4 +1,4 @@ -import useSynthetixQueries from '@synthetixio/queries'; +import useSynthetixQueries, { Token } from '@synthetixio/queries'; import Wei, { wei } from '@synthetixio/wei'; import { ethers } from 'ethers'; import produce from 'immer'; @@ -55,7 +55,11 @@ import { networkState, gasSpeedState, } from 'store/wallet'; -import { newGetExchangeRatesForCurrencies } from 'utils/currencies'; +import { + newGetCoinGeckoPricesForCurrencies, + newGetExchangeRatesForCurrencies, + newGetExchangeRatesTupleForCurrencies, +} from 'utils/currencies'; import { truncateNumbers, zeroBN } from 'utils/formatters/number'; import { hexToAsciiV2 } from 'utils/formatters/string'; import logError from 'utils/logError'; @@ -191,7 +195,7 @@ const useExchange = ({ : null; const quoteCurrencyTokenAddress = useMemo( - () => + (): Token['address'] | null => quoteCurrencyKey != null ? isQuoteCurrencyETH ? ETH_ADDRESS @@ -201,7 +205,7 @@ const useExchange = ({ ); const baseCurrencyTokenAddress = useMemo( - () => + (): Token['address'] | null => baseCurrencyKey != null ? isBaseCurrencyETH ? ETH_ADDRESS @@ -274,11 +278,21 @@ const useExchange = ({ const exchangeRates = exchangeRatesQuery.isSuccess ? exchangeRatesQuery.data ?? null : null; - const rate = useMemo( - () => newGetExchangeRatesForCurrencies(exchangeRates, quoteCurrencyKey, baseCurrencyKey), + const [baseRate, quoteRate] = useMemo( + () => newGetExchangeRatesTupleForCurrencies(exchangeRates, baseCurrencyKey, quoteCurrencyKey), [exchangeRates, quoteCurrencyKey, baseCurrencyKey] ); + const rate = useMemo(() => { + const base = baseRate.lte(0) + ? newGetCoinGeckoPricesForCurrencies(coinGeckoPrices, baseCurrencyTokenAddress) + : baseRate; + const quote = quoteRate.lte(0) + ? newGetCoinGeckoPricesForCurrencies(coinGeckoPrices, quoteCurrencyTokenAddress) + : quoteRate; + return base.gt(0) && quote.gt(0) ? base.div(quote) : wei(0); + }, [baseCurrencyTokenAddress, baseRate, coinGeckoPrices, quoteCurrencyTokenAddress, quoteRate]); + const inverseRate = useMemo(() => (rate.gt(0) ? wei(1).div(rate) : wei(0)), [rate]); const getBalance = useCallback( diff --git a/pages/exchange.tsx b/pages/exchange.tsx index b31a6eedf3..6215c89da5 100644 --- a/pages/exchange.tsx +++ b/pages/exchange.tsx @@ -22,7 +22,7 @@ const Exchange: ExchangeComponent = () => { showNoSynthsCard: true, }); - const { baseCurrencyKey, quoteCurrencyKey, inverseRate } = exchangeData; + const { baseCurrencyKey, quoteCurrencyKey, rate } = exchangeData; return ( @@ -32,7 +32,7 @@ const Exchange: ExchangeComponent = () => { ? t('exchange.page-title-currency-pair', { baseCurrencyKey, quoteCurrencyKey, - rate: formatCurrency(quoteCurrencyKey, inverseRate, { + rate: formatCurrency(quoteCurrencyKey, rate, { currencyKey: quoteCurrencyKey, }), }) diff --git a/utils/currencies.ts b/utils/currencies.ts index 8d0704cbdc..97a567294e 100644 --- a/utils/currencies.ts +++ b/utils/currencies.ts @@ -1,8 +1,9 @@ -import { Rates } from '@synthetixio/queries'; +import { Rates, Token } from '@synthetixio/queries'; import { wei } from '@synthetixio/wei'; import { CurrencyKey, Synths, CRYPTO_CURRENCY_MAP, FIAT_SYNTHS } from 'constants/currency'; +import { PriceResponse } from '../queries/coingecko/types'; import { FuturesMarketKey } from './futures'; export const isSynth = (currencyKey: CurrencyKey) => !!Synths[currencyKey]; @@ -54,5 +55,42 @@ export const newGetExchangeRatesForCurrencies = ( : rates[base].div(rates[quote]); }; +export const newGetExchangeRatesTupleForCurrencies = ( + rates: Rates | null, + base: CurrencyKey | FuturesMarketKey | string | null, + quote: CurrencyKey | FuturesMarketKey | null +) => { + base = new Set([ + FuturesMarketKey.sAPE, + FuturesMarketKey.sDYDX, + FuturesMarketKey.sXAU, + FuturesMarketKey.sXAG, + ]).has(base as FuturesMarketKey) + ? synthToAsset(base as CurrencyKey) + : base; + const baseRate = + rates == null || base == null || rates[base] === undefined ? wei(0) : rates[base]; + const quoteRate = + rates == null || quote == null || rates[quote] === undefined ? wei(0) : rates[quote]; + + return [baseRate, quoteRate]; +}; + +export const newGetCoinGeckoPricesForCurrencies = ( + coinGeckoPrices: PriceResponse | null, + baseCurrencyTokenAddress: Token['address'] | null +) => { + if (!coinGeckoPrices || !baseCurrencyTokenAddress) { + return wei(0); + } + const base = baseCurrencyTokenAddress.toLowerCase(); + + if (!coinGeckoPrices[base]) { + return wei(0); + } + + return wei(coinGeckoPrices[base].usd); +}; + export const getCurrencyKeyURLPath = (currencyKey: CurrencyKey) => `https:///www.synthetix.io/assets/synths/svg/${currencyKey}.svg`; From 903c7eec41556da33e7dc139815e81c61c953e4b Mon Sep 17 00:00:00 2001 From: Xiaolei-Shawn Date: Thu, 18 Aug 2022 08:56:50 +0300 Subject: [PATCH 2/3] Export rate from useExchange hook --- hooks/useExchange.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/useExchange.ts b/hooks/useExchange.ts index 3a1ebb3abf..c553f8c6d3 100644 --- a/hooks/useExchange.ts +++ b/hooks/useExchange.ts @@ -1157,6 +1157,7 @@ const useExchange = ({ return { baseCurrencyKey, handleCurrencySwap, + rate, inverseRate, quoteCurrencyKey, txProvider, From f03ced6a95ff9081f32377d755f847366b7f0b60 Mon Sep 17 00:00:00 2001 From: Xiaolei-Shawn Date: Thu, 18 Aug 2022 21:39:41 +0300 Subject: [PATCH 3/3] Use inverted rate on title --- hooks/useExchange.ts | 7 +++---- pages/exchange.tsx | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/hooks/useExchange.ts b/hooks/useExchange.ts index c553f8c6d3..4c26bdc68f 100644 --- a/hooks/useExchange.ts +++ b/hooks/useExchange.ts @@ -278,8 +278,8 @@ const useExchange = ({ const exchangeRates = exchangeRatesQuery.isSuccess ? exchangeRatesQuery.data ?? null : null; - const [baseRate, quoteRate] = useMemo( - () => newGetExchangeRatesTupleForCurrencies(exchangeRates, baseCurrencyKey, quoteCurrencyKey), + const [quoteRate, baseRate] = useMemo( + () => newGetExchangeRatesTupleForCurrencies(exchangeRates, quoteCurrencyKey, baseCurrencyKey), [exchangeRates, quoteCurrencyKey, baseCurrencyKey] ); @@ -290,7 +290,7 @@ const useExchange = ({ const quote = quoteRate.lte(0) ? newGetCoinGeckoPricesForCurrencies(coinGeckoPrices, quoteCurrencyTokenAddress) : quoteRate; - return base.gt(0) && quote.gt(0) ? base.div(quote) : wei(0); + return base.gt(0) && quote.gt(0) ? quote.div(base) : wei(0); }, [baseCurrencyTokenAddress, baseRate, coinGeckoPrices, quoteCurrencyTokenAddress, quoteRate]); const inverseRate = useMemo(() => (rate.gt(0) ? wei(1).div(rate) : wei(0)), [rate]); @@ -1157,7 +1157,6 @@ const useExchange = ({ return { baseCurrencyKey, handleCurrencySwap, - rate, inverseRate, quoteCurrencyKey, txProvider, diff --git a/pages/exchange.tsx b/pages/exchange.tsx index 6215c89da5..b31a6eedf3 100644 --- a/pages/exchange.tsx +++ b/pages/exchange.tsx @@ -22,7 +22,7 @@ const Exchange: ExchangeComponent = () => { showNoSynthsCard: true, }); - const { baseCurrencyKey, quoteCurrencyKey, rate } = exchangeData; + const { baseCurrencyKey, quoteCurrencyKey, inverseRate } = exchangeData; return ( @@ -32,7 +32,7 @@ const Exchange: ExchangeComponent = () => { ? t('exchange.page-title-currency-pair', { baseCurrencyKey, quoteCurrencyKey, - rate: formatCurrency(quoteCurrencyKey, rate, { + rate: formatCurrency(quoteCurrencyKey, inverseRate, { currencyKey: quoteCurrencyKey, }), })