Skip to content

Commit

Permalink
Merge pull request #3157 from OlympusDAO/priceConsistency
Browse files Browse the repository at this point in the history
Price consistency
  • Loading branch information
brightiron authored Dec 9, 2024
2 parents 5fcb728 + f35409b commit 4d898ed
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 183 deletions.
41 changes: 12 additions & 29 deletions src/components/Sidebar/NavContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ 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 { Environment } from "src/helpers/environment/Environment/Environment";
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";
Expand All @@ -29,6 +27,8 @@ const NavContent: React.VFC = () => {
const theme = useTheme();
const { chain = { id: 1 } } = useNetwork();
const networks = useTestableNetworks();
const { data: ohmPrice } = useOhmPriceDefillama();
const { data: gohmPrice } = useGohmPriceDefiLlama();

const protocolMetricsEnabled = Boolean(Environment.getWundergraphNodeUrl());
const emissionsManagerEnabled = Environment.getEmissionsManagerEnabled();
Expand All @@ -49,6 +49,14 @@ const NavContent: React.VFC = () => {
Olympus
</Typography>
</Link>
<Box display="flex" flexDirection="column" mt="10px">
<Box fontSize="12px" fontWeight="500" lineHeight={"15px"}>
OHM Price: {formatCurrency(ohmPrice || 0, 2)}
</Box>
<Box fontSize="12px" fontWeight="500" lineHeight="15px">
gOHM Price: {formatCurrency(gohmPrice || 0, 2)}
</Box>
</Box>
</Box>

<div className="dapp-menu-links">
Expand Down Expand Up @@ -98,29 +106,4 @@ const NavContent: React.VFC = () => {
);
};

const RangePrice = (props: { bidOrAsk: "bid" | "ask" }) => {
const { data, isFetched } = DetermineRangeDiscount(props.bidOrAsk);
return (
<>
{isFetched && (
<Box ml="26px" mt="12px" mb="12px" mr="18px">
<Typography variant="body2" color="textSecondary">
{props.bidOrAsk === "bid" ? `Bid` : `Ask`}
</Typography>
<Box mt="12px">
<Box mt="8px">
<Link component={NavLink} to={`/range`}>
<Box display="flex" flexDirection="row" justifyContent="space-between">
<Typography variant="body1">{data.quoteToken}</Typography>
<BondDiscount discount={new DecimalBigNumber(data.discount.toString())} />
</Box>
</Link>
</Box>
</Box>
</Box>
)}
</>
);
};

export default NavContent;
37 changes: 37 additions & 0 deletions src/hooks/usePrices.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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);

Expand All @@ -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<number, Error>(
[key],
async () => {
queryAssertion(ohmPrice && currentIndex, key);

return currentIndex.toApproxNumber() * ohmPrice;
},
{ enabled: !!ohmPrice && !!currentIndex },
);
};
38 changes: 0 additions & 38 deletions src/hooks/useProtocolMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
8 changes: 2 additions & 6 deletions src/views/MyBalances/MyCoolerLoans.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@ 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";

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" });
Expand Down
7 changes: 2 additions & 5 deletions src/views/MyBalances/MyGohmBalances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
11 changes: 4 additions & 7 deletions src/views/MyBalances/index.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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";
Expand All @@ -42,7 +42,7 @@ export const MyBalances: FC<OHMAssetsProps> = () => {
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];
Expand Down Expand Up @@ -177,9 +177,6 @@ export const MyBalances: FC<OHMAssetsProps> = () => {
</Box>
</Box>
</Grid>
<Grid item xs={6} sm={4}>
<Metric label="OHM Price" metric={ohmPrice ? formatCurrency(ohmPrice, 2) : <Skeleton />} />
</Grid>
</Grid>
<Box display="flex" flexDirection="row" justifyContent="space-between"></Box>
<Box display="flex" flexWrap="wrap" justifyContent="space-between" mt="50px" gap="20px">
Expand Down
43 changes: 1 addition & 42 deletions src/views/Range/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"
import { Environment } from "src/helpers/environment/Environment/Environment";
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";
Expand Down Expand Up @@ -250,7 +248,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(
Expand Down Expand Up @@ -301,45 +299,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.
Expand Down
32 changes: 16 additions & 16 deletions src/views/TreasuryDashboard/TreasuryDashboard.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -26,11 +26,8 @@ import {
BackingPerOHM,
CurrentIndex,
GOhmCirculatingSupply,
GOHMPriceFromSubgraph,
MarketCap,
MetricSubgraphProps,
OhmCirculatingSupply,
OHMPriceFromSubgraph,
} from "src/views/TreasuryDashboard/components/Metric/Metric";

const baseMetricProps: PropsOf<typeof Metric> = { labelVariant: "h6", metricVariant: "h5" };
Expand Down Expand Up @@ -161,18 +158,21 @@ const MetricsDashboard = () => {
<Grid container spacing={1}>
<Grid item xs={12}>
<Paper {...paperProps}>
<MetricCollection>
<MarketCap {...sharedMetricProps} />
<OHMPriceFromSubgraph {...sharedMetricProps} />
<GOHMPriceFromSubgraph {...sharedMetricProps} className="wsoprice" />
{isTokenOHM() ? (
<OhmCirculatingSupply {...sharedMetricProps} />
) : (
<GOhmCirculatingSupply {...sharedMetricProps} />
)}
{isTokenOHM() ? <BackingPerOHM {...sharedMetricProps} /> : <BackingPerGOHM {...sharedMetricProps} />}
<CurrentIndex {...sharedMetricProps} />
</MetricCollection>
<Box display="flex" justifyContent="space-around" flexWrap="wrap" gap="12px">
<div>
{isTokenOHM() ? (
<OhmCirculatingSupply {...sharedMetricProps} />
) : (
<GOhmCirculatingSupply {...sharedMetricProps} />
)}
</div>
<div>
{isTokenOHM() ? <BackingPerOHM {...sharedMetricProps} /> : <BackingPerGOHM {...sharedMetricProps} />}
</div>
<div>
<CurrentIndex {...sharedMetricProps} />
</div>
</Box>
</Paper>
</Grid>
{/* Custom paddingBottom to make the filter row(s) equidistant from the metrics (above) and
Expand Down
Loading

0 comments on commit 4d898ed

Please sign in to comment.