@@ -10,7 +10,12 @@ import {
1010import { metaMorphoAbi } from "@morpho-org/uikit/assets/abis/meta-morpho" ;
1111import { metaMorphoFactoryAbi } from "@morpho-org/uikit/assets/abis/meta-morpho-factory" ;
1212import useContractEvents from "@morpho-org/uikit/hooks/use-contract-events/use-contract-events" ;
13- import { readAccrualVaults , readAccrualVaultsStateOverride } from "@morpho-org/uikit/lens/read-vaults" ;
13+ import {
14+ getDeadDepositsBitmap ,
15+ readAccrualVaults ,
16+ readAccrualVaultsStateOverride ,
17+ vaultHasDeadDeposits ,
18+ } from "@morpho-org/uikit/lens/read-vaults" ;
1419import { CORE_DEPLOYMENTS , getContractDeploymentInfo } from "@morpho-org/uikit/lib/deployments" ;
1520import { Token } from "@morpho-org/uikit/lib/utils" ;
1621import { useEffect , useMemo } from "react" ;
@@ -25,7 +30,7 @@ import * as Merkl from "@/hooks/use-merkl-campaigns";
2530import { useMerklOpportunities } from "@/hooks/use-merkl-opportunities" ;
2631import { useTopNCurators } from "@/hooks/use-top-n-curators" ;
2732import { getDisplayableCurators } from "@/lib/curators" ;
28- import { CREATE_METAMORPHO_EVENT_OVERRIDES , getDeploylessMode } from "@/lib/overrides" ;
33+ import { CREATE_METAMORPHO_EVENT_OVERRIDES , getDeploylessMode , getShouldEnforceDeadDeposit } from "@/lib/overrides" ;
2934import { getTokenURI } from "@/lib/tokens" ;
3035
3136const STALE_TIME = 5 * 60 * 1000 ;
@@ -37,6 +42,7 @@ export function EarnSubPage() {
3742
3843 const shouldOverrideCreateMetaMorphoEvents = chainId !== undefined && chainId in CREATE_METAMORPHO_EVENT_OVERRIDES ;
3944 const shouldUseDeploylessReads = getDeploylessMode ( chainId ) === "deployless" ;
45+ const shouldEnforceDeadDeposit = getShouldEnforceDeadDeposit ( chainId ) ;
4046
4147 const [ morpho , factory , factoryV1_1 ] = useMemo (
4248 ( ) => [
@@ -116,8 +122,9 @@ export function EarnSubPage() {
116122
117123 const marketIds = useMemo ( ( ) => [ ...new Set ( vaultsData ?. flatMap ( ( d ) => d . vault . withdrawQueue ) ?? [ ] ) ] , [ vaultsData ] ) ;
118124 const markets = useMarkets ( { chainId, marketIds, staleTime : STALE_TIME } ) ;
119- const vaults = useMemo ( ( ) => {
125+ const { vaults, hasDeadDeposits } = useMemo ( ( ) => {
120126 const vaults : AccrualVault [ ] = [ ] ;
127+ const hasDeadDeposits = new Map < Address , boolean > ( ) ;
121128 vaultsData ?. forEach ( ( vaultData ) => {
122129 const { vault : address , supplyQueue, withdrawQueue, ...iVault } = vaultData . vault ;
123130 // NOTE: pending values are placeholders
@@ -131,13 +138,17 @@ export function EarnSubPage() {
131138 pendingTimelock : { value : 0n , validAt : 0n } ,
132139 } ) ;
133140
134- if ( vault . name === "" || vaultData . allocations . some ( ( allocation ) => markets [ allocation . id ] === undefined ) ) {
141+ const shouldSkipVault =
142+ vault . name === "" || vaultData . allocations . some ( ( allocation ) => markets [ allocation . id ] === undefined ) ;
143+
144+ if ( shouldSkipVault ) {
135145 const urlSearchParams = new URLSearchParams ( window . location . search ) ;
136146 if ( urlSearchParams . has ( "dev" ) ) {
137147 // Detailed logging of filtering reason to help curators diagnose their situation.
138148 console . log ( `Skipping vault '${ vault . name } ':
139149- ${ vault . name === "" ? "❌" : "✅" } name is defined
140150- ${ vaultData . allocations . some ( ( allocation ) => markets [ allocation . id ] === undefined ) ? "❌" : "✅" } fetched constituent markets
151+ - ${ shouldEnforceDeadDeposit && ! hasDeadDeposits ? "❌" : "✅" } has dead deposits (${ getDeadDepositsBitmap ( vaultData ) } )
141152` ) ;
142153 }
143154 return ;
@@ -167,10 +178,11 @@ export function EarnSubPage() {
167178 } ) ;
168179
169180 vaults . push ( new AccrualVault ( vault , allocations ) ) ;
181+ hasDeadDeposits . set ( vault . address , vaultHasDeadDeposits ( vaultData ) ) ;
170182 } ) ;
171183 vaults . sort ( ( a , b ) => ( a . netApy > b . netApy ? - 1 : 1 ) ) ;
172- return vaults ;
173- } , [ vaultsData , markets ] ) ;
184+ return { vaults, hasDeadDeposits } ;
185+ } , [ shouldEnforceDeadDeposit , vaultsData , markets ] ) ;
174186
175187 // MARK: Fetch metadata for every ERC20 asset
176188 const tokenAddresses = useMemo ( ( ) => {
@@ -230,23 +242,27 @@ export function EarnSubPage() {
230242 ) as { [ vault : Address ] : bigint | undefined } ;
231243
232244 const rows = useMemo ( ( ) => {
233- return vaults . map ( ( vault ) => {
234- const { decimals, symbol } = tokens . get ( vault . asset ) ?? { decimals : undefined , symbol : undefined } ;
245+ return vaults
246+ . map ( ( vault ) => {
247+ const { decimals, symbol } = tokens . get ( vault . asset ) ?? { decimals : undefined , symbol : undefined } ;
248+ const isDeadDepositStateValid = ! shouldEnforceDeadDeposit || ( hasDeadDeposits . get ( vault . address ) ?? false ) ;
235249
236- return {
237- vault,
238- asset : {
239- address : vault . asset ,
250+ return {
251+ vault,
252+ isDeadDepositStateValid,
253+ asset : {
254+ address : vault . asset ,
255+ imageSrc : getTokenURI ( { symbol, address : vault . asset , chainId } ) ,
256+ symbol,
257+ decimals,
258+ } as Token ,
259+ curators : getDisplayableCurators ( vault , curators , chainId ) ,
260+ userShares : userShares [ vault . address ] ,
240261 imageSrc : getTokenURI ( { symbol, address : vault . asset , chainId } ) ,
241- symbol,
242- decimals,
243- } as Token ,
244- curators : getDisplayableCurators ( vault , curators , chainId ) ,
245- userShares : userShares [ vault . address ] ,
246- imageSrc : getTokenURI ( { symbol, address : vault . asset , chainId } ) ,
247- } ;
248- } ) ;
249- } , [ vaults , tokens , userShares , curators , chainId ] ) ;
262+ } ;
263+ } )
264+ . filter ( ( vault ) => vault . isDeadDepositStateValid || ( vault . userShares ?? 0n ) > 0n ) ;
265+ } , [ vaults , hasDeadDeposits , shouldEnforceDeadDeposit , tokens , userShares , curators , chainId ] ) ;
250266
251267 const userRows = rows . filter ( ( row ) => ( row . userShares ?? 0n ) > 0n ) ;
252268
0 commit comments