From ddb60659b896052006e7b9d71da8fe4d59fa5453 Mon Sep 17 00:00:00 2001 From: cuzz-venus Date: Mon, 1 Jun 2026 01:07:05 +0800 Subject: [PATCH 1/5] feat: hiden assets when hidden --- .../filterEModeGroups/__tests__/index.spec.ts | 65 +++++++++++++++++++ .../Tabs/EMode/filterEModeGroups/index.ts | 9 +++ 2 files changed, 74 insertions(+) diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts index 3d07240425..528417b41a 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts @@ -94,6 +94,71 @@ describe('filterEModeGroups', () => { expect(shownResult.map(g => g.id)).toEqual([stablecoinsGroup.id, defiGroup.id]); }); + it('hides the whole isolation group when its main asset is paused and showPausedAssets is false', () => { + // eModeGroups[0] holds [XVS, USDC, USDT]; naming it "XVS Isolated" makes XVS its main asset. + const isolationGroup = extendGroup(eModeGroups[0], { + name: 'XVS Isolated', + isIsolated: true, + assetSettings: eModeGroups[0].assetSettings.map(settings => ({ + ...settings, + isPaused: settings.vToken.underlyingToken.symbol === 'XVS', + })), + }); + + const hiddenResult = filterEModeGroups({ + pool: fakePool, + extendedEModeGroups: [isolationGroup, defiGroup], + searchValue: '', + showPausedAssets: false, + showUserAssetsOnly: false, + }); + + // Whole group gone, only the unaffected group remains. + expect(hiddenResult.map(g => g.id)).toEqual([defiGroup.id]); + + // Even a search matching a sibling asset keeps the group hidden. + const searchResult = filterEModeGroups({ + pool: fakePool, + extendedEModeGroups: [isolationGroup, defiGroup], + searchValue: 'usdc', + showPausedAssets: false, + showUserAssetsOnly: false, + }); + + expect(searchResult.map(g => g.id)).toEqual([]); + + // Turning the toggle on brings the whole group back. + const shownResult = filterEModeGroups({ + pool: fakePool, + extendedEModeGroups: [isolationGroup, defiGroup], + searchValue: '', + showPausedAssets: true, + showUserAssetsOnly: false, + }); + + expect(shownResult.map(g => g.id)).toContain(isolationGroup.id); + }); + + it('does not hide the group when the label prefix matches no asset, even if an asset is paused', () => { + // "Stablecoins" has no leading asset symbol, so no main asset can be resolved. + const groupWithPausedAsset = extendGroup(eModeGroups[0], { + assetSettings: eModeGroups[0].assetSettings.map(settings => ({ + ...settings, + isPaused: settings.vToken.underlyingToken.symbol === 'XVS', + })), + }); + + const result = filterEModeGroups({ + pool: fakePool, + extendedEModeGroups: [groupWithPausedAsset], + searchValue: '', + showPausedAssets: false, + showUserAssetsOnly: false, + }); + + expect(result.map(g => g.id)).toEqual([groupWithPausedAsset.id]); + }); + it('filters to user assets only when showUserAssetsOnly is true', () => { const nonUserAsset = makeAsset(defiGroup.assetSettings[0].vToken.address, { userSupplyBalanceCents: new BigNumber(0), diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts index 83f74969df..9b31aff1a5 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts @@ -23,6 +23,15 @@ export const filterEModeGroups = ({ const { assetSettings } = extendedEModeGroup; const groupNameMatches = searchMatches(extendedEModeGroup.name); + const mainAssetSymbol = extendedEModeGroup.name.split(' ')[0]?.toLowerCase(); + const mainAssetSettings = assetSettings.find( + settings => settings.vToken.underlyingToken.symbol.toLowerCase() === mainAssetSymbol, + ); + + if (mainAssetSettings?.isPaused && !showPausedAssets) { + return acc; + } + let hasUserAsset = false; let hasSearchMatch = false; From 67d249df8ff6d9b32244c3315b79ea18e9cd1037 Mon Sep 17 00:00:00 2001 From: cuzz-venus Date: Mon, 1 Jun 2026 01:11:58 +0800 Subject: [PATCH 2/5] feat: hiden assets when hidden --- .changeset/cyan-needles-trade.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cyan-needles-trade.md diff --git a/.changeset/cyan-needles-trade.md b/.changeset/cyan-needles-trade.md new file mode 100644 index 0000000000..80f183f270 --- /dev/null +++ b/.changeset/cyan-needles-trade.md @@ -0,0 +1,5 @@ +--- +"@venusprotocol/evm": patch +--- + +feat: hidden assets if assets delist From 6e6fd7e09ee208690f9dc182f066deb8c485f16c Mon Sep 17 00:00:00 2001 From: cuzz-venus Date: Mon, 1 Jun 2026 11:30:30 +0800 Subject: [PATCH 3/5] fix: guard isolation group hide with isIsolated Co-Authored-By: Claude Opus 4.8 (1M context) --- .../filterEModeGroups/__tests__/index.spec.ts | 23 +++++++++++++++++++ .../Tabs/EMode/filterEModeGroups/index.ts | 8 ++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts index 528417b41a..f2f460188c 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts @@ -139,6 +139,29 @@ describe('filterEModeGroups', () => { expect(shownResult.map(g => g.id)).toContain(isolationGroup.id); }); + it('does not hide a non-isolated group even when its label prefix matches a paused asset', () => { + // Same XVS-paused setup, but the group is a regular (non-isolated) e-mode group, + // so the whole-group hide rule must not apply. + const nonIsolatedGroup = extendGroup(eModeGroups[0], { + name: 'XVS something', + isIsolated: false, + assetSettings: eModeGroups[0].assetSettings.map(settings => ({ + ...settings, + isPaused: settings.vToken.underlyingToken.symbol === 'XVS', + })), + }); + + const result = filterEModeGroups({ + pool: fakePool, + extendedEModeGroups: [nonIsolatedGroup], + searchValue: '', + showPausedAssets: false, + showUserAssetsOnly: false, + }); + + expect(result.map(g => g.id)).toEqual([nonIsolatedGroup.id]); + }); + it('does not hide the group when the label prefix matches no asset, even if an asset is paused', () => { // "Stablecoins" has no leading asset symbol, so no main asset can be resolved. const groupWithPausedAsset = extendGroup(eModeGroups[0], { diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts index 9b31aff1a5..8030ebffa4 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts @@ -23,12 +23,18 @@ export const filterEModeGroups = ({ const { assetSettings } = extendedEModeGroup; const groupNameMatches = searchMatches(extendedEModeGroup.name); + // An isolation group is anchored by a "main asset", identified by the group + // label prefix (e.g. "FIL Isolated" -> "FIL"). When that main asset is + // delisted/paused, the whole isolation group should be hidden by default and + // only surface when the "Paused assets" toggle is on, so users keep no entry + // point into an effectively dead pool. This only applies to isolation groups + // — regular e-mode groups keep the per-asset paused filtering below. const mainAssetSymbol = extendedEModeGroup.name.split(' ')[0]?.toLowerCase(); const mainAssetSettings = assetSettings.find( settings => settings.vToken.underlyingToken.symbol.toLowerCase() === mainAssetSymbol, ); - if (mainAssetSettings?.isPaused && !showPausedAssets) { + if (extendedEModeGroup.isIsolated && mainAssetSettings?.isPaused && !showPausedAssets) { return acc; } From 31d6397e6f39ea0f2e064daa54eb9072db63ad8d Mon Sep 17 00:00:00 2001 From: cuzz-venus Date: Mon, 1 Jun 2026 11:31:43 +0800 Subject: [PATCH 4/5] chore: trim comment Co-Authored-By: Claude Opus 4.8 (1M context) --- .../pages/Markets/Tabs/EMode/filterEModeGroups/index.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts index 8030ebffa4..e161f6587c 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts @@ -23,12 +23,8 @@ export const filterEModeGroups = ({ const { assetSettings } = extendedEModeGroup; const groupNameMatches = searchMatches(extendedEModeGroup.name); - // An isolation group is anchored by a "main asset", identified by the group - // label prefix (e.g. "FIL Isolated" -> "FIL"). When that main asset is - // delisted/paused, the whole isolation group should be hidden by default and - // only surface when the "Paused assets" toggle is on, so users keep no entry - // point into an effectively dead pool. This only applies to isolation groups - // — regular e-mode groups keep the per-asset paused filtering below. + // Identify the isolation group's "main asset" from its label prefix (e.g. "FIL Isolated" -> "FIL"); + // when that asset is paused, hide the whole group unless "Paused assets" is on. const mainAssetSymbol = extendedEModeGroup.name.split(' ')[0]?.toLowerCase(); const mainAssetSettings = assetSettings.find( settings => settings.vToken.underlyingToken.symbol.toLowerCase() === mainAssetSymbol, From f8239514535223e0ce069d1922406507bfd25130 Mon Sep 17 00:00:00 2001 From: cuzz-venus Date: Mon, 1 Jun 2026 11:39:18 +0800 Subject: [PATCH 5/5] refactor: match isolation group label to main asset symbol Co-Authored-By: Claude Opus 4.8 (1M context) --- .../filterEModeGroups/__tests__/index.spec.ts | 18 ++++++++++-------- .../Tabs/EMode/filterEModeGroups/index.ts | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts index f2f460188c..2b817ee655 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/__tests__/index.spec.ts @@ -95,9 +95,9 @@ describe('filterEModeGroups', () => { }); it('hides the whole isolation group when its main asset is paused and showPausedAssets is false', () => { - // eModeGroups[0] holds [XVS, USDC, USDT]; naming it "XVS Isolated" makes XVS its main asset. + // eModeGroups[0] holds [XVS, USDC, USDT]; the label "XVS" matches XVS as its main asset. const isolationGroup = extendGroup(eModeGroups[0], { - name: 'XVS Isolated', + name: 'XVS', isIsolated: true, assetSettings: eModeGroups[0].assetSettings.map(settings => ({ ...settings, @@ -139,11 +139,11 @@ describe('filterEModeGroups', () => { expect(shownResult.map(g => g.id)).toContain(isolationGroup.id); }); - it('does not hide a non-isolated group even when its label prefix matches a paused asset', () => { - // Same XVS-paused setup, but the group is a regular (non-isolated) e-mode group, - // so the whole-group hide rule must not apply. + it('does not hide a non-isolated group even when its label matches a paused asset', () => { + // Same XVS-paused setup with a matching "XVS" label, but the group is a regular + // (non-isolated) e-mode group, so the whole-group hide rule must not apply. const nonIsolatedGroup = extendGroup(eModeGroups[0], { - name: 'XVS something', + name: 'XVS', isIsolated: false, assetSettings: eModeGroups[0].assetSettings.map(settings => ({ ...settings, @@ -162,9 +162,11 @@ describe('filterEModeGroups', () => { expect(result.map(g => g.id)).toEqual([nonIsolatedGroup.id]); }); - it('does not hide the group when the label prefix matches no asset, even if an asset is paused', () => { - // "Stablecoins" has no leading asset symbol, so no main asset can be resolved. + it('does not hide the group when the label matches no asset, even if an asset is paused', () => { + // "Stablecoins" matches no asset symbol, so no main asset can be resolved. const groupWithPausedAsset = extendGroup(eModeGroups[0], { + name: 'Stablecoins', + isIsolated: true, assetSettings: eModeGroups[0].assetSettings.map(settings => ({ ...settings, isPaused: settings.vToken.underlyingToken.symbol === 'XVS', diff --git a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts index e161f6587c..2d26d3ad42 100644 --- a/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts +++ b/apps/evm/src/pages/Markets/Tabs/EMode/filterEModeGroups/index.ts @@ -23,11 +23,12 @@ export const filterEModeGroups = ({ const { assetSettings } = extendedEModeGroup; const groupNameMatches = searchMatches(extendedEModeGroup.name); - // Identify the isolation group's "main asset" from its label prefix (e.g. "FIL Isolated" -> "FIL"); - // when that asset is paused, hide the whole group unless "Paused assets" is on. - const mainAssetSymbol = extendedEModeGroup.name.split(' ')[0]?.toLowerCase(); + // An isolation group's label is its "main asset" symbol (e.g. "FIL"); when that asset + // is paused, hide the whole group unless "Paused assets" is on. const mainAssetSettings = assetSettings.find( - settings => settings.vToken.underlyingToken.symbol.toLowerCase() === mainAssetSymbol, + settings => + settings.vToken.underlyingToken.symbol.toLowerCase() === + extendedEModeGroup.name.toLowerCase(), ); if (extendedEModeGroup.isIsolated && mainAssetSettings?.isPaused && !showPausedAssets) {