diff --git a/.gitignore b/.gitignore index 33a7761f..bdaa4c5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - +.codexrc # dependencies /node_modules @@ -54,4 +54,4 @@ next-env.d.ts CLAUDE.md FULLAUTO_CONTEXT.md -.claude/settings.local.json \ No newline at end of file +.claude/settings.local.json diff --git a/src/components/shared/estimated-value-tooltip.tsx b/src/components/shared/estimated-value-tooltip.tsx new file mode 100644 index 00000000..b7e28256 --- /dev/null +++ b/src/components/shared/estimated-value-tooltip.tsx @@ -0,0 +1,32 @@ +import type { ReactNode } from 'react'; +import { Tooltip } from '@/components/ui/tooltip'; +import { TooltipContent } from '@/components/shared/tooltip-content'; +import { cn } from '@/utils/components'; + +type EstimatedValueTooltipProps = { + children: ReactNode; + isEstimated: boolean; + detail?: string; + className?: string; +}; + +const DEFAULT_DETAIL = 'This USD value is estimated using a hardcoded price.'; + +export function EstimatedValueTooltip({ children, isEstimated, detail = DEFAULT_DETAIL, className }: EstimatedValueTooltipProps) { + if (!isEstimated) { + return <>{children}; + } + + return ( + + } + > + {children} + + ); +} diff --git a/src/data-sources/subgraph/market.ts b/src/data-sources/subgraph/market.ts index 4a9bb1d9..baf1d135 100644 --- a/src/data-sources/subgraph/market.ts +++ b/src/data-sources/subgraph/market.ts @@ -7,7 +7,7 @@ import { getSubgraphUrl } from '@/utils/subgraph-urls'; import { blacklistTokens, type ERC20Token, findToken, type UnknownERC20Token, TokenPeg } from '@/utils/tokens'; import { fetchMajorPrices, type MajorPrices } from '@/utils/majorPrices'; import type { Market, MarketWarning } from '@/utils/types'; -import { SUBGRAPH_NO_PRICE, UNRECOGNIZED_COLLATERAL, UNRECOGNIZED_LOAN } from '@/utils/warnings'; +import { UNRECOGNIZED_COLLATERAL, UNRECOGNIZED_LOAN } from '@/utils/warnings'; import { subgraphGraphqlFetcher } from './fetchers'; // Helper to safely parse BigDecimal/BigInt strings @@ -104,7 +104,6 @@ const transformSubgraphMarketToMarket = ( if (knownCollateralAsset) { collateralAssetPrice = getEstimateValue(knownCollateralAsset) ?? 0; } - warnings.push(SUBGRAPH_NO_PRICE); } const supplyAssetsUsd = formatBalance(supplyAssets, loanAsset.decimals) * loanAssetPrice; diff --git a/src/features/markets/components/table/market-row-detail.tsx b/src/features/markets/components/table/market-row-detail.tsx index b05cb46e..ab62053a 100644 --- a/src/features/markets/components/table/market-row-detail.tsx +++ b/src/features/markets/components/table/market-row-detail.tsx @@ -1,4 +1,5 @@ import { Info } from '@/components/Info/info'; +import { EstimatedValueTooltip } from '@/components/shared/estimated-value-tooltip'; import { OracleTypeInfo } from '@/features/markets/components/oracle'; import { useMarketWarnings } from '@/hooks/useMarketWarnings'; import { formatReadable } from '@/utils/balance'; @@ -30,7 +31,11 @@ export function ExpandedMarketDetail({ market }: { market: Market }) {

Available Liquidity

-

{formatReadable(Number(market.state.liquidityAssetsUsd))}

+

+ + {formatReadable(Number(market.state.liquidityAssetsUsd))} + +

Utilization Rate

diff --git a/src/features/markets/components/table/market-table-body.tsx b/src/features/markets/components/table/market-table-body.tsx index e86f16a6..bc70cafc 100644 --- a/src/features/markets/components/table/market-table-body.tsx +++ b/src/features/markets/components/table/market-table-body.tsx @@ -182,6 +182,7 @@ export function MarketTableBody({ currentEntries, expandedRowId, setExpandedRowI assets={item.state.supplyAssets} decimals={item.loanAsset.decimals} symbol={item.loanAsset.symbol} + isEstimated={!item.hasUSDPrice} /> )} {columnVisibility.totalBorrow && ( @@ -191,6 +192,7 @@ export function MarketTableBody({ currentEntries, expandedRowId, setExpandedRowI assets={item.state.borrowAssets} decimals={item.loanAsset.decimals} symbol={item.loanAsset.symbol} + isEstimated={!item.hasUSDPrice} /> )} {columnVisibility.liquidity && ( @@ -200,6 +202,7 @@ export function MarketTableBody({ currentEntries, expandedRowId, setExpandedRowI assets={item.state.liquidityAssets} decimals={item.loanAsset.decimals} symbol={item.loanAsset.symbol} + isEstimated={!item.hasUSDPrice} /> )} {columnVisibility.supplyAPY && ( diff --git a/src/features/markets/components/table/market-table-utils.tsx b/src/features/markets/components/table/market-table-utils.tsx index 51e090c1..9c2a547b 100644 --- a/src/features/markets/components/table/market-table-utils.tsx +++ b/src/features/markets/components/table/market-table-utils.tsx @@ -1,6 +1,7 @@ import { ArrowDownIcon, ArrowUpIcon, ExternalLinkIcon } from '@radix-ui/react-icons'; import { TableHead, TableCell } from '@/components/ui/table'; import { TokenIcon } from '@/components/shared/token-icon'; +import { EstimatedValueTooltip } from '@/components/shared/estimated-value-tooltip'; import { formatBalance, formatReadable } from '@/utils/balance'; import { getAssetURL } from '@/utils/external'; import type { SortColumn } from '../constants'; @@ -68,12 +69,14 @@ export function TDTotalSupplyOrBorrow({ assets, decimals, symbol, + isEstimated = false, }: { dataLabel: string; assetsUSD: number; assets: string; decimals: number; symbol: string; + isEstimated?: boolean; }) { return ( -

${`${formatReadable(Number(assetsUSD))} `}

+

+ ${formatReadable(Number(assetsUSD))} +

{`${formatReadable(formatBalance(assets, decimals))} ${symbol}`}

); diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index 16fc01ea..2eb0654d 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -13,13 +13,6 @@ export const SUBGRAPH_NO_ORACLE = { __typename: 'OracleWarning_MonarchAttached', }; -// Most subgraph markets has no price data -export const SUBGRAPH_NO_PRICE = { - type: 'subgraph_no_price', - level: 'warning', - __typename: 'MarketWarning_SubgraphNoPrice', -}; - export const subgraphDefaultWarnings: MarketWarning[] = [SUBGRAPH_NO_ORACLE]; export const UNRECOGNIZED_LOAN = { @@ -90,15 +83,6 @@ const morphoOfficialWarnings: WarningWithDetail[] = [ }, ]; -const subgraphWarnings: WarningWithDetail[] = [ - { - code: 'subgraph_no_price', - level: 'warning', - description: 'The USD value of the market is estimated with an offchain price source.', - category: WarningCategory.general, - }, -]; - const BAD_DEBT: WarningWithDetail = { code: 'bad_debt_realized', level: 'warning', @@ -155,7 +139,7 @@ export const getMarketWarningsWithDetail = (market: Market, optionsOrWhitelist?: const { considerWhitelist = false, oracleMetadataMap } = options; const result = []; - const allDetails = [...morphoOfficialWarnings, ...subgraphWarnings]; + const allDetails = [...morphoOfficialWarnings]; const whitelistedMarketData = considerWhitelist ? monarchWhitelistedMarkets.find((m) => m.id === market.uniqueKey.toLowerCase())