From 2ea04dea598a2cfe6db6cf3904e607225d1021aa Mon Sep 17 00:00:00 2001 From: brightiron Date: Sun, 11 Feb 2024 11:55:56 -0600 Subject: [PATCH] add price to sidebar. remove from protocol metrics and other views. --- src/components/Sidebar/NavContent.tsx | 41 ++++++------------ src/hooks/usePrices.ts | 37 ++++++++++++++++ src/hooks/useProtocolMetrics.ts | 38 ---------------- src/views/MyBalances/MyCoolerLoans.tsx | 8 +--- src/views/MyBalances/MyGohmBalances.tsx | 7 +-- src/views/MyBalances/index.tsx | 11 ++--- src/views/Range/hooks.tsx | 43 +------------------ .../TreasuryDashboard/TreasuryDashboard.tsx | 32 +++++++------- .../components/Metric/Metric.tsx | 41 +----------------- 9 files changed, 75 insertions(+), 183 deletions(-) diff --git a/src/components/Sidebar/NavContent.tsx b/src/components/Sidebar/NavContent.tsx index f7d4cc2da9..ec9dfbf763 100644 --- a/src/components/Sidebar/NavContent.tsx +++ b/src/components/Sidebar/NavContent.tsx @@ -2,14 +2,12 @@ import { Box, Link, Paper, SvgIcon, Typography, useTheme } from "@mui/material"; import { styled } from "@mui/material/styles"; import { Icon } from "@olympusdao/component-library"; import React from "react"; -import { NavLink } from "react-router-dom"; import lendAndBorrowIcon from "src/assets/icons/lendAndBorrow.svg?react"; import OlympusIcon from "src/assets/icons/olympus-nav-header.svg?react"; import NavItem from "src/components/library/NavItem"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { formatCurrency } from "src/helpers"; +import { useGohmPriceDefiLlama, useOhmPriceDefillama } from "src/hooks/usePrices"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; -import { BondDiscount } from "src/views/Bond/components/BondDiscount"; -import { DetermineRangeDiscount } from "src/views/Range/hooks"; import { useNetwork } from "wagmi"; const PREFIX = "NavContent"; @@ -28,6 +26,8 @@ const NavContent: React.VFC = () => { const theme = useTheme(); const { chain = { id: 1 } } = useNetwork(); const networks = useTestableNetworks(); + const { data: ohmPrice } = useOhmPriceDefillama(); + const { data: gohmPrice } = useGohmPriceDefiLlama(); return ( @@ -45,6 +45,14 @@ const NavContent: React.VFC = () => { Olympus + + + OHM Price: {formatCurrency(ohmPrice || 0, 2)} + + + gOHM Price: {formatCurrency(gohmPrice || 0, 2)} + +
@@ -93,29 +101,4 @@ const NavContent: React.VFC = () => { ); }; -const RangePrice = (props: { bidOrAsk: "bid" | "ask" }) => { - const { data, isFetched } = DetermineRangeDiscount(props.bidOrAsk); - return ( - <> - {isFetched && ( - - - {props.bidOrAsk === "bid" ? `Bid` : `Ask`} - - - - - - {data.quoteToken} - - - - - - - )} - - ); -}; - export default NavContent; diff --git a/src/hooks/usePrices.ts b/src/hooks/usePrices.ts index 4e0485e144..f50c2798e9 100644 --- a/src/hooks/usePrices.ts +++ b/src/hooks/usePrices.ts @@ -1,7 +1,9 @@ import { useQuery } from "@tanstack/react-query"; import { NetworkId } from "src/constants"; +import { OHM_ADDRESSES } from "src/constants/addresses"; import { OHM_TOKEN } from "src/constants/tokens"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { useGetDefillamaPrice } from "src/helpers/pricing/useGetDefillamaPrice"; import { queryAssertion } from "src/helpers/react-query/queryAssertion"; import { nonNullable } from "src/helpers/types/nonNullable"; import { useCurrentIndex } from "src/hooks/useCurrentIndex"; @@ -19,6 +21,22 @@ export const useOhmPrice = () => { }); }; +export const useOhmPriceDefillama = () => { + const { data: currentMarketPrices } = useGetDefillamaPrice({ + addresses: [OHM_ADDRESSES[1]], + }); + + return useQuery( + ["useOhmPriceDefillama"], + async () => { + const ohmPriceUSD = currentMarketPrices?.[`ethereum:${OHM_ADDRESSES[1]}`].price; + + return ohmPriceUSD; + }, + { enabled: !!currentMarketPrices }, + ); +}; + export const gohmPriceQueryKey = (marketPrice?: number, currentIndex?: DecimalBigNumber) => ["useGOHMPrice", marketPrice, currentIndex].filter(nonNullable); @@ -40,3 +58,22 @@ export const useGohmPrice = () => { { enabled: !!ohmPrice && !!currentIndex }, ); }; + +/** + * Returns the calculated price of gOHM. + */ +export const useGohmPriceDefiLlama = () => { + const { data: ohmPrice } = useOhmPriceDefillama(); + const { data: currentIndex } = useCurrentIndex(); + + const key = gohmPriceQueryKey(ohmPrice, currentIndex); + return useQuery( + [key], + async () => { + queryAssertion(ohmPrice && currentIndex, key); + + return currentIndex.toApproxNumber() * ohmPrice; + }, + { enabled: !!ohmPrice && !!currentIndex }, + ); +}; diff --git a/src/hooks/useProtocolMetrics.ts b/src/hooks/useProtocolMetrics.ts index fc2ef768cc..de6037d86d 100644 --- a/src/hooks/useProtocolMetrics.ts +++ b/src/hooks/useProtocolMetrics.ts @@ -10,44 +10,6 @@ export const useTotalValueDeposited = ({ ignoreCache }: { ignoreCache?: boolean return data.sOhmTotalValueLocked; }; -/** - * Returns the latest OHM price (in USD). - * - * This data is fetched from the subgraph, and will not reflect market rates. - * Do NOT use this if you need real-time data. Instead, use `useOhmPrice` from - * `src/hooks/usePrices.ts`. - * - * @returns - */ -export const useOhmPrice = ({ ignoreCache }: { ignoreCache?: boolean }): number | undefined => { - const { data } = useMetricsLatestQuery({ ignoreCache }); - - if (!data) { - return undefined; - } - - return data.ohmPrice; -}; - -/** - * Returns the latest gOHM price (in USD). - * - * This data is fetched from the subgraph, and will not reflect market rates. - * Do NOT use this if you need real-time data. Instead, use `useGohmPrice` from - * `src/hooks/usePrices.ts`. - * - * @returns - */ -export const useGOhmPrice = ({ ignoreCache }: { ignoreCache?: boolean }): number | undefined => { - const { data } = useMetricsLatestQuery({ ignoreCache }); - - if (!data) { - return undefined; - } - - return data.gOhmPrice; -}; - /** * Determines the current index. * diff --git a/src/views/MyBalances/MyCoolerLoans.tsx b/src/views/MyBalances/MyCoolerLoans.tsx index 49523888fd..0f864532f4 100644 --- a/src/views/MyBalances/MyCoolerLoans.tsx +++ b/src/views/MyBalances/MyCoolerLoans.tsx @@ -4,9 +4,7 @@ import { ethers } from "ethers"; import { Link as RouterLink } from "react-router-dom"; import lendAndBorrowIcon from "src/assets/icons/lendAndBorrow.svg?react"; import { formatCurrency } from "src/helpers"; -import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; -import { useCurrentIndex } from "src/hooks/useCurrentIndex"; -import { useOhmPrice } from "src/hooks/usePrices"; +import { useGohmPriceDefiLlama } from "src/hooks/usePrices"; import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; import { useGetCoolerLoans } from "src/views/Lending/Cooler/hooks/useGetCoolerLoans"; import { useAccount } from "wagmi"; @@ -14,9 +12,7 @@ import { useAccount } from "wagmi"; export const MyCoolerLoans = ({ balance, balanceUSD }: { balance: string; balanceUSD: string }) => { const theme = useTheme(); const { address } = useAccount(); - const { data: ohmPrice = 0 } = useOhmPrice(); - const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); - const gOhmPrice = ohmPrice * currentIndex.toApproxNumber(); + const { data: gOhmPrice = 0 } = useGohmPriceDefiLlama(); const { data: clearingHouseV1 } = useGetClearingHouse({ clearingHouse: "clearingHouseV1" }); const { data: clearingHouseV2 } = useGetClearingHouse({ clearingHouse: "clearingHouseV2" }); diff --git a/src/views/MyBalances/MyGohmBalances.tsx b/src/views/MyBalances/MyGohmBalances.tsx index 0c1ac075a4..792ffdd28b 100644 --- a/src/views/MyBalances/MyGohmBalances.tsx +++ b/src/views/MyBalances/MyGohmBalances.tsx @@ -5,16 +5,13 @@ import WalletIcon from "src/assets/icons/wallet.svg?react"; import { formatCurrency } from "src/helpers"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; import { useGohmBalance } from "src/hooks/useBalance"; -import { useCurrentIndex } from "src/hooks/useCurrentIndex"; -import { useOhmPrice } from "src/hooks/usePrices"; +import { useGohmPriceDefiLlama } from "src/hooks/usePrices"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; import { NetworkId } from "src/networkDetails"; export const MyGohmBalances = ({ walletBalance }: { walletBalance?: DecimalBigNumber }) => { const gohmBalances = useGohmBalance(); - const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); - const { data: ohmPrice = 0 } = useOhmPrice(); - const gOhmPrice = ohmPrice * currentIndex.toApproxNumber(); + const { data: gOhmPrice = 0 } = useGohmPriceDefiLlama(); const networks = useTestableNetworks(); diff --git a/src/views/MyBalances/index.tsx b/src/views/MyBalances/index.tsx index 20638b05d7..a5d1274b22 100644 --- a/src/views/MyBalances/index.tsx +++ b/src/views/MyBalances/index.tsx @@ -1,6 +1,6 @@ -import { Box, Grid, Skeleton, Typography, useMediaQuery } from "@mui/material"; +import { Box, Grid, Typography, useMediaQuery } from "@mui/material"; import { useTheme } from "@mui/material/styles"; -import { Metric, Token } from "@olympusdao/component-library"; +import { Token } from "@olympusdao/component-library"; import { FC } from "react"; import { InPageConnectButton } from "src/components/ConnectButton/ConnectButton"; import { DevFaucet } from "src/components/DevFaucet"; @@ -18,7 +18,7 @@ import { useWsohmBalance, } from "src/hooks/useBalance"; import { useCurrentIndex } from "src/hooks/useCurrentIndex"; -import { useOhmPrice } from "src/hooks/useProtocolMetrics"; +import { useOhmPriceDefillama } from "src/hooks/usePrices"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; import { NetworkId } from "src/networkDetails"; import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; @@ -42,7 +42,7 @@ export const MyBalances: FC = () => { const { address } = useAccount(); const networks = useTestableNetworks(); const { chain = { id: 1 } } = useNetwork(); - const ohmPrice = useOhmPrice({}) || 0; + const { data: ohmPrice = 0 } = useOhmPriceDefillama(); const { data: currentIndex = new DecimalBigNumber("0", 9) } = useCurrentIndex(); const { data: v1OhmBalance = new DecimalBigNumber("0", 9) } = useV1OhmBalance()[networks.MAINNET]; const { data: v1SohmBalance = new DecimalBigNumber("0", 9) } = useV1SohmBalance()[networks.MAINNET]; @@ -177,9 +177,6 @@ export const MyBalances: FC = () => { - - } /> - diff --git a/src/views/Range/hooks.tsx b/src/views/Range/hooks.tsx index 1ca4b4297d..5451bb696c 100644 --- a/src/views/Range/hooks.tsx +++ b/src/views/Range/hooks.tsx @@ -14,8 +14,6 @@ import { trackGAEvent, trackGtagEvent } from "src/helpers/analytics/trackGAEvent import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; import { isValidAddress } from "src/helpers/misc/isValidAddress"; import { Providers } from "src/helpers/providers/Providers/Providers"; -import { queryAssertion } from "src/helpers/react-query/queryAssertion"; -import { useOhmPrice } from "src/hooks/usePrices"; import { useTestableNetworks } from "src/hooks/useTestableNetworks"; import { BondFixedTermSDA__factory, BondTeller__factory, IERC20__factory } from "src/typechain"; import { RANGEv2 as OlympusRange } from "src/typechain/Range"; @@ -233,7 +231,7 @@ export const DetermineRangePrice = (bidOrAsk: "bid" | "ask") => { const { data: lowerBondMarket } = useBondV3({ id: rangeData.low.market.toString(), isInverseBond: true }); const { - data = { price: 0, contract: "swap", activeBondMarket: false }, + data = { price: 0, contract: "swap", activeBondMarket: false, discount: undefined }, isFetched, isLoading, } = useQuery( @@ -284,45 +282,6 @@ export const DetermineRangePrice = (bidOrAsk: "bid" | "ask") => { return { data, isFetched, isLoading }; }; -export const DetermineRangeDiscount = (bidOrAsk: "bid" | "ask") => { - const { data: currentOhmPrice } = useOhmPrice(); - const { data: reserveSymbol } = OperatorReserveSymbol(); - const { data: rangeData } = RangeData(); - const { data: bidOrAskPrice } = DetermineRangePrice(bidOrAsk); - const { - data = { discount: 0, quoteToken: "" }, - isFetched, - isLoading, - } = useQuery( - ["getDetermineRangeDiscount", currentOhmPrice, bidOrAskPrice, reserveSymbol, bidOrAsk], - () => { - queryAssertion(currentOhmPrice); - const bondDiscount = bidOrAskPrice.discount ? bidOrAskPrice.discount : undefined; - const sellActive = bidOrAsk === "bid"; - const swapWithOperator = sellActive - ? bidOrAskPrice.price < parseBigNumber(rangeData.low.wall.price, 18) - : bidOrAskPrice.price > parseBigNumber(rangeData.high.wall.price, 18); - - const swapPrice = swapWithOperator - ? sellActive - ? parseBigNumber(rangeData.low.wall.price, 18) - : parseBigNumber(rangeData.high.wall.price, 18) - : sellActive - ? bidOrAskPrice.price - : bidOrAskPrice.price; - const discount = - bondDiscount && !swapWithOperator - ? bondDiscount - : (currentOhmPrice - swapPrice) / (sellActive ? -currentOhmPrice : currentOhmPrice); - - return { discount, quoteToken: bidOrAsk === "ask" ? "OHM" : reserveSymbol.symbol }; - }, - { enabled: !!currentOhmPrice && !!bidOrAskPrice.price && !!reserveSymbol.symbol }, - ); - - return { data, isFetched, isLoading }; -}; - type RangeContracts = "swap" | "bond"; /** * Executes Range Swap Transaction and routes it to the appropriate contract. diff --git a/src/views/TreasuryDashboard/TreasuryDashboard.tsx b/src/views/TreasuryDashboard/TreasuryDashboard.tsx index 7ff76e38c5..a7bb9540a5 100644 --- a/src/views/TreasuryDashboard/TreasuryDashboard.tsx +++ b/src/views/TreasuryDashboard/TreasuryDashboard.tsx @@ -1,5 +1,5 @@ import { Box, Container, Grid, useMediaQuery, useTheme } from "@mui/material"; -import { Metric, MetricCollection, Paper, TabBar } from "@olympusdao/component-library"; +import { Metric, Paper, TabBar } from "@olympusdao/component-library"; import { memo, useEffect, useMemo, useState } from "react"; import { Outlet, Route, Routes, useSearchParams } from "react-router-dom"; import PageTitle from "src/components/PageTitle"; @@ -26,11 +26,8 @@ import { BackingPerOHM, CurrentIndex, GOhmCirculatingSupply, - GOHMPriceFromSubgraph, - MarketCap, MetricSubgraphProps, OhmCirculatingSupply, - OHMPriceFromSubgraph, } from "src/views/TreasuryDashboard/components/Metric/Metric"; const baseMetricProps: PropsOf = { labelVariant: "h6", metricVariant: "h5" }; @@ -161,18 +158,21 @@ const MetricsDashboard = () => { - - - - - {isTokenOHM() ? ( - - ) : ( - - )} - {isTokenOHM() ? : } - - + +
+ {isTokenOHM() ? ( + + ) : ( + + )} +
+
+ {isTokenOHM() ? : } +
+
+ +
+
{/* Custom paddingBottom to make the filter row(s) equidistant from the metrics (above) and diff --git a/src/views/TreasuryDashboard/components/Metric/Metric.tsx b/src/views/TreasuryDashboard/components/Metric/Metric.tsx index e3efcf83a2..82f2f7af93 100644 --- a/src/views/TreasuryDashboard/components/Metric/Metric.tsx +++ b/src/views/TreasuryDashboard/components/Metric/Metric.tsx @@ -1,12 +1,7 @@ import { Metric } from "@olympusdao/component-library"; import { formatCurrency, formatCurrencyOrLoading, formatNumber, formatNumberOrLoading } from "src/helpers"; import { useGohmPrice, useOhmPrice } from "src/hooks/usePrices"; -import { - useCurrentIndex, - useGOhmPrice as useGOhmPriceFromSubgraph, - useOhmPrice as useOhmPriceFromSubgraph, - useTotalValueDeposited, -} from "src/hooks/useProtocolMetrics"; +import { useCurrentIndex, useTotalValueDeposited } from "src/hooks/useProtocolMetrics"; import { useTreasuryMarketValueLatest } from "src/hooks/useTokenRecordsMetrics"; import { useOhmCirculatingSupply, useOhmTotalSupply } from "src/hooks/useTokenSupplyMetrics"; import { useLiquidBackingPerGOhm, useLiquidBackingPerOhmBacked, useMarketCap } from "src/hooks/useTreasuryMetrics"; @@ -55,23 +50,6 @@ export const OHMPrice: React.FC = props => { return ; }; -/** - * same as OHMPrice but uses Subgraph price - */ -export const OHMPriceFromSubgraph: React.FC = props => { - const ohmPrice = useOhmPriceFromSubgraph({ ignoreCache: props.ignoreCache }); - const _props: MetricProps = { - ...props, - label: "OHM " + `Price`, - tooltip: `This price is determined at the time a snapshot is recorded (every 8 hours). As a result, it will lag the real-time market rate.`, - }; - - if (ohmPrice) _props.metric = formatCurrency(ohmPrice, 2); - else _props.isLoading = true; - - return ; -}; - export const OhmCirculatingSupply: React.FC = props => { const totalSupply = useOhmTotalSupply({ ignoreCache: props.ignoreCache }); const circSupply = useOhmCirculatingSupply({ ignoreCache: props.ignoreCache }); @@ -186,23 +164,6 @@ export const GOHMPrice: React.FC = props => { return ; }; -export const GOHMPriceFromSubgraph: React.FC = props => { - const gOhmPrice = useGOhmPriceFromSubgraph({ ignoreCache: props.ignoreCache }); - const _props: MetricProps = { - ...props, - label: "gOHM " + `Price`, - tooltip: - "gOHM = sOHM * index" + - "\n\n" + - `The price of gOHM is equal to the price of OHM multiplied by the current index.`, - }; - - if (gOhmPrice) _props.metric = formatCurrency(gOhmPrice, 2); - else _props.isLoading = true; - - return ; -}; - export const TotalValueDeposited: React.FC = props => { const totalValueDeposited = useTotalValueDeposited({ ignoreCache: props.ignoreCache }); const _props: MetricProps = {