diff --git a/src/features/positions/components/vault-risk-indicators.tsx b/src/features/positions/components/vault-risk-indicators.tsx
deleted file mode 100644
index 6ec2b089..00000000
--- a/src/features/positions/components/vault-risk-indicators.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { useMemo } from 'react';
-import type { UserVaultV2 } from '@/data-sources/subgraph/v2-vaults';
-import { RiskIndicator } from '@/features/markets/components/risk-indicator';
-import { useProcessedMarkets } from '@/hooks/useProcessedMarkets';
-import { computeMarketWarnings } from '@/hooks/useMarketWarnings';
-import { parseCapIdParams } from '@/utils/morpho';
-import { type WarningWithDetail, WarningCategory } from '@/utils/types';
-
-type AggregatedVaultRiskIndicatorsProps = {
- vault: UserVaultV2;
-};
-
-/**
- * Aggregates risk indicators from all markets allocated in a vault.
- * Similar to AggregatedRiskIndicators but works with vault data structure.
- */
-export function AggregatedVaultRiskIndicators({ vault }: AggregatedVaultRiskIndicatorsProps) {
- const { allMarkets } = useProcessedMarkets();
-
- // Aggregate warnings from all markets in the vault
- const uniqueWarnings = useMemo((): WarningWithDetail[] => {
- const allWarnings: WarningWithDetail[] = [];
-
- vault.caps.forEach((cap) => {
- const params = parseCapIdParams(cap.idParams);
-
- // Only process market caps (not collateral caps)
- if (params.type === 'market' && params.marketId) {
- const market = allMarkets.find((m) => m.uniqueKey.toLowerCase() === params.marketId?.toLowerCase());
-
- if (market) {
- const marketWarnings = computeMarketWarnings(market, true);
- allWarnings.push(...marketWarnings);
- }
- }
- });
-
- // Remove duplicates based on warning code
- return allWarnings.filter((warning, index, array) => array.findIndex((w) => w.code === warning.code) === index);
- }, [vault.caps, allMarkets]);
-
- // Helper to get warnings by category and determine risk level
- const getWarningIndicator = (category: WarningCategory, greenDesc: string, yellowDesc: string, redDesc: string) => {
- const categoryWarnings = uniqueWarnings.filter((w) => w.category === category);
-
- if (categoryWarnings.length === 0) {
- return (
-
- );
- }
-
- if (categoryWarnings.some((w) => w.level === 'alert')) {
- const alertWarning = categoryWarnings.find((w) => w.level === 'alert');
- return (
-
- );
- }
-
- return (
-
- );
- };
-
- return (
- <>
- {getWarningIndicator(WarningCategory.asset, 'Recognized asset', 'Asset with warning', 'High-risk asset')}
- {getWarningIndicator(WarningCategory.oracle, 'Recognized oracles', 'Oracle warning', 'Oracle warning')}
- {getWarningIndicator(WarningCategory.debt, 'No bad debt', 'Bad debt has occurred', 'Bad debt higher than 1% of supply')}
- >
- );
-}
diff --git a/src/features/positions/positions-view.tsx b/src/features/positions/positions-view.tsx
index a8e5ebd9..8e78d613 100644
--- a/src/features/positions/positions-view.tsx
+++ b/src/features/positions/positions-view.tsx
@@ -1,6 +1,6 @@
'use client';
-import { useCallback } from 'react';
+import { useCallback, useMemo } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { IoIosSwap } from 'react-icons/io';
import { GoHistory } from 'react-icons/go';
@@ -14,7 +14,9 @@ import { useProcessedMarkets } from '@/hooks/useProcessedMarkets';
import useUserPositionsSummaryData from '@/hooks/useUserPositionsSummaryData';
import { usePortfolioValue } from '@/hooks/usePortfolioValue';
import { useUserVaultsV2Query } from '@/hooks/queries/useUserVaultsV2Query';
+import { useVaultHistoricalApy } from '@/hooks/useVaultHistoricalApy';
import { useModal } from '@/hooks/useModal';
+import { usePositionsFilters } from '@/stores/usePositionsFilters';
import { SuppliedMorphoBlueGroupedTable } from './components/supplied-morpho-blue-grouped-table';
import { PortfolioValueBadge } from './components/portfolio-value-badge';
import { UserVaultsTable } from './components/user-vaults-table';
@@ -25,6 +27,7 @@ export default function Positions() {
const { account } = useParams<{ account: string }>();
const { open } = useModal();
const { chainId } = useConnection();
+ const period = usePositionsFilters((s) => s.period);
const { loading: isMarketsLoading } = useProcessedMarkets();
@@ -38,6 +41,18 @@ export default function Positions() {
refetch: refetchVaults,
} = useUserVaultsV2Query({ userAddress: account as Address });
+ // Fetch historical APY for vaults
+ const { data: vaultApyData, isLoading: isVaultApyLoading } = useVaultHistoricalApy(vaults, period);
+
+ // Merge APY data into vaults
+ const vaultsWithApy = useMemo(() => {
+ if (!vaultApyData) return vaults;
+ return vaults.map((vault) => ({
+ ...vault,
+ actualApy: vaultApyData.get(vault.address.toLowerCase())?.actualApy,
+ }));
+ }, [vaults, vaultApyData]);
+
const router = useRouter();
// Calculate portfolio value from positions and vaults
@@ -63,8 +78,6 @@ export default function Positions() {
Portfolio
- {' '}
- {/* aligned with portfolio */}