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 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..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 @@ -94,6 +94,96 @@ 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]; the label "XVS" matches XVS as its main asset. + const isolationGroup = extendGroup(eModeGroups[0], { + name: 'XVS', + 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 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', + 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 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', + })), + }); + + 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..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,6 +23,18 @@ export const filterEModeGroups = ({ const { assetSettings } = extendedEModeGroup; const groupNameMatches = searchMatches(extendedEModeGroup.name); + // 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() === + extendedEModeGroup.name.toLowerCase(), + ); + + if (extendedEModeGroup.isIsolated && mainAssetSettings?.isPaused && !showPausedAssets) { + return acc; + } + let hasUserAsset = false; let hasSearchMatch = false;