Repository: MetaMask/metamask-extension
Pull request #32896: feat: defi missing items
Author: login: jpsains
Labels: name: team-assets
name: release-12.20.0
description: Issue or pull request that will be included in release 12.20.0
Created: 2025-05-14T09:14:54Z | Merged: 2025-05-21T08:52:13Z

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Updates and fixes to defi tabs and defi details page

DeFi Tab
* New error message 
* New empty state
* Add Token Symbol Component 

DeFi Details Page
* Protocol badge added

Other bits:
* Increase test coverage 
* Create generic token cell

<!--
Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/32896?quickstart=1)

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to the defi tab
2. View updated defi cell with new symbol component
3. Click into the defi details tab 
4. View protocol icon 

## **Screenshots/Recordings**

https://www.loom.com/share/9a455f842b7d4acb86798b934eb84b66?sid=8d1a2bc8-2039-4fc1-a925-41375878c84e

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable
- [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.



Diff:
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 4d811abaf13e..3226fb3cc6cf 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1637,10 +1637,10 @@
     "message": "DeFi"
   },
   "defiTabErrorContent": {
-    "message": "Your funds are safe, try to visit this page again later."
+    "message": "Try visiting again later."
   },
   "defiTabErrorTitle": {
-    "message": "Oops! Something went wrong."
+    "message": "We could not load this page."
   },
   "delete": {
     "message": "Delete"
@@ -3497,6 +3497,9 @@
   "noConversionRateAvailable": {
     "message": "No conversion rate available"
   },
+  "noDeFiPositions": {
+    "message": "No positions yet"
+  },
   "noDomainResolution": {
     "message": "No resolution for domain provided."
   },
@@ -3886,6 +3889,9 @@
   "onekey": {
     "message": "OneKey"
   },
+  "only": {
+    "message": "only"
+  },
   "onlyConnectTrust": {
     "message": "Only connect with sites you trust. $1",
     "description": "Text displayed above the buttons for connection confirmation. $1 is the link to the learn more web page."
@@ -3916,10 +3922,16 @@
   "osTheme": {
     "message": "System"
   },
+  "other": {
+    "message": "other"
+  },
   "otherSnaps": {
     "message": "other snaps",
     "description": "Used in the 'permission_rpc' message."
   },
+  "others": {
+    "message": "others"
+  },
   "outdatedBrowserNotification": {
     "message": "Your browser is out of date. If you don't update your browser, you won't be able to get security patches and new features from MetaMask."
   },
@@ -5467,7 +5479,7 @@
     "message": "Something's gone wrong. Try reloading the page."
   },
   "somethingWentWrong": {
-    "message": "Oops! Something went wrong."
+    "message": "We could not load this page."
   },
   "sortBy": {
     "message": "Sort by"
@@ -5657,6 +5669,9 @@
   "standardAccountLabel": {
     "message": "Standard Account"
   },
+  "startEarning": {
+    "message": "Start earning"
+  },
   "stateCorruptionDetectedErrorMessage": {
     "message": "MetaMask's state file is damaged or missing. The files are possibly recoverable, so don't uninstall the MetaMask extension!"
   },
diff --git a/app/_locales/en_GB/messages.json b/app/_locales/en_GB/messages.json
index 4d811abaf13e..3226fb3cc6cf 100644
--- a/app/_locales/en_GB/messages.json
+++ b/app/_locales/en_GB/messages.json
@@ -1637,10 +1637,10 @@
     "message": "DeFi"
   },
   "defiTabErrorContent": {
-    "message": "Your funds are safe, try to visit this page again later."
+    "message": "Try visiting again later."
   },
   "defiTabErrorTitle": {
-    "message": "Oops! Something went wrong."
+    "message": "We could not load this page."
   },
   "delete": {
     "message": "Delete"
@@ -3497,6 +3497,9 @@
   "noConversionRateAvailable": {
     "message": "No conversion rate available"
   },
+  "noDeFiPositions": {
+    "message": "No positions yet"
+  },
   "noDomainResolution": {
     "message": "No resolution for domain provided."
   },
@@ -3886,6 +3889,9 @@
   "onekey": {
     "message": "OneKey"
   },
+  "only": {
+    "message": "only"
+  },
   "onlyConnectTrust": {
     "message": "Only connect with sites you trust. $1",
     "description": "Text displayed above the buttons for connection confirmation. $1 is the link to the learn more web page."
@@ -3916,10 +3922,16 @@
   "osTheme": {
     "message": "System"
   },
+  "other": {
+    "message": "other"
+  },
   "otherSnaps": {
     "message": "other snaps",
     "description": "Used in the 'permission_rpc' message."
   },
+  "others": {
+    "message": "others"
+  },
   "outdatedBrowserNotification": {
     "message": "Your browser is out of date. If you don't update your browser, you won't be able to get security patches and new features from MetaMask."
   },
@@ -5467,7 +5479,7 @@
     "message": "Something's gone wrong. Try reloading the page."
   },
   "somethingWentWrong": {
-    "message": "Oops! Something went wrong."
+    "message": "We could not load this page."
   },
   "sortBy": {
     "message": "Sort by"
@@ -5657,6 +5669,9 @@
   "standardAccountLabel": {
     "message": "Standard Account"
   },
+  "startEarning": {
+    "message": "Start earning"
+  },
   "stateCorruptionDetectedErrorMessage": {
     "message": "MetaMask's state file is damaged or missing. The files are possibly recoverable, so don't uninstall the MetaMask extension!"
   },
diff --git a/test/e2e/page-objects/pages/defi-tab.ts b/test/e2e/page-objects/pages/defi-tab.ts
index 66d12b2534ea..36973bc98a82 100644
--- a/test/e2e/page-objects/pages/defi-tab.ts
+++ b/test/e2e/page-objects/pages/defi-tab.ts
@@ -1,9 +1,46 @@
 import { Driver } from '../../webdriver/driver';
-import TokenList from './token-list';
 
-class DeFiTab extends TokenList {
+class DeFiToken {
   protected readonly driver: Driver;
 
+  protected readonly tokenListItemTokenName =
+    '[data-testid="multichain-token-list-item-token-name"]';
+
+  protected readonly tokenListItemSecondaryValue =
+    '[data-testid="defi-list-market-value"]';
+
+  constructor(driver: Driver) {
+    this.driver = driver;
+  }
+
+  async check_tokenMarketValue(tokenListItemSecondaryValue: string) {
+    console.log(
+      'Check if token market value is displayed on token list item',
+      tokenListItemSecondaryValue,
+    );
+    await this.driver.waitForSelector({
+      css: this.tokenListItemSecondaryValue,
+      text: tokenListItemSecondaryValue,
+    });
+  }
+
+  async check_tokenName(tokenName: string) {
+    console.log(
+      'Check if token name is displayed on token list item',
+      tokenName,
+    );
+    await this.driver.waitForSelector({
+      css: this.tokenListItemTokenName,
+      text: tokenName,
+    });
+  }
+}
+
+class DeFiTab {
+  protected readonly driver: Driver;
+
+  readonly defiTabCells: DeFiToken;
+
   private readonly allNetworksOption =
     '[data-testid="network-filter-all__button"]';
 
@@ -12,15 +49,17 @@ class DeFiTab extends TokenList {
   private readonly popularNetworks =
     '[data-testid="network-filter-all__button"]';
 
-  private readonly stakeLink = '[data-testid="staking-entrypoint-0x1"]';
+  private readonly stakeLink = '[data-testid="defi-tab-start-earning-link"]';
 
   private readonly groupIcon = '[data-testid="avatar-group"]';
 
   private readonly errorMessage = '[data-testid="defi-tab-error-message"]';
 
+  private readonly noPositionsMessage = '[data-testid="defi-tab-no-positions"]';
+
   constructor(driver: Driver) {
-    super(driver);
     this.driver = driver;
+    this.defiTabCells = new DeFiToken(driver);
   }
 
   async openNetworksFilterAndClickPopularNetworks(): Promise<void> {
@@ -50,6 +89,11 @@ class DeFiTab extends TokenList {
     await this.driver.waitForSelector(this.errorMessage);
   }
 
+  async check_noPositionsMessageIsDisplayed(): Promise<void> {
+    console.log('Check that no positions message is displayed');
+    await this.driver.waitForSelector(this.noPositionsMessage);
+  }
+
   async check_groupIconIsDisplayed(): Promise<void> {
     console.log('Check that group icon is displayed');
     await this.driver.waitForSelector(this.groupIcon);
diff --git a/test/e2e/tests/tokens/defi/view-defi-details.spec.ts b/test/e2e/tests/tokens/defi/view-defi-details.spec.ts
index c94be4d2af1f..d681814247ce 100644
--- a/test/e2e/tests/tokens/defi/view-defi-details.spec.ts
+++ b/test/e2e/tests/tokens/defi/view-defi-details.spec.ts
@@ -33,23 +33,23 @@ describe('View DeFi details', function () {
         const defiTab = new DeFiTab(driver);
 
         // Empty state
-        await defiTab.check_tokenName('Start earning');
+        await defiTab.check_noPositionsMessageIsDisplayed();
         await defiTab.waitForStakeLink();
 
         // check ethereum positions present
         await switchToNetworkFlow(driver, 'Ethereum Mainnet');
         await defiTab.check_groupIconIsDisplayed();
-        await defiTab.check_tokenName('Aave V3');
-        await defiTab.check_tokenMarketValue('$14.74');
-        await defiTab.check_tokenName('Aave V2');
-        await defiTab.check_tokenMarketValue('$0.33');
+        await defiTab.defiTabCells.check_tokenName('Aave V3');
+        await defiTab.defiTabCells.check_tokenMarketValue('$14.74');
+        await defiTab.defiTabCells.check_tokenName('Aave V2');
+        await defiTab.defiTabCells.check_tokenMarketValue('$0.33');
 
         // switch popular networks and check linea positions present
         await defiTab.openNetworksFilterAndClickPopularNetworks();
-        await defiTab.check_tokenName('UniswapV3');
-        await defiTab.check_tokenMarketValue('$8.48');
-        await defiTab.check_tokenName('UniswapV2');
-        await defiTab.check_tokenMarketValue('$4.24');
+        await defiTab.defiTabCells.check_tokenName('UniswapV3');
+        await defiTab.defiTabCells.check_tokenMarketValue('$8.48');
+        await defiTab.defiTabCells.check_tokenName('UniswapV2');
+        await defiTab.defiTabCells.check_tokenMarketValue('$4.24');
 
         // click detils page for AaveV3
         await defiTab.clickIntoAaveV3DetailsPage();
diff --git a/test/e2e/tests/tokens/defi/defi-positions-api-failure.spec.ts b/test/e2e/tests/tokens/defi/view-defi-error-message.spec.ts
similarity index 95%
rename from test/e2e/tests/tokens/defi/defi-positions-api-failure.spec.ts
rename to test/e2e/tests/tokens/defi/view-defi-error-message.spec.ts
index 800cc10ac02b..f4d03bc73dd7 100644
--- a/test/e2e/tests/tokens/defi/defi-positions-api-failure.spec.ts
+++ b/test/e2e/tests/tokens/defi/view-defi-error-message.spec.ts
@@ -6,7 +6,7 @@ import { loginWithBalanceValidation } from '../../../page-objects/flows/login.fl
 import { Driver } from '../../../webdriver/driver';
 import { mockDefiPositionsFailure } from '../../confirmations/helpers';
 
-describe('Check DeFi error state', function () {
+describe('View DeFi error state', function () {
   it('user should be able to view error message', async function () {
     await withFixtures(
       {
diff --git a/test/e2e/tests/tokens/defi/no-defi-positions.spec.ts b/test/e2e/tests/tokens/defi/view-defi-no-positions-message.spec.ts
similarity index 92%
rename from test/e2e/tests/tokens/defi/no-defi-positions.spec.ts
rename to test/e2e/tests/tokens/defi/view-defi-no-positions-message.spec.ts
index 330ae5b43d56..5451b81b7d50 100644
--- a/test/e2e/tests/tokens/defi/no-defi-positions.spec.ts
+++ b/test/e2e/tests/tokens/defi/view-defi-no-positions-message.spec.ts
@@ -33,7 +33,7 @@ describe('Check DeFi empty state when no defi positions', function () {
         const defiTab = new DeFiTab(driver);
 
         // Empty state
-        await defiTab.check_tokenName('Start earning');
+        await defiTab.check_noPositionsMessageIsDisplayed();
         await defiTab.waitForStakeLink();
 
         // switch network
@@ -41,7 +41,7 @@ describe('Check DeFi empty state when no defi positions', function () {
 
         // check emtry state still present
         await defiTab.openNetworksFilterAndClickPopularNetworks();
-        await defiTab.check_tokenName('Start earning');
+        await defiTab.check_noPositionsMessageIsDisplayed();
       },
     );
   });
diff --git a/ui/components/app/assets/token-cell/cells/token-cell-badge.tsx b/ui/components/app/assets/asset-list/cells/asset-cell-badge.tsx
similarity index 60%
rename from ui/components/app/assets/token-cell/cells/token-cell-badge.tsx
rename to ui/components/app/assets/asset-list/cells/asset-cell-badge.tsx
index b842131289c4..d1a079a79fe9 100644
--- a/ui/components/app/assets/token-cell/cells/token-cell-badge.tsx
+++ b/ui/components/app/assets/asset-list/cells/asset-cell-badge.tsx
@@ -14,26 +14,30 @@ import {
   getMultichainIsEvm,
 } from '../../../../../selectors/multichain';
 import { getNetworkConfigurationsByChainId } from '../../../../../../shared/modules/selectors/networks';
-import { TokenFiatDisplayInfo } from '../../types';
 
-type TokenCellBadgeProps = {
-  token: TokenFiatDisplayInfo;
+type AssetCellBadgeProps = {
+  chainId: `0x${string}` | `${string}:${string}`;
+  isNative?: boolean;
+  tokenImage: string;
+  symbol: string;
 };
 
-export const TokenCellBadge = React.memo(
-  ({ token }: TokenCellBadgeProps) => {
+export const AssetCellBadge = React.memo(
+  ({ chainId, isNative, tokenImage, symbol }: AssetCellBadgeProps) => {
     const isEvm = useSelector(getMultichainIsEvm);
     const allNetworks = useSelector(getNetworkConfigurationsByChainId);
 
+    const avatarTokenSrc =
+      isEvm && isNative ? getNativeCurrencyForChain(chainId) : tokenImage;
+    const badgeWrapperSrc = getImageForChainId(chainId) ?? undefined;
+
     return (
       <BadgeWrapper
         badge={
           <AvatarNetwork
             size={AvatarNetworkSize.Xs}
-            name={allNetworks?.[token.chainId as Hex]?.name}
-            // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31880
-            // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
-            src={getImageForChainId(token.chainId) || undefined}
+            name={allNetworks?.[chainId as Hex]?.name}
+            src={badgeWrapperSrc}
             backgroundColor={BackgroundColor.backgroundMuted}
             borderWidth={2}
           />
@@ -42,16 +46,12 @@ export const TokenCellBadge = React.memo(
         style={{ alignSelf: 'center' }}
       >
         <AvatarToken
-          name={token.symbol}
+          name={symbol}
           backgroundColor={BackgroundColor.backgroundMuted}
-          src={
-            isEvm && token.isNative
-              ? getNativeCurrencyForChain(token.chainId)
-              : token.tokenImage
-          }
+          src={avatarTokenSrc}
         />
       </BadgeWrapper>
     );
   },
-  (prevProps, nextProps) => prevProps.token.chainId === nextProps.token.chainId,
+  (prevProps, nextProps) => prevProps.chainId === nextProps.chainId,
 );
diff --git a/ui/components/app/assets/asset-list/cells/asset-title.tsx b/ui/components/app/assets/asset-list/cells/asset-title.tsx
new file mode 100644
index 000000000000..534f5bb4a079
--- /dev/null
+++ b/ui/components/app/assets/asset-list/cells/asset-title.tsx
@@ -0,0 +1,54 @@
+import React from 'react';
+import {
+  Display,
+  FontWeight,
+  TextVariant,
+} from '../../../../../helpers/constants/design-system';
+import { Text } from '../../../../component-library';
+import {
+  TranslateFunction,
+  networkTitleOverrides,
+} from '../../util/networkTitleOverrides';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+import Tooltip from '../../../../ui/tooltip';
+
+type AssetCellTitleProps = {
+  title: string;
+};
+
+export const AssetCellTitle = ({ title }: AssetCellTitleProps) => {
+  const t = useI18nContext();
+
+  if (title && title.length > 12) {
+    return (
+      <Tooltip
+        position="bottom"
+        html={title}
+        wrapperClassName="token-cell-title--ellipsis"
+      >
+        <Text
+          as="span"
+          data-testid="multichain-token-list-item-token-name"
+          fontWeight={FontWeight.Medium}
+          variant={TextVariant.bodyMd}
+          display={Display.Block}
+          ellipsis
+        >
+          {networkTitleOverrides(t as TranslateFunction, { title })}
+        </Text>
+      </Tooltip>
+    );
+  }
+
+  // non-ellipsized title
+  return (
+    <Text
+      fontWeight={FontWeight.Medium}
+      variant={TextVariant.bodyMd}
+      ellipsis
+      data-testid="multichain-token-list-item-token-name"
+    >
+      {networkTitleOverrides(t as TranslateFunction, { title })}
+    </Text>
+  );
+};
diff --git a/ui/components/app/assets/asset-list/cells/generic-asset-cell-layout.tsx b/ui/components/app/assets/asset-list/cells/generic-asset-cell-layout.tsx
new file mode 100644
index 000000000000..bae27a8edd14
--- /dev/null
+++ b/ui/components/app/assets/asset-list/cells/generic-asset-cell-layout.tsx
@@ -0,0 +1,96 @@
+import React, { ReactNode, useState } from 'react';
+import { Box } from '../../../../component-library';
+import {
+  Display,
+  FlexDirection,
+  BlockSize,
+  JustifyContent,
+} from '../../../../../helpers/constants/design-system';
+
+type GenericAssetCellLayoutProps = {
+  onClick?: () => void;
+  disableHover?: boolean;
+  badge: ReactNode;
+  headerLeftDisplay: ReactNode;
+  headerRightDisplay: ReactNode;
+  footerLeftDisplay: ReactNode;
+  footerRightDisplay: ReactNode;
+};
+
+export default function GenericAssetCellLayout({
+  onClick,
+  disableHover = false,
+  badge,
+  headerLeftDisplay,
+  headerRightDisplay,
+  footerLeftDisplay,
+  footerRightDisplay,
+}: GenericAssetCellLayoutProps) {
+  const [isHovered, setIsHovered] = useState(false);
+
+  return (
+    <Box
+      display={Display.Flex}
+      flexDirection={FlexDirection.Row}
+      width={BlockSize.Full}
+      height={BlockSize.Full}
+      gap={4}
+    >
+      <Box
+        as="a"
+        onClick={(e?: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
+          e?.preventDefault();
+          if (onClick) {
+            onClick();
+          }
+        }}
+        display={Display.Flex}
+        flexDirection={FlexDirection.Row}
+        paddingTop={2}
+        paddingBottom={2}
+        paddingLeft={4}
+        paddingRight={4}
+        width={BlockSize.Full}
+        style={{
+          height: 62,
+          cursor: onClick ? 'pointer' : 'auto',
+          backgroundColor:
+            !disableHover && isHovered
+              ? 'var(--color-background-default-hover)'
+              : 'transparent',
+          transition: 'background-color 0.2s ease-in-out',
+        }}
+        onMouseEnter={() => !disableHover && setIsHovered(true)}
+        onMouseLeave={() => !disableHover && setIsHovered(false)}
+        data-testid="multichain-token-list-button"
+      >
+        {badge}
+        <Box
+          display={Display.Flex}
+          flexDirection={FlexDirection.Column}
+          width={BlockSize.Full}
+          style={{ flexGrow: 1, overflow: 'hidden' }}
+          justifyContent={JustifyContent.center}
+        >
+          <Box
+            display={Display.Flex}
+            flexDirection={FlexDirection.Row}
+            justifyContent={JustifyContent.spaceBetween}
+          >
+            {headerLeftDisplay}
+            {headerRightDisplay}
+          </Box>
+
+          <Box
+            display={Display.Flex}
+            flexDirection={FlexDirection.Row}
+            justifyContent={JustifyContent.spaceBetween}
+          >
+            {footerLeftDisplay}
+            {footerRightDisplay}
+          </Box>
+        </Box>
+      </Box>
+    </Box>
+  );
+}
diff --git a/ui/components/app/assets/defi-list/cells/defi-empty-state.tsx b/ui/components/app/assets/defi-list/cells/defi-empty-state.tsx
new file mode 100644
index 000000000000..67bf7e9e7a87
--- /dev/null
+++ b/ui/components/app/assets/defi-list/cells/defi-empty-state.tsx
@@ -0,0 +1,57 @@
+import React from 'react';
+import {
+  Box,
+  ButtonLink,
+  ButtonLinkSize,
+  Text,
+} from '../../../../component-library';
+import {
+  Display,
+  JustifyContent,
+  AlignItems,
+  FlexDirection,
+  TextColor,
+  TextVariant,
+  TextAlign,
+} from '../../../../../helpers/constants/design-system';
+import { getPortfolioUrl } from '../../../../../helpers/utils/portfolio';
+
+export function DeFiEmptyStateMessage({
+  primaryText,
+  secondaryText,
+}: {
+  primaryText: string;
+  secondaryText: string;
+}) {
+  return (
+    <Box
+      paddingTop={6}
+      marginTop={12}
+      marginBottom={12}
+      display={Display.Flex}
+      justifyContent={JustifyContent.center}
+      alignItems={AlignItems.center}
+      flexDirection={FlexDirection.Column}
+      className="nfts-tab__link"
+    >
+      <Text
+        color={TextColor.textAlternative}
+        variant={TextVariant.bodyMdMedium}
+        textAlign={TextAlign.Center}
+        data-testid="defi-tab-no-positions"
+      >
+        {primaryText}
+      </Text>
+      {
+        <ButtonLink
+          size={ButtonLinkSize.Md}
+          href={getPortfolioUrl('stake', 'ext_stake_button')}
+          externalLink
+          data-testid="defi-tab-start-earning-link"
+        >
+          {secondaryText}
+        </ButtonLink>
+      }
+    </Box>
+  );
+}
diff --git a/ui/components/app/assets/defi-list/cells/defi-error-message.tsx b/ui/components/app/assets/defi-list/cells/defi-error-message.tsx
new file mode 100644
index 000000000000..f005f5201858
--- /dev/null
+++ b/ui/components/app/assets/defi-list/cells/defi-error-message.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import {
+  BlockSize,
+  Display,
+  JustifyContent,
+  AlignItems,
+  FlexDirection,
+  TextVariant,
+  TextAlign,
+} from '../../../../../helpers/constants/design-system';
+import {
+  Box,
+  Icon,
+  IconName,
+  IconSize,
+  Text,
+} from '../../../../component-library';
+
+export function DeFiErrorMessage({
+  title,
+  text,
+}: {
+  title: string;
+  text: string;
+}) {
+  return (
+    <Box
+      height={BlockSize.Full}
+      width={BlockSize.Full}
+      display={Display.Flex}
+      justifyContent={JustifyContent.center}
+      alignItems={AlignItems.center}
+      flexDirection={FlexDirection.Column}
+      gap={2}
+      data-testid="defi-tab-error-message"
+    >
+      <Icon name={IconName.Warning} size={IconSize.Xl} />
+      <Text variant={TextVariant.headingSm}>{title}</Text>
+      <Text variant={TextVariant.bodyMd} textAlign={TextAlign.Center}>
+        {text}
+      </Text>
+    </Box>
+  );
+}
diff --git a/ui/components/app/assets/defi-list/cells/defi-grouped-symbol-cell.test.tsx b/ui/components/app/assets/defi-list/cells/defi-grouped-symbol-cell.test.tsx
new file mode 100644
index 000000000000..ea1d2dabcffe
--- /dev/null
+++ b/ui/components/app/assets/defi-list/cells/defi-grouped-symbol-cell.test.tsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import { render } from '@testing-library/react';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+import { DeFiSymbolGroup } from './defi-grouped-symbol-cell';
+
+jest.mock('../../../../../hooks/useI18nContext', () => ({
+  useI18nContext: jest.fn(),
+}));
+
+describe('DeFiSymbolGroup', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('renders correctly with one symbol', () => {
+    (useI18nContext as jest.Mock).mockReturnValue((key: string) =>
+      key === 'only' ? 'only' : '',
+    );
+    const { getByTestId } = render(
+      <DeFiSymbolGroup symbols={['ETH']} privacyMode={false} />,
+    );
+
+    const element = getByTestId('defi-list-symbol-group');
+    expect(element).toHaveTextContent('ETH only');
+  });
+
+  it('renders correctly with two symbols', () => {
+    (useI18nContext as jest.Mock).mockReturnValue((key: string) =>
+      key === 'other' ? 'other' : '',
+    );
+    const { getByTestId } = render(
+      <DeFiSymbolGroup symbols={['ETH', 'BTC']} privacyMode={false} />,
+    );
+
+    const element = getByTestId('defi-list-symbol-group');
+    expect(element).toHaveTextContent('ETH +1 other');
+  });
+
+  it('renders correctly with more than two symbols', () => {
+    (useI18nContext as jest.Mock).mockReturnValue((key: string) =>
+      key === 'others' ? 'others' : '',
+    );
+    const { getByTestId } = render(
+      <DeFiSymbolGroup symbols={['ETH', 'BTC', 'DAI']} privacyMode={false} />,
+    );
+
+    const element = getByTestId('defi-list-symbol-group');
+    expect(element).toHaveTextContent('ETH +2 others');
+  });
+
+  it('hides text when privacyMode is enabled', () => {
+    (useI18nContext as jest.Mock).mockReturnValue(() => '');
+    const { getByTestId } = render(
+      <DeFiSymbolGroup symbols={['ETH']} privacyMode={true} />,
+    );
+
+    const element = getByTestId('defi-list-symbol-group');
+    expect(element).toHaveTextContent('•••••••••');
+  });
+});
diff --git a/ui/components/app/assets/defi-list/cells/defi-grouped-symbol-cell.tsx b/ui/components/app/assets/defi-list/cells/defi-grouped-symbol-cell.tsx
new file mode 100644
index 000000000000..483ebef7a7fe
--- /dev/null
+++ b/ui/components/app/assets/defi-list/cells/defi-grouped-symbol-cell.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import {
+  TextVariant,
+  TextAlign,
+} from '../../../../../helpers/constants/design-system';
+import {
+  SensitiveText,
+  SensitiveTextLength,
+} from '../../../../component-library';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+
+export function DeFiSymbolGroup({
+  symbols,
+  privacyMode = false,
+}: {
+  symbols: string[];
+  privacyMode?: boolean;
+}) {
+  const t = useI18nContext();
+
+  const buildSymbolGroup = (defiSymbols: string[]): string => {
+    if (defiSymbols.length === 1) {
+      return `${defiSymbols[0]} ${t('only')}`;
+    }
+
+    if (defiSymbols.length === 2) {
+      return `${defiSymbols[0]} +${defiSymbols.length - 1} ${t('other')}`;
+    }
+
+    if (defiSymbols.length > 2) {
+      return `${defiSymbols[0]} +${defiSymbols.length - 1} ${t('others')}`;
+    }
+    return '';
+  };
+
+  const symbolGroup = buildSymbolGroup(symbols);
+
+  return (
+    <SensitiveText
+      variant={TextVariant.bodyMd}
+      textAlign={TextAlign.End}
+      data-testid="defi-list-symbol-group"
+      isHidden={privacyMode}
+      length={SensitiveTextLength.Medium}
+    >
+      {symbolGroup}
+    </SensitiveText>
+  );
+}
diff --git a/ui/components/app/assets/defi-list/cells/defi-protocol-cell.tsx b/ui/components/app/assets/defi-list/cells/defi-protocol-cell.tsx
new file mode 100644
index 000000000000..6c4edc965778
--- /dev/null
+++ b/ui/components/app/assets/defi-list/cells/defi-protocol-cell.tsx
@@ -0,0 +1,88 @@
+import React, { useContext } from 'react';
+import { useSelector } from 'react-redux';
+import GenericAssetCellLayout from '../../asset-list/cells/generic-asset-cell-layout';
+import { getPreferences } from '../../../../../selectors';
+
+import {
+  TextVariant,
+  TextColor,
+} from '../../../../../helpers/constants/design-system';
+import { SensitiveText } from '../../../../component-library';
+import { AvatarType } from '../../../../multichain/avatar-group/avatar-group.types';
+import { AssetCellBadge } from '../../asset-list/cells/asset-cell-badge';
+import { AssetCellTitle } from '../../asset-list/cells/asset-title';
+import {
+  MetaMetricsEventCategory,
+  MetaMetricsEventName,
+} from '../../../../../../shared/constants/metametrics';
+import { MetaMetricsContext } from '../../../../../contexts/metametrics';
+import { DeFiProtocolPosition } from '../../types';
+import { AvatarGroup } from '../../../../multichain/avatar-group/avatar-group';
+import { DeFiSymbolGroup } from './defi-grouped-symbol-cell';
+
+type DeFiProtocolCellProps = {
+  onClick: (chainId: string, protocolId: string) => void;
+  position: DeFiProtocolPosition;
+};
+
+export default function DefiProtocolCell({
+  onClick,
+  position,
+}: DeFiProtocolCellProps) {
+  const { privacyMode } = useSelector(getPreferences);
+  const trackEvent = useContext(MetaMetricsContext);
+
+  const handleTokenClick = (token: DeFiProtocolPosition) => () => {
+    onClick(token.chainId, token.protocolId);
+
+    trackEvent({
+      category: MetaMetricsEventCategory.DeFi,
+      event: MetaMetricsEventName.DeFiDetailsOpened,
+      properties: {
+        location: 'Home',
+        chain_id: token.chainId,
+        protocol_id: token.protocolId,
+      },
+    });
+  };
+
+  return (
+    <GenericAssetCellLayout
+      key={`${position.chainId}-${position.protocolId}`}
+      onClick={handleTokenClick(position)}
+      disableHover={false}
+      badge={
+        <AssetCellBadge
+          chainId={position.chainId}
+          data-testid="defi-list-protocol-badge"
+          tokenImage={position.tokenImage}
+          symbol={position.protocolId}
+        />
+      }
+      headerLeftDisplay={<AssetCellTitle title={position.title} />}
+      headerRightDisplay={
+        <SensitiveText
+          color={TextColor.textAlternativeSoft}
+          variant={TextVariant.bodySmMedium}
+          isHidden={privacyMode}
+          data-testid="defi-list-market-value"
+        >
+          {position.marketValue}
+        </SensitiveText>
+      }
+      footerLeftDisplay={
+        <DeFiSymbolGroup
+          privacyMode={privacyMode}
+          symbols={position.underlyingSymbols}
+        />
+      }
+      footerRightDisplay={
+        <AvatarGroup
+          avatarType={AvatarType.TOKEN}
+          limit={4}
+          members={position.iconGroup}
+        />
+      }
+    />
+  );
+}
diff --git a/ui/components/app/assets/defi-list/defi-list.test.tsx b/ui/components/app/assets/defi-list/defi-list.test.tsx
index 873c7fe351c4..2ec0e71035e3 100644
--- a/ui/components/app/assets/defi-list/defi-list.test.tsx
+++ b/ui/components/app/assets/defi-list/defi-list.test.tsx
@@ -69,7 +69,7 @@ describe('DeFiDetailsPage', () => {
 
     await waitFor(() => {
       expect(
-        screen.getByText('Oops! Something went wrong.'),
+        screen.getByText('We could not load this page.'),
       ).toBeInTheDocument();
     });
   });
diff --git a/ui/components/app/assets/defi-list/defi-list.tsx b/ui/components/app/assets/defi-list/defi-list.tsx
index e8abe1d95dc3..81c53918a69d 100644
--- a/ui/components/app/assets/defi-list/defi-list.tsx
+++ b/ui/components/app/assets/defi-list/defi-list.tsx
@@ -1,20 +1,8 @@
-import React, { useContext, useMemo } from 'react';
+import React, { useMemo } from 'react';
 import { useSelector } from 'react-redux';
-
-import {
-  DeFiPositionsControllerState,
-  GroupedDeFiPositions,
-} from '@metamask/assets-controllers';
-
 import { Hex } from '@metamask/utils';
-import TokenCell from '../token-cell';
-import {
-  getPreferences,
-  getSelectedAccount,
-  getTokenSortConfig,
-} from '../../../../selectors';
+import { getSelectedAccount, getTokenSortConfig } from '../../../../selectors';
 import { useNetworkFilter } from '../hooks';
-import { TokenWithFiatAmount } from '../types';
 import { filterAssets } from '../util/filter';
 import { sortAssets } from '../util/sort';
 import {
@@ -22,86 +10,32 @@ import {
   FlexDirection,
   AlignItems,
   JustifyContent,
-  BlockSize,
-  TextVariant,
-  TextAlign,
 } from '../../../../helpers/constants/design-system';
 import PulseLoader from '../../../ui/pulse-loader';
-import { AvatarGroup } from '../../../multichain/avatar-group/avatar-group';
-import { AvatarType } from '../../../multichain/avatar-group/avatar-group.types';
-import { MetaMetricsContext } from '../../../../contexts/metametrics';
-import {
-  MetaMetricsEventCategory,
-  MetaMetricsEventName,
-} from '../../../../../shared/constants/metametrics';
-import {
-  Box,
-  Icon,
-  IconName,
-  IconSize,
-  Text,
-} from '../../../component-library';
+import { Box } from '../../../component-library';
 import { useI18nContext } from '../../../../hooks/useI18nContext';
 
-export type DefiState = {
-  metamask: DeFiPositionsControllerState;
-};
-export function getDefiPositions(
-  state: DefiState,
-): DeFiPositionsControllerState['allDeFiPositions'] {
-  return state?.metamask?.allDeFiPositions;
-}
+import { formatWithThreshold } from '../util/formatWithThreshold';
+import { getIntlLocale } from '../../../../ducks/locale/locale';
+
+import { extractUniqueIconAndSymbols } from '../util/extractIconAndSymbol';
+import { getDefiPositions } from '../../../../selectors/assets';
+import { DeFiProtocolPosition } from '../types';
+import { DeFiErrorMessage } from './cells/defi-error-message';
+import { DeFiEmptyStateMessage } from './cells/defi-empty-state';
+import DefiProtocolCell from './cells/defi-protocol-cell';
 
 type DefiListProps = {
   onClick: (chainId: string, protocolId: string) => void;
 };
 
-type DeFiProtocolPosition = TokenWithFiatAmount & {
-  protocolId: string;
-  iconGroup: { avatarValue: string; symbol: string }[];
-};
-
-export function ErrorMessage({ title, text }: { title: string; text: string }) {
-  return (
-    <Box
-      height={BlockSize.Full}
-      width={BlockSize.Full}
-      display={Display.Flex}
-      justifyContent={JustifyContent.center}
-      alignItems={AlignItems.center}
-      flexDirection={FlexDirection.Column}
-      gap={2}
-      data-testid="defi-tab-error-message"
-    >
-      <Icon name={IconName.Warning} size={IconSize.Xl} />
-      <Text variant={TextVariant.headingSm}>{title}</Text>
-      <Text variant={TextVariant.bodyMd} textAlign={TextAlign.Center}>
-        {text}
-      </Text>
-    </Box>
-  );
-}
-
-const DEFI_EMPTY_STATE_TOKEN = {
-  address: '0x' as Hex,
-  title: 'Start earning',
-  symbol: 'Start earning',
-  tokenFiatAmount: 0,
-  image: `images/logo/metamask-fox-bg.svg`,
-  primary: '0',
-  secondary: 0,
-  decimals: 10,
-  chainId: '0x1' as Hex,
-  isStakeable: true,
-};
-
-function DefiList({ onClick }: DefiListProps) {
+export default function DefiList({ onClick }: DefiListProps) {
   const t = useI18nContext();
   const { networkFilter } = useNetworkFilter();
-  const { privacyMode } = useSelector(getPreferences);
+  const locale = useSelector(getIntlLocale);
+
   const tokenSortConfig = useSelector(getTokenSortConfig);
   const selectedAccount = useSelector(getSelectedAccount);
-  const trackEvent = useContext(MetaMetricsContext);
 
   const allDefiPositions = useSelector(getDefiPositions);
 
@@ -133,43 +67,20 @@ function DefiList({ onClick }: DefiListProps) {
       currentAddressDefiPositions,
     ).flatMap(([chainId, chainData]) =>
       Object.entries(chainData.protocols).map(([protocolId, protocol]) => {
-        const extractIconGroup = (
-          protocolPositions: GroupedDeFiPositions['protocols'][keyof GroupedDeFiPositions['protocols']],
-        ) => {
-          if (!protocolPositions?.positionTypes) {
-            return [];
-          }
-
-          return Object.values(protocolPositions.positionTypes).flatMap(
-            (displayTokens) =>
-              displayTokens?.positions?.flatMap(
-                (nestedToken) =>
-                  nestedToken?.flatMap(
-                    (token) =>
-                      token?.tokens?.map((underlying) => ({
-                        symbol: underlying?.symbol || '',
-                        avatarValue: underlying?.iconUrl || '',
-                      })) || [],
-                  ) || [],
-              ) || [],
-          );
-        };
+        const { name: protocolName, iconUrl } = protocol.protocolDetails;
+        const marketValue = protocol.aggregatedMarketValue;
+        const iconGroup = extractUniqueIconAndSymbols(protocol);
 
-        const iconGroup = extractIconGroup(protocol);
         return {
           protocolId,
-          // Currently we don't have an address for a protocol
-          // Protocols have many addresses - perhaps one day the Protocol's Govenance Contract address might make sense here
-          // Note: this is also the case for native tokens - they also dont have an address
-          address: '0x',
-          title: protocol.protocolDetails.name,
-          symbol: protocol.protocolDetails.name,
-          tokenFiatAmount: protocol.aggregatedMarketValue,
-          image: protocol.protocolDetails.iconUrl,
-          primary: protocol.aggregatedMarketValue.toString(),
-          secondary: protocol.aggregatedMarketValue,
-          decimals: 10,
-          chainId: chainId as '0x' & string,
+          title: protocolName,
+          tokenImage: iconUrl,
+          underlyingSymbols: iconGroup.map(({ symbol }) => symbol),
+          marketValue: formatWithThreshold(marketValue, 0.01, locale, {
+            style: 'currency',
+            currency: 'USD',
+          }),
+          chainId: chainId as Hex,
           iconGroup,
         };
       }),
@@ -185,21 +96,13 @@ function DefiList({ onClick }: DefiListProps) {
 
     // sort filtered tokens based on the tokenSortConfig in state
     return sortAssets(filteredAssets, tokenSortConfig);
-  }, [allDefiPositions, networkFilter, selectedAccount, tokenSortConfig]);
-
-  const handleTokenClick = (token: DeFiProtocolPosition) => () => {
-    onClick(token.chainId, token.protocolId);
-
-    trackEvent({
-      category: MetaMetricsEventCategory.DeFi,
-      event: MetaMetricsEventName.DeFiDetailsOpened,
-      properties: {
-        location: 'Home',
-        chain_id: token.chainId,
-        protocol_id: token.protocolId,
-      },
-    });
-  };
+  }, [
+    allDefiPositions,
+    locale,
+    networkFilter,
+    selectedAccount,
+    tokenSortConfig,
+  ]);
 
   if (sortedFilteredDefi === undefined) {
     return (
@@ -216,7 +119,7 @@ function DefiList({ onClick }: DefiListProps) {
 
   if (sortedFilteredDefi === null) {
     return (
-      <ErrorMessage
+      <DeFiErrorMessage
         title={t('defiTabErrorTitle')}
         text={t('defiTabErrorContent')}
       />
@@ -225,37 +128,22 @@ function DefiList({ onClick }: DefiListProps) {
 
   return (
     <>
-      {sortedFilteredDefi && sortedFilteredDefi?.length > 0 ? (
-        sortedFilteredDefi.map((token: DeFiProtocolPosition) => {
+      {sortedFilteredDefi && sortedFilteredDefi.length > 0 ? (
+        sortedFilteredDefi.map((position: DeFiProtocolPosition) => {
           return (
-            <TokenCell
-              key={`${token.chainId}-${token.protocolId}`}
-              token={token}
-              privacyMode={privacyMode}
-              onClick={handleTokenClick(token)}
-              TokenCellPrimaryDisplayOverride={() => (
-                <AvatarGroup
-                  avatarType={AvatarType.TOKEN}
-                  limit={4}
-                  members={token.iconGroup}
-                  data-testid="defi-list-avatar-group"
-                />
-              )}
-              fixCurrencyToUSD={true}
+            <DefiProtocolCell
+              key={`${position.protocolId}#${position.chainId}`}
+              position={position}
+              onClick={onClick}
             />
           );
         })
       ) : (
-        <TokenCell
-          key={`empty-defi-list`}
-          token={DEFI_EMPTY_STATE_TOKEN}
-          privacyMode={privacyMode}
-          onClick={undefined}
-          fixCurrencyToUSD={true}
+        <DeFiEmptyStateMessage
+          primaryText={t('noDeFiPositions')}
+          secondaryText={t('startEarning')}
         />
       )}
     </>
   );
 }
-
-export default React.memo(DefiList);
diff --git a/ui/components/app/assets/defi-list/defi-tab.test.tsx b/ui/components/app/assets/defi-list/defi-tab.test.tsx
index a79bdfffa9c8..3d8442431c90 100644
--- a/ui/components/app/assets/defi-list/defi-tab.test.tsx
+++ b/ui/components/app/assets/defi-list/defi-tab.test.tsx
@@ -59,15 +59,36 @@ const allDeFiPositions = {
     },
   },
 };
+const loadingDefiPositions = {
+  [mockState.metamask.selectedAddress]: undefined,
+};
+const noOpenPositions = {
+  [mockState.metamask.selectedAddress]: [],
+};
+const defiApiError = null;
+
+const render = (
+  state: 'with-positions' | 'loading-positions' | 'error' | 'no-open-positions',
+) => {
+  let selectedDeFiPositions;
+
+  if (state === 'with-positions') {
+    selectedDeFiPositions = allDeFiPositions;
+  } else if (state === 'loading-positions') {
+    selectedDeFiPositions = loadingDefiPositions;
+  } else if (state === 'no-open-positions') {
+    selectedDeFiPositions = noOpenPositions;
+  } else {
+    selectedDeFiPositions = defiApiError;
+  }
 
-const render = () => {
   const mockStore = {
     ...mockState,
 
     metamask: {
       ...mockState.metamask,
       ...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }),
-      allDeFiPositions,
+      allDeFiPositions: selectedDeFiPositions,
       currencyRates: {
         ETH: {
           conversionRate: 1597.32,
@@ -82,16 +103,78 @@ const render = () => {
 describe('DefiList', () => {
   it('renders DeFiList component and shows control bar', async () => {
     await act(async () => {
-      render();
+      render('with-positions');
     });
 
     await waitFor(() => {
+      const image = screen.getByAltText('stETH logo');
+
+      expect(screen.getByTestId('defi-list-market-value')).toHaveTextContent(
+        '$20,000.00',
+      );
+
+      expect(image).toBeInTheDocument();
+      expect(image).toHaveAttribute(
+        'src',
+        'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84/logo.png',
+      );
+
+      expect(screen.getByTestId('avatar-group')).toBeInTheDocument();
+      expect(screen.getByTestId('sort-by-popover-toggle')).toBeInTheDocument();
+      expect(screen.getByTestId('sort-by-networks')).toBeInTheDocument();
+
       expect(
-        screen.getByTestId('multichain-token-list-item-secondary-value'),
-      ).toHaveTextContent('$20,000.00');
+        screen.queryByTestId('import-token-button'),
+      ).not.toBeInTheDocument();
+    });
+  });
+  it('renders loading spinner', async () => {
+    await act(async () => {
+      render('loading-positions');
+    });
+
+    await waitFor(() => {
+      expect(screen.getByTestId('pulse-loader')).toBeInTheDocument();
+
       expect(screen.getByTestId('sort-by-popover-toggle')).toBeInTheDocument();
       expect(screen.getByTestId('sort-by-networks')).toBeInTheDocument();
-      expect(screen.getByTestId('avatar-group')).toBeInTheDocument();
+
+      expect(
+        screen.queryByTestId('import-token-button'),
+      ).not.toBeInTheDocument();
+    });
+  });
+  it('renders error message', async () => {
+    await act(async () => {
+      render('error');
+    });
+
+    await waitFor(() => {
+      expect(screen.getByTestId('defi-tab-error-message')).toHaveTextContent(
+        'We could not load this page.',
+      );
+      expect(screen.getByTestId('defi-tab-error-message')).toHaveTextContent(
+        'Try visiting again later.',
+      );
+      expect(screen.getByTestId('sort-by-popover-toggle')).toBeInTheDocument();
+      expect(screen.getByTestId('sort-by-networks')).toBeInTheDocument();
+
+      expect(
+        screen.queryByTestId('import-token-button'),
+      ).not.toBeInTheDocument();
+    });
+  });
+  it('renders no positions message', async () => {
+    await act(async () => {
+      render('no-open-positions');
+    });
+
+    await waitFor(() => {
+      expect(screen.queryByText('No positions yet')).toBeInTheDocument();
+      expect(screen.queryByText('Start earning')).toBeInTheDocument();
+      expect(screen.getByTestId('sort-by-popover-toggle')).toBeInTheDocument();
+      expect(screen.getByTestId('sort-by-networks')).toBeInTheDocument();
+
       expect(
         screen.queryByTestId('import-token-button'),
       ).not.toBeInTheDocument();
diff --git a/ui/components/app/assets/defi-list/defi-tab.tsx b/ui/components/app/assets/defi-list/defi-tab.tsx
index 670069780a18..245d01661d1f 100644
--- a/ui/components/app/assets/defi-list/defi-tab.tsx
+++ b/ui/components/app/assets/defi-list/defi-tab.tsx
@@ -3,13 +3,11 @@ import { AssetListProps } from '../asset-list/asset-list';
 import AssetListControlBar from '../asset-list/asset-list-control-bar';
 import DefiList from './defi-list';
 
-const DeFiTab = ({ onClickAsset }: AssetListProps) => {
+export default function DeFiTab({ onClickAsset }: AssetListProps) {
   return (
     <>
       <AssetListControlBar showImportTokenButton={false} />
       <DefiList onClick={onClickAsset} />
     </>
   );
-};
-
-export default DeFiTab;
+}
diff --git a/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap b/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap
index 3a6501cbb5b8..17356452f8dd 100644
--- a/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap
+++ b/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap
@@ -44,12 +44,16 @@ exports[`Token Cell should match snapshot 1`] = `
         <div
           class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
         >
-          <p
-            class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
-            data-testid="multichain-token-list-item-token-name"
+          <div
+            class="mm-box mm-box--display-flex"
           >
-            TEST
-          </p>
+            <p
+              class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
+              data-testid="multichain-token-list-item-token-name"
+            >
+              TEST
+            </p>
+          </div>
           <p
             class="mm-box mm-text mm-text--body-sm mm-text--font-weight-normal mm-text--text-align-end mm-box--color-text-default"
             data-testid="multichain-token-list-item-secondary-value"
diff --git a/ui/components/app/assets/token-cell/cells/index.ts b/ui/components/app/assets/token-cell/cells/index.ts
index 5158f539b9f9..0da224ae5d23 100644
--- a/ui/components/app/assets/token-cell/cells/index.ts
+++ b/ui/components/app/assets/token-cell/cells/index.ts
@@ -1,4 +1,3 @@
-export * from './token-cell-badge';
 export * from './token-cell-percent-change';
 export * from './token-cell-primary-display';
 export * from './token-cell-secondary-display';
diff --git a/ui/components/app/assets/token-cell/cells/token-cell-title.tsx b/ui/components/app/assets/token-cell/cells/token-cell-title.tsx
index 46faec6018fd..16bc32c4b038 100644
--- a/ui/components/app/assets/token-cell/cells/token-cell-title.tsx
+++ b/ui/components/app/assets/token-cell/cells/token-cell-title.tsx
@@ -1,18 +1,9 @@
 import React from 'react';
-import {
-  Display,
-  FontWeight,
-  TextVariant,
-} from '../../../../../helpers/constants/design-system';
-import { Text } from '../../../../component-library';
 import { TokenFiatDisplayInfo } from '../../types';
 import { StakeableLink } from '../../../../multichain/token-list-item/stakeable-link';
-import {
-  TranslateFunction,
-  networkTitleOverrides,
-} from '../../util/networkTitleOverrides';
-import { useI18nContext } from '../../../../../hooks/useI18nContext';
-import Tooltip from '../../../../ui/tooltip';
+import { AssetCellTitle } from '../../asset-list/cells/asset-title';
+import { Box } from '../../../../component-library';
+import { Display } from '../../../../../helpers/constants/design-system';
 
 type TokenCellTitleProps = {
   token: TokenFiatDisplayInfo;
@@ -20,45 +11,13 @@ type TokenCellTitleProps = {
 
 export const TokenCellTitle = React.memo(
   ({ token }: TokenCellTitleProps) => {
-    const t = useI18nContext();
-
-    if (token.title && token.title.length > 12) {
-      return (
-        <Tooltip
-          position="bottom"
-          html={token.title}
-          wrapperClassName="token-cell-title--ellipsis"
-        >
-          <Text
-            as="span"
-            data-testid="multichain-token-list-item-token-name"
-            fontWeight={FontWeight.Medium}
-            variant={TextVariant.bodyMd}
-            display={Display.Block}
-            ellipsis
-          >
-            {networkTitleOverrides(t as TranslateFunction, token)}
-            {token.isStakeable && (
-              <StakeableLink chainId={token.chainId} symbol={token.symbol} />
-            )}
-          </Text>
-        </Tooltip>
-      );
-    }
-
-    // non-ellipsized title
     return (
-      <Text
-        fontWeight={FontWeight.Medium}
-        variant={TextVariant.bodyMd}
-        ellipsis
-        data-testid="multichain-token-list-item-token-name"
-      >
-        {networkTitleOverrides(t as TranslateFunction, token)}
+      <Box display={Display.Flex}>
+        <AssetCellTitle title={token.title} />
         {token.isStakeable && (
           <StakeableLink chainId={token.chainId} symbol={token.symbol} />
         )}
-      </Text>
+      </Box>
     );
   },
   (prevProps, nextProps) => prevProps.token.title === nextProps.token.title, // Only rerender if the title changes
diff --git a/ui/components/app/assets/token-cell/token-cell.tsx b/ui/components/app/assets/token-cell/token-cell.tsx
index d53c1e66441d..84e36d011f10 100644
--- a/ui/components/app/assets/token-cell/token-cell.tsx
+++ b/ui/components/app/assets/token-cell/token-cell.tsx
@@ -1,15 +1,8 @@
-import React, { useState } from 'react';
+import React, { useMemo, useState } from 'react';
 import { useDispatch, useSelector } from 'react-redux';
 import { useHistory } from 'react-router-dom';
 import { useTokenDisplayInfo } from '../hooks';
 import {
-  BlockSize,
-  Display,
-  FlexDirection,
-  JustifyContent,
-} from '../../../../helpers/constants/design-system';
-import {
-  Box,
   ButtonSecondary,
   Modal,
   ModalBody,
@@ -28,8 +21,9 @@ import {
   useSafeChains,
 } from '../../../../pages/settings/networks-tab/networks-form/use-safe-chains';
 import { TokenWithFiatAmount } from '../types';
+import GenericAssetCellLayout from '../asset-list/cells/generic-asset-cell-layout';
+import { AssetCellBadge } from '../asset-list/cells/asset-cell-badge';
 import {
-  TokenCellBadge,
   TokenCellTitle,
   TokenCellPercentChange,
   TokenCellPrimaryDisplay,
@@ -41,7 +35,6 @@ export type TokenCellProps = {
   privacyMode?: boolean;
   disableHover?: boolean;
   onClick?: () => void;
-  TokenCellPrimaryDisplayOverride?: React.ComponentType;
   fixCurrencyToUSD?: boolean;
 };
 
@@ -50,7 +43,6 @@ export default function TokenCell({
   privacyMode = false,
   onClick,
   disableHover = false,
-  TokenCellPrimaryDisplayOverride,
   fixCurrencyToUSD = false,
 }: TokenCellProps) {
   const dispatch = useDispatch();
@@ -59,7 +51,6 @@ export default function TokenCell({
   const isEvm = useSelector(getMultichainIsEvm);
   const { safeChains } = useSafeChains();
   const [showScamWarningModal, setShowScamWarningModal] = useState(false);
-  const [isHovered, setIsHovered] = useState(false);
 
   const decimalChainId = isEvm && parseInt(hexToDecimal(token.chainId), 10);
 
@@ -75,6 +66,14 @@ export default function TokenCell({
     fixCurrencyToUSD,
   });
 
+  const displayToken = useMemo(
+    () => ({
+      ...token,
+      ...tokenDisplayInfo,
+    }),
+    [token, tokenDisplayInfo],
+  );
+
   const handleScamWarningModal = (arg: boolean) => {
     setShowScamWarningModal(arg);
   };
@@ -83,88 +82,29 @@ export default function TokenCell({
     return null;
   }
 
-  const PrimaryDisplay = () =>
-    TokenCellPrimaryDisplayOverride ? (
-      <TokenCellPrimaryDisplayOverride />
-    ) : (
-      <TokenCellPrimaryDisplay
-        token={{ ...token, ...tokenDisplayInfo }}
-        privacyMode={privacyMode}
-      />
-    );
-
   return (
-    <Box
-      display={Display.Flex}
-      flexDirection={FlexDirection.Row}
-      width={BlockSize.Full}
-      height={BlockSize.Full}
-      gap={4}
-    >
-      <Box
-        as="a"
-        onClick={(e?: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
-          e?.preventDefault();
-
-          if (!onClick || showScamWarningModal) {
-            return;
-          }
-
-          onClick();
-        }}
-        display={Display.Flex}
-        flexDirection={FlexDirection.Row}
-        paddingTop={2}
-        paddingBottom={2}
-        paddingLeft={4}
-        paddingRight={4}
-        width={BlockSize.Full}
-        style={{
-          height: 62,
-          cursor: onClick ? 'pointer' : 'auto',
-          backgroundColor:
-            !disableHover && isHovered
-              ? 'var(--color-background-default-hover)'
-              : 'transparent',
-          transition: 'background-color 0.2s ease-in-out',
-        }}
-        onMouseEnter={() => !disableHover && setIsHovered(true)}
-        onMouseLeave={() => !disableHover && setIsHovered(false)}
-        data-testid="multichain-token-list-button"
-      >
-        <TokenCellBadge token={{ ...token, ...tokenDisplayInfo }} />
-        <Box
-          display={Display.Flex}
-          flexDirection={FlexDirection.Column}
-          width={BlockSize.Full}
-          style={{ flexGrow: 1, overflow: 'hidden' }}
-          justifyContent={JustifyContent.center}
-        >
-          <Box
-            display={Display.Flex}
-            flexDirection={FlexDirection.Row}
-            justifyContent={JustifyContent.spaceBetween}
-          >
-            <TokenCellTitle token={{ ...token, ...tokenDisplayInfo }} />
-            <TokenCellSecondaryDisplay
-              token={{ ...token, ...tokenDisplayInfo }}
-              handleScamWarningModal={handleScamWarningModal}
-              privacyMode={privacyMode}
-            />
-          </Box>
-
-          <Box
-            display={Display.Flex}
-            flexDirection={FlexDirection.Row}
-            justifyContent={JustifyContent.spaceBetween}
-          >
-            <TokenCellPercentChange token={{ ...token, ...tokenDisplayInfo }} />
-            <PrimaryDisplay />
-          </Box>
-        </Box>
-      </Box>
-      {/* scam warning modal, this should be higher up in the component tree */}
-      {isEvm && showScamWarningModal ? (
+    <>
+      <GenericAssetCellLayout
+        onClick={showScamWarningModal ? undefined : onClick}
+        disableHover={disableHover}
+        badge={<AssetCellBadge {...displayToken} />}
+        headerLeftDisplay={<TokenCellTitle token={displayToken} />}
+        headerRightDisplay={
+          <TokenCellSecondaryDisplay
+            token={displayToken}
+            handleScamWarningModal={handleScamWarningModal}
+            privacyMode={privacyMode}
+          />
+        }
+        footerLeftDisplay={<TokenCellPercentChange token={displayToken} />}
+        footerRightDisplay={
+          <TokenCellPrimaryDisplay
+            token={displayToken}
+            privacyMode={privacyMode}
+          />
+        }
+      />
+      {isEvm && showScamWarningModal && (
         <Modal isOpen onClose={() => setShowScamWarningModal(false)}>
           <ModalOverlay />
           <ModalContent>
@@ -174,10 +114,8 @@ export default function TokenCell({
             <ModalBody marginTop={4} marginBottom={4}>
               {t('nativeTokenScamWarningDescription', [
                 token.symbol,
-                // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31880
-                // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
                 safeChainDetails?.nativeCurrency?.symbol ||
-                  t('nativeTokenScamWarningDescriptionExpectedTokenFallback'), // never render "undefined" string value
+                  t('nativeTokenScamWarningDescriptionExpectedTokenFallback'),
               ])}
             </ModalBody>
             <ModalFooter>
@@ -193,7 +131,7 @@ export default function TokenCell({
             </ModalFooter>
           </ModalContent>
         </Modal>
-      ) : null}
-    </Box>
+      )}
+    </>
   );
 }
diff --git a/ui/components/app/assets/types.ts b/ui/components/app/assets/types.ts
index f30c35c92f2e..bae1fca816eb 100644
--- a/ui/components/app/assets/types.ts
+++ b/ui/components/app/assets/types.ts
@@ -68,3 +68,13 @@ export type ChainAddressMarketData = Record<
 >;
 
 export type SymbolCurrencyRateMapping = Record<string, Record<string, number>>;
+
+export type DeFiProtocolPosition = {
+  chainId: Hex;
+  tokenImage: string;
+  underlyingSymbols: string[];
+  marketValue: string;
+  title: string;
+  protocolId: string;
+  iconGroup: { avatarValue: string; symbol: string }[];
+};
diff --git a/ui/components/app/assets/util/buildSymbolGroup.ts b/ui/components/app/assets/util/buildSymbolGroup.ts
new file mode 100644
index 000000000000..db4ffe53cfbf
--- /dev/null
+++ b/ui/components/app/assets/util/buildSymbolGroup.ts
@@ -0,0 +1,10 @@
+export const buildSymbolGroup = (symbols: string[]): string => {
+  if (symbols.length === 1) {
+    return `${symbols[0]} only`;
+  } else if (symbols.length === 2) {
+    return `${symbols[0]} +${symbols.length - 1} other`;
+  } else if (symbols.length > 2) {
+    return `${symbols[0]} +${symbols.length - 1} others`;
+  }
+  return '';
+};
diff --git a/ui/components/app/assets/util/extractIconAndSymbol.ts b/ui/components/app/assets/util/extractIconAndSymbol.ts
new file mode 100644
index 000000000000..52b55dbcf076
--- /dev/null
+++ b/ui/components/app/assets/util/extractIconAndSymbol.ts
@@ -0,0 +1,49 @@
+import { GroupedDeFiPositions } from '@metamask/assets-controllers';
+
+/**
+ * Extracts unique token icons and symbols from nested protocol position data, and orders by ETH or WETH.
+ * This function is used within `useMemo` based on `protocolPositions`
+ *
+ * @param protocolPositions
+ */
+export const extractUniqueIconAndSymbols = (
+  protocolPositions: GroupedDeFiPositions['protocols'][keyof GroupedDeFiPositions['protocols']],
+) => {
+  if (!protocolPositions?.positionTypes) {
+    return [];
+  }
+
+  const iconsAndSymbols = Array.from(
+    new Map(
+      Object.values(protocolPositions.positionTypes)
+        .flatMap(
+          (displayTokens) =>
+            displayTokens?.positions?.flatMap(
+              (nestedToken) =>
+                nestedToken?.flatMap(
+                  (token) =>
+                    token?.tokens?.map((underlying) => ({
+                      symbol: underlying?.symbol || '',
+                      avatarValue: underlying?.iconUrl || '',
+                    })) || [],
+                ) || [],
+            ) || [],
+        )
+        .filter(Boolean)
+        .map((item) => [item.symbol, item]), // Use symbol as the key for uniqueness
+    ).values(),
+  );
+
+  // Ensure 'ETH' or 'WETH' is at position 1
+  const symbolPriority = ['ETH', 'WETH'];
+  const firstTokenIndex = iconsAndSymbols.findIndex((item) =>
+    symbolPriority.includes(item.symbol),
+  );
+
+  if (firstTokenIndex > -1) {
+    const [firstItem] = iconsAndSymbols.splice(firstTokenIndex, 1);
+    iconsAndSymbols.unshift(firstItem);
+  }
+
+  return iconsAndSymbols;
+};
diff --git a/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap b/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap
index b2b27cd3f68e..e56e6470eedb 100644
--- a/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap
+++ b/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap
@@ -253,11 +253,15 @@ exports[`AssetPage should render a native asset 1`] = `
             <div
               class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
             >
-              <p
-                class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
-                data-testid="multichain-token-list-item-token-name"
+              <div
+                class="mm-box mm-box--display-flex"
               >
-                TEST
+                <p
+                  class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
+                  data-testid="multichain-token-list-item-token-name"
+                >
+                  TEST
+                </p>
                 <button
                   class="mm-box mm-box--padding-inline-0 mm-box--padding-inline-start-1 mm-box--padding-inline-end-1 mm-box--gap-1 mm-box--background-color-transparent"
                   data-testid="staking-entrypoint-0x1"
@@ -278,7 +282,7 @@ exports[`AssetPage should render a native asset 1`] = `
                     style="mask-image: url('./images/icons/stake.svg');"
                   />
                 </button>
-              </p>
+              </div>
               <p
                 class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-text--text-align-end mm-box--color-text-default"
                 data-testid="multichain-token-list-item-secondary-value"
@@ -674,12 +678,16 @@ exports[`AssetPage should render an ERC20 asset without prices 1`] = `
             <div
               class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
             >
-              <p
-                class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
-                data-testid="multichain-token-list-item-token-name"
+              <div
+                class="mm-box mm-box--display-flex"
               >
-                TEST
-              </p>
+                <p
+                  class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
+                  data-testid="multichain-token-list-item-token-name"
+                >
+                  TEST
+                </p>
+              </div>
               <p
                 class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--text-align-end mm-box--color-text-default"
                 data-testid="multichain-token-list-item-secondary-value"
@@ -1140,12 +1148,16 @@ exports[`AssetPage should render an ERC20 token with prices 1`] = `
             <div
               class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
             >
-              <p
-                class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
-                data-testid="multichain-token-list-item-token-name"
+              <div
+                class="mm-box mm-box--display-flex"
               >
-                TEST
-              </p>
+                <p
+                  class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
+                  data-testid="multichain-token-list-item-token-name"
+                >
+                  TEST
+                </p>
+              </div>
               <p
                 class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--text-align-end mm-box--color-text-default"
                 data-testid="multichain-token-list-item-secondary-value"
diff --git a/ui/pages/defi/components/__snapshots__/defi-details-list.test.tsx.snap b/ui/pages/defi/components/__snapshots__/defi-details-list.test.tsx.snap
index 56e5046c7486..bcd8a41473f7 100644
--- a/ui/pages/defi/components/__snapshots__/defi-details-list.test.tsx.snap
+++ b/ui/pages/defi/components/__snapshots__/defi-details-list.test.tsx.snap
@@ -56,12 +56,16 @@ exports[`DeFiDetailsPage renders defi details list 1`] = `
             <div
               class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
             >
-              <p
-                class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
-                data-testid="multichain-token-list-item-token-name"
+              <div
+                class="mm-box mm-box--display-flex"
               >
-                Ethereum
-              </p>
+                <p
+                  class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
+                  data-testid="multichain-token-list-item-token-name"
+                >
+                  Ethereum
+                </p>
+              </div>
               <p
                 class="mm-box mm-text mm-text--body-sm mm-text--font-weight-normal mm-text--text-align-end mm-box--color-text-default"
                 data-testid="multichain-token-list-item-secondary-value"
@@ -145,12 +149,16 @@ exports[`DeFiDetailsPage renders defi details list 1`] = `
             <div
               class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
             >
-              <p
-                class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
-                data-testid="multichain-token-list-item-token-name"
+              <div
+                class="mm-box mm-box--display-flex"
               >
-                Ethereum
-              </p>
+                <p
+                  class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--color-text-default"
+                  data-testid="multichain-token-list-item-token-name"
+                >
+                  Ethereum
+                </p>
+              </div>
               <p
                 class="mm-box mm-text mm-text--body-sm mm-text--font-weight-normal mm-text--text-align-end mm-box--color-text-default"
                 data-testid="multichain-token-list-item-secondary-value"
diff --git a/ui/pages/defi/components/__snapshots__/defi-details-page.test.tsx.snap b/ui/pages/defi/components/__snapshots__/defi-details-page.test.tsx.snap
index 11113c6dd714..0c6cea08ef3a 100644
--- a/ui/pages/defi/components/__snapshots__/defi-details-page.test.tsx.snap
+++ b/ui/pages/defi/components/__snapshots__/defi-details-page.test.tsx.snap
@@ -6,29 +6,56 @@ exports[`DeFiDetailsPage renders defi asset page 1`] = `
     class="mm-box main-container asset__container"
   >
     <div
-      class="mm-box mm-box--padding-left-2"
+      class="mm-box mm-box--padding-top-4 mm-box--padding-bottom-4 mm-box--padding-left-2 mm-box--display-flex"
     >
+      <button
+        aria-label="Back"
+        class="mm-box mm-button-icon mm-button-icon--size-sm mm-box--margin-right-1 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-alternative mm-box--background-color-transparent mm-box--rounded-lg"
+        data-testid="defi-details-page-back-button"
+      >
+        <span
+          class="mm-box mm-icon mm-icon--size-sm mm-box--display-inline-block mm-box--color-inherit"
+          style="mask-image: url('./images/icons/arrow-left.svg');"
+        />
+      </button>
+    </div>
+    <div
+      class="mm-box mm-box--padding-right-4 mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
+    >
+      <h2
+        class="mm-box mm-text mm-text--heading-lg mm-box--padding-bottom-2 mm-box--padding-left-4 mm-box--color-text-default"
+        data-testid="defi-details-page-title"
+      >
+        Lido
+      </h2>
       <div
-        class="mm-box mm-box--padding-top-4 mm-box--padding-bottom-4 mm-box--display-flex"
+        class="mm-box mm-badge-wrapper mm-box--margin-right-4 mm-box--display-inline-block"
+        style="align-self: center;"
       >
-        <button
-          aria-label="Back"
-          class="mm-box mm-button-icon mm-button-icon--size-sm mm-box--margin-right-1 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-alternative mm-box--background-color-transparent mm-box--rounded-lg"
-          data-testid="defi-details-page-back-button"
+        <div
+          class="mm-box mm-text mm-avatar-base mm-avatar-base--size-md mm-avatar-token mm-text--body-sm mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-background-muted mm-box--rounded-full"
         >
-          <span
-            class="mm-box mm-icon mm-icon--size-sm mm-box--display-inline-block mm-box--color-inherit"
-            style="mask-image: url('./images/icons/arrow-left.svg');"
+          <img
+            alt="Lido logo"
+            class="mm-avatar-token__token-image"
+            src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84/logo.png"
           />
-        </button>
+        </div>
+        <div
+          class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right"
+        >
+          <div
+            class="mm-box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network mm-text--body-xs mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-background-muted mm-box--rounded-md mm-box--border-color-background-default mm-box--border-width-2 box--border-style-solid"
+          >
+            <img
+              alt="Custom Mainnet RPC logo"
+              class="mm-avatar-network__network-image"
+              src="./images/eth_logo.svg"
+            />
+          </div>
+        </div>
       </div>
     </div>
-    <h2
-      class="mm-box mm-text mm-text--heading-lg mm-box--padding-bottom-2 mm-box--padding-left-4 mm-box--color-text-default"
-      data-testid="defi-details-page-title"
-    >
-      Lido
-    </h2>
     <div
       class="mm-box mm-box--padding-bottom-4 mm-box--padding-left-4"
     >
@@ -102,22 +129,26 @@ exports[`DeFiDetailsPage renders defi asset page 1`] = `
                   class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between"
                 >
                   <div
-                    class="token-cell-title--ellipsis"
+                    class="mm-box mm-box--display-flex"
                   >
                     <div
-                      aria-describedby="tippy-tooltip-1"
-                      class=""
-                      data-original-title="null"
-                      data-tooltipped=""
-                      style="display: inline;"
-                      tabindex="0"
+                      class="token-cell-title--ellipsis"
                     >
-                      <span
-                        class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--display-block mm-box--color-text-default"
-                        data-testid="multichain-token-list-item-token-name"
+                      <div
+                        aria-describedby="tippy-tooltip-1"
+                        class=""
+                        data-original-title="null"
+                        data-tooltipped=""
+                        style="display: inline;"
+                        tabindex="0"
                       >
-                        Liquid staked Ether 2.0
-                      </span>
+                        <span
+                          class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-text--ellipsis mm-box--display-block mm-box--color-text-default"
+                          data-testid="multichain-token-list-item-token-name"
+                        >
+                          Liquid staked Ether 2.0
+                        </span>
+                      </div>
                     </div>
                   </div>
                   <p
diff --git a/ui/pages/defi/components/defi-details-page.tsx b/ui/pages/defi/components/defi-details-page.tsx
index 4ad501d7548b..46c0b7dfd1b5 100644
--- a/ui/pages/defi/components/defi-details-page.tsx
+++ b/ui/pages/defi/components/defi-details-page.tsx
@@ -5,6 +5,7 @@ import {
   Display,
   FlexDirection,
   IconColor,
+  JustifyContent,
   TextVariant,
 } from '../../../helpers/constants/design-system';
 import {
@@ -21,9 +22,10 @@ import { useI18nContext } from '../../../hooks/useI18nContext';
 import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
 
 import { getPreferences, getSelectedAccount } from '../../../selectors';
-import { getDefiPositions } from '../../../components/app/assets/defi-list/defi-list';
 import { CHAIN_IDS } from '../../../../shared/constants/network';
 import { formatWithThreshold } from '../../../components/app/assets/util/formatWithThreshold';
+import { AssetCellBadge } from '../../../components/app/assets/asset-list/cells/asset-cell-badge';
+import { getDefiPositions } from '../../../selectors/assets';
 import DefiDetailsList, {
   PositionTypeKeys,
   PositionTypeLabels,
@@ -84,28 +86,44 @@ const DeFiPage = () => {
 
   return (
     <Box className="main-container asset__container">
-      <Box paddingLeft={2}>
-        <Box display={Display.Flex} paddingBottom={4} paddingTop={4}>
-          <ButtonIcon
-            data-testid="defi-details-page-back-button"
-            color={IconColor.iconAlternative}
-            marginRight={1}
-            size={ButtonIconSize.Sm}
-            ariaLabel={t('back')}
-            iconName={IconName.ArrowLeft}
-            onClick={() => history.push(DEFAULT_ROUTE)}
-          />
-        </Box>
+      <Box
+        paddingLeft={2}
+        display={Display.Flex}
+        paddingBottom={4}
+        paddingTop={4}
+      >
+        <ButtonIcon
+          data-testid="defi-details-page-back-button"
+          color={IconColor.iconAlternative}
+          marginRight={1}
+          size={ButtonIconSize.Sm}
+          ariaLabel={t('back')}
+          iconName={IconName.ArrowLeft}
+          onClick={() => history.push(DEFAULT_ROUTE)}
+        />
       </Box>
 
-      <Text
-        variant={TextVariant.headingLg}
-        paddingLeft={4}
-        paddingBottom={2}
-        data-testid="defi-details-page-title"
+      <Box
+        display={Display.Flex}
+        flexDirection={FlexDirection.Row}
+        justifyContent={JustifyContent.spaceBetween}
+        paddingRight={4}
       >
-        {protocolPosition.protocolDetails.name}
-      </Text>
+        <Text
+          variant={TextVariant.headingLg}
+          paddingLeft={4}
+          paddingBottom={2}
+          data-testid="defi-details-page-title"
+        >
+          {protocolPosition.protocolDetails.name}
+        </Text>
+        <AssetCellBadge
+          chainId={chainId}
+          tokenImage={protocolPosition.protocolDetails.iconUrl}
+          symbol={protocolPosition.protocolDetails.name}
+          data-testid="defi-details-page-protocol-badge"
+        />
+      </Box>
       <Box paddingLeft={4} paddingBottom={4}>
         <SensitiveText
           data-testid="defi-details-page-market-value"
diff --git a/ui/selectors/assets.ts b/ui/selectors/assets.ts
index c74faeab1dbf..79c96dcf243b 100644
--- a/ui/selectors/assets.ts
+++ b/ui/selectors/assets.ts
@@ -1,4 +1,5 @@
 import {
+  DeFiPositionsControllerState,
   MultichainAssetsControllerState,
   MultichainAssetsRatesControllerState,
 } from '@metamask/assets-controllers';
@@ -41,6 +42,10 @@ export type AssetsRatesState = {
   metamask: MultichainAssetsRatesControllerState;
 };
 
+export type DefiState = {
+  metamask: DeFiPositionsControllerState;
+};
+
 /**
  * Gets non-EVM accounts assets.
  *
@@ -71,6 +76,18 @@ export function getAssetsRates(state: AssetsRatesState) {
   return state.metamask.conversionRates;
 }
 
+/**
+ * Gets DeFi positions
+ *
+ * @param state - Redux state object.
+ * @returns An object containing defi positions for all accounts
+ */
+export function getDefiPositions(
+  state: DefiState,
+): DeFiPositionsControllerState['allDeFiPositions'] {
+  return state?.metamask?.allDeFiPositions;
+}
+
 /**
  * Gets non-EVM assets historical prices.
  *


Reviews:
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:37:46Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:39:31Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:42:06Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:43:10Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:48:16Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:49:12Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T14:50:15Z
user: login: HowardBraham
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T15:52:37Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T16:43:05Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T16:49:52Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T16:57:31Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T17:00:08Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T17:06:07Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T17:06:53Z
user: login: sahar-fehri
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T17:45:48Z
user: login: sahar-fehri
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T17:46:11Z
user: login: bergarces
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T08:54:04Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:15:38Z
user: login: jpsains
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:17:04Z
user: login: HowardBraham
body: You must change this in order to not increase the circular dependences
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:43:22Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T17:35:54Z
user: login: Prithpal-Sooriya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T17:38:15Z
user: login: Prithpal-Sooriya
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T17:38:46Z
user: login: bergarces
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-21T06:49:50Z

Review comments:
diff_hunk: @@ -14,44 +14,53 @@ import {
   getMultichainIsEvm,
 } from '../../../../../selectors/multichain';
 import { getNetworkConfigurationsByChainId } from '../../../../../../shared/modules/selectors/networks';
-import { TokenFiatDisplayInfo } from '../../types';
 
-type TokenCellBadgeProps = {
-  token: TokenFiatDisplayInfo;
+type AssetCellBadgeProps = {
+  chainId: `0x${string}` | `${string}:${string}`;
+  isNative?: boolean;
+  tokenImage: string;
+  symbol: string;
 };
 
-export const TokenCellBadge = React.memo(
-  ({ token }: TokenCellBadgeProps) => {
+export const AssetCellBadge = React.memo(
+  ({
+    chainId,
+    isNative,
+    tokenImage,
+    symbol,
+    ...restProps
+  }: AssetCellBadgeProps) => {
     const isEvm = useSelector(getMultichainIsEvm);
     const allNetworks = useSelector(getNetworkConfigurationsByChainId);
 
+    const avatarTokenSrc =
+      isEvm && isNative ? getNativeCurrencyForChain(chainId) : tokenImage;
+    // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31880
+    // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+    const badgeWrapperSrc = getImageForChainId(chainId) || undefined;
+
     return (
       <BadgeWrapper
         badge={
           <AvatarNetwork
             size={AvatarNetworkSize.Xs}
-            name={allNetworks?.[token.chainId as Hex]?.name}
-            // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31880
-            // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
-            src={getImageForChainId(token.chainId) || undefined}
+            name={allNetworks?.[chainId as Hex]?.name}
+            src={badgeWrapperSrc}
             backgroundColor={BackgroundColor.backgroundMuted}
             borderWidth={2}
           />
         }
         marginRight={4}
         style={{ alignSelf: 'center' }}
+        {...restProps}
       >
         <AvatarToken
-          name={token.symbol}
+          name={symbol}
           backgroundColor={BackgroundColor.backgroundMuted}
-          src={
-            isEvm && token.isNative
-              ? getNativeCurrencyForChain(token.chainId)
-              : token.tokenImage
-          }
+          src={avatarTokenSrc}
         />
       </BadgeWrapper>
     );
   },
-  (prevProps, nextProps) => prevProps.token.chainId === nextProps.token.chainId,
+  (prevProps, nextProps) => prevProps.chainId === nextProps.chainId,
path: ui/components/app/assets/asset-list/cells/asset-cell-badge.tsx
user: login: jpsains
body: Created new generic badge-cell by removing unnecessary props. This makes the component more reusable, instead of needing whole Token object like before.
created_at: 2025-05-15T14:37:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,54 @@
+import React from 'react';
+import {
+  Display,
+  FontWeight,
+  TextVariant,
+} from '../../../../../helpers/constants/design-system';
+import { Text } from '../../../../component-library';
+import {
+  TranslateFunction,
+  networkTitleOverrides,
+} from '../../util/networkTitleOverrides';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+import Tooltip from '../../../../ui/tooltip';
+
+type AssetCellTitleProps = {
+  title: string;
+};
+
+export const AssetCellTitle = ({ title }: AssetCellTitleProps) => {
+  const t = useI18nContext();
+
+  if (title && title.length > 12) {
+    return (
+      <Tooltip
+        position="bottom"
+        html={title}
+        wrapperClassName="token-cell-title--ellipsis"
+      >
+        <Text
+          as="span"
+          data-testid="multichain-token-list-item-token-name"
+          fontWeight={FontWeight.Medium}
+          variant={TextVariant.bodyMd}
+          display={Display.Block}
+          ellipsis
+        >
+          {networkTitleOverrides(t as TranslateFunction, { title })}
+        </Text>
+      </Tooltip>
+    );
+  }
+
+  // non-ellipsized title
+  return (
+    <Text
+      fontWeight={FontWeight.Medium}
+      variant={TextVariant.bodyMd}
+      ellipsis
+      data-testid="multichain-token-list-item-token-name"
+    >
+      {networkTitleOverrides(t as TranslateFunction, { title })}
+    </Text>
+  );
+};
path: ui/components/app/assets/asset-list/cells/asset-title.tsx
user: login: jpsains
body: Created new generic title-cell by removing unnecessary props and removing staking link making it reusable (staking link is now applied outside this component)
created_at: 2025-05-15T14:39:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,96 @@
+import React, { ReactNode, useState } from 'react';
+import { Box } from '../../../../component-library';
+import {
+  Display,
+  FlexDirection,
+  BlockSize,
+  JustifyContent,
+} from '../../../../../helpers/constants/design-system';
+
+export type GenericAssetCellLayoutProps = {
+  onClick?: () => void;
+  disableHover?: boolean;
+  badge: ReactNode;
+  headerLeftDisplay: ReactNode;
+  headerRightDisplay: ReactNode;
+  footerLeftDisplay: ReactNode;
+  footerRightDisplay: ReactNode;
+};
+
+export default function GenericAssetCellLayout({
+  onClick,
+  disableHover = false,
+  badge,
+  headerLeftDisplay,
+  headerRightDisplay,
+  footerLeftDisplay,
+  footerRightDisplay,
+}: GenericAssetCellLayoutProps) {
+  const [isHovered, setIsHovered] = useState(false);
+
+  return (
+    <Box
+      display={Display.Flex}
+      flexDirection={FlexDirection.Row}
+      width={BlockSize.Full}
+      height={BlockSize.Full}
+      gap={4}
+    >
+      <Box
+        as="a"
+        onClick={(e?: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
+          e?.preventDefault();
+          if (onClick) {
+            onClick();
+          }
+        }}
+        display={Display.Flex}
+        flexDirection={FlexDirection.Row}
+        paddingTop={2}
+        paddingBottom={2}
+        paddingLeft={4}
+        paddingRight={4}
+        width={BlockSize.Full}
+        style={{
+          height: 62,
+          cursor: onClick ? 'pointer' : 'auto',
+          backgroundColor:
+            !disableHover && isHovered
+              ? 'var(--color-background-default-hover)'
+              : 'transparent',
+          transition: 'background-color 0.2s ease-in-out',
+        }}
+        onMouseEnter={() => !disableHover && setIsHovered(true)}
+        onMouseLeave={() => !disableHover && setIsHovered(false)}
+        data-testid="multichain-token-list-button"
+      >
+        {badge}
+        <Box
+          display={Display.Flex}
+          flexDirection={FlexDirection.Column}
+          width={BlockSize.Full}
+          style={{ flexGrow: 1, overflow: 'hidden' }}
+          justifyContent={JustifyContent.center}
+        >
+          <Box
+            display={Display.Flex}
+            flexDirection={FlexDirection.Row}
+            justifyContent={JustifyContent.spaceBetween}
+          >
+            {headerLeftDisplay}
+            {headerRightDisplay}
+          </Box>
+
+          <Box
+            display={Display.Flex}
+            flexDirection={FlexDirection.Row}
+            justifyContent={JustifyContent.spaceBetween}
+          >
+            {footerLeftDisplay}
+            {footerRightDisplay}
+          </Box>
+        </Box>
+      </Box>
+    </Box>
+  );
+}
path: ui/components/app/assets/asset-list/cells/generic-asset-cell-layout.tsx
user: login: jpsains
body: Created new generic asset layout component separates the layout from the input components. 

This improves reusability and clarity. Used by Token and DeFi
created_at: 2025-05-15T14:42:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,7 +69,7 @@ describe('DeFiDetailsPage', () => {
 
     await waitFor(() => {
       expect(
-        screen.getByText('Oops! Something went wrong.'),
+        screen.getByText('We could not load this page.'),
path: ui/components/app/assets/defi-list/defi-list.test.tsx
user: login: jpsains
body: New wording as per Amanda
created_at: 2025-05-15T14:43:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -133,43 +87,20 @@ function DefiList({ onClick }: DefiListProps) {
       currentAddressDefiPositions,
     ).flatMap(([chainId, chainData]) =>
       Object.entries(chainData.protocols).map(([protocolId, protocol]) => {
-        const extractIconGroup = (
-          protocolPositions: GroupedDeFiPositions['protocols'][keyof GroupedDeFiPositions['protocols']],
-        ) => {
-          if (!protocolPositions?.positionTypes) {
-            return [];
-          }
-
-          return Object.values(protocolPositions.positionTypes).flatMap(
-            (displayTokens) =>
-              displayTokens?.positions?.flatMap(
-                (nestedToken) =>
-                  nestedToken?.flatMap(
-                    (token) =>
-                      token?.tokens?.map((underlying) => ({
-                        symbol: underlying?.symbol || '',
-                        avatarValue: underlying?.iconUrl || '',
-                      })) || [],
-                  ) || [],
-              ) || [],
-          );
-        };
+        const { name: protocolName, iconUrl } = protocol.protocolDetails;
+        const marketValue = protocol.aggregatedMarketValue;
+        const iconGroup = extractUniqueIconAndSymbols(protocol);
 
-        const iconGroup = extractIconGroup(protocol);
         return {
           protocolId,
-          // Currently we don't have an address for a protocol
-          // Protocols have many addresses - perhaps one day the Protocol's Govenance Contract address might make sense here
-          // Note: this is also the case for native tokens - they also dont have an address
-          address: '0x',
-          title: protocol.protocolDetails.name,
-          symbol: protocol.protocolDetails.name,
-          tokenFiatAmount: protocol.aggregatedMarketValue,
-          image: protocol.protocolDetails.iconUrl,
-          primary: protocol.aggregatedMarketValue.toString(),
-          secondary: protocol.aggregatedMarketValue,
-          decimals: 10,
-          chainId: chainId as '0x' & string,
+          title: protocolName,
+          tokenImage: iconUrl,
+          symbolGroup: buildSymbolGroup(iconGroup.map(({ symbol }) => symbol)),
+          marketValue: formatWithThreshold(marketValue, 0.01, locale, {
+            style: 'currency',
+            currency: 'USD',
+          }),
+          chainId: chainId as Hex,
path: ui/components/app/assets/defi-list/defi-list.tsx
user: login: jpsains
body: @bergarces The generic component means we no longer create a fake Token therefore reducing potential errors
created_at: 2025-05-15T14:48:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,64 +1,23 @@
 import React from 'react';
-import {
-  Display,
-  FontWeight,
-  TextVariant,
-} from '../../../../../helpers/constants/design-system';
-import { Text } from '../../../../component-library';
 import { TokenFiatDisplayInfo } from '../../types';
 import { StakeableLink } from '../../../../multichain/token-list-item/stakeable-link';
-import {
-  TranslateFunction,
-  networkTitleOverrides,
-} from '../../util/networkTitleOverrides';
-import { useI18nContext } from '../../../../../hooks/useI18nContext';
-import Tooltip from '../../../../ui/tooltip';
+import { AssetCellTitle } from '../../asset-list/cells/asset-title';
+import { Box } from '../../../../component-library';
+import { Display } from '../../../../../helpers/constants/design-system';
 
 type TokenCellTitleProps = {
   token: TokenFiatDisplayInfo;
 };
 
 export const TokenCellTitle = React.memo(
   ({ token }: TokenCellTitleProps) => {
-    const t = useI18nContext();
-
-    if (token.title && token.title.length > 12) {
-      return (
-        <Tooltip
-          position="bottom"
-          html={token.title}
-          wrapperClassName="token-cell-title--ellipsis"
-        >
-          <Text
-            as="span"
-            data-testid="multichain-token-list-item-token-name"
-            fontWeight={FontWeight.Medium}
-            variant={TextVariant.bodyMd}
-            display={Display.Block}
-            ellipsis
-          >
-            {networkTitleOverrides(t as TranslateFunction, token)}
-            {token.isStakeable && (
-              <StakeableLink chainId={token.chainId} symbol={token.symbol} />
-            )}
-          </Text>
-        </Tooltip>
-      );
-    }
-
-    // non-ellipsized title
     return (
-      <Text
-        fontWeight={FontWeight.Medium}
-        variant={TextVariant.bodyMd}
-        ellipsis
-        data-testid="multichain-token-list-item-token-name"
-      >
-        {networkTitleOverrides(t as TranslateFunction, token)}
+      <Box display={Display.Flex}>
+        <AssetCellTitle title={token.title} />
         {token.isStakeable && (
           <StakeableLink chainId={token.chainId} symbol={token.symbol} />
         )}
-      </Text>
+      </Box>
     );
path: ui/components/app/assets/token-cell/cells/token-cell-title.tsx
user: login: jpsains
body: Here we are using the new generic component 
created_at: 2025-05-15T14:49:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,49 @@
+import { GroupedDeFiPositions } from '@metamask/assets-controllers';
+
+/**
+ * Extracts unique token icons and symbols from nested protocol position data, and orders by ETH or WETH.
+ * This function is used within `useMemo` based on `protocolPositions`
+ *
+ * @param protocolPositions
+ */
+export const extractUniqueIconAndSymbols = (
+  protocolPositions: GroupedDeFiPositions['protocols'][keyof GroupedDeFiPositions['protocols']],
+) => {
+  if (!protocolPositions?.positionTypes) {
+    return [];
+  }
+
+  const iconsAndSymbols = Array.from(
+    new Map(
+      Object.values(protocolPositions.positionTypes)
+        .flatMap(
+          (displayTokens) =>
+            displayTokens?.positions?.flatMap(
+              (nestedToken) =>
+                nestedToken?.flatMap(
+                  (token) =>
+                    token?.tokens?.map((underlying) => ({
+                      symbol: underlying?.symbol || '',
+                      avatarValue: underlying?.iconUrl || '',
+                    })) || [],
+                ) || [],
+            ) || [],
+        )
+        .filter(Boolean)
+        .map((item) => [item.symbol, item]), // Use symbol as the key for uniqueness
+    ).values(),
+  );
+
+  // Ensure 'ETH' or 'WETH' is at position 1
+  const symbolPriority = ['ETH', 'WETH'];
+  const firstTokenIndex = iconsAndSymbols.findIndex((item) =>
+    symbolPriority.includes(item.symbol),
+  );
+
+  if (firstTokenIndex > -1) {
+    const [firstItem] = iconsAndSymbols.splice(firstTokenIndex, 1);
+    iconsAndSymbols.unshift(firstItem);
+  }
+
+  return iconsAndSymbols;
+};
path: ui/components/app/assets/util/extractIconAndSymbol.ts
user: login: jpsains
body: I expect we will move this logic into the deficontroller soon as its need by both mobile and extension
created_at: 2025-05-15T14:50:15Z
author_association: CONTRIBUTOR
path: development/circular-deps.jsonc
user: login: HowardBraham
body: @jpsains You have increased the number of circular dependences, which is not okay
created_at: 2025-05-15T15:52:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -14,26 +14,32 @@ import {
   getMultichainIsEvm,
 } from '../../../../../selectors/multichain';
 import { getNetworkConfigurationsByChainId } from '../../../../../../shared/modules/selectors/networks';
-import { TokenFiatDisplayInfo } from '../../types';
 
-type TokenCellBadgeProps = {
-  token: TokenFiatDisplayInfo;
+type AssetCellBadgeProps = {
+  chainId: `0x${string}` | `${string}:${string}`;
+  isNative?: boolean;
+  tokenImage: string;
+  symbol: string;
 };
 
-export const TokenCellBadge = React.memo(
-  ({ token }: TokenCellBadgeProps) => {
+export const AssetCellBadge = React.memo(
+  ({ chainId, isNative, tokenImage, symbol }: AssetCellBadgeProps) => {
     const isEvm = useSelector(getMultichainIsEvm);
     const allNetworks = useSelector(getNetworkConfigurationsByChainId);
 
+    const avatarTokenSrc =
+      isEvm && isNative ? getNativeCurrencyForChain(chainId) : tokenImage;
+    // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31880
+    // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+    const badgeWrapperSrc = getImageForChainId(chainId) || undefined;
path: ui/components/app/assets/asset-list/cells/asset-cell-badge.tsx
user: login: Prithpal-Sooriya
body: nit (we can leave it) - since this was moved, we could potentially fix?
```suggestion
    const badgeWrapperSrc = getImageForChainId(chainId) ?? undefined;
```
created_at: 2025-05-15T16:43:05Z
author_association: CONTRIBUTOR
path: ui/components/app/assets/asset-list/cells/generic-asset-cell-layout.tsx
user: login: Prithpal-Sooriya
body: Really nice cleanup!
created_at: 2025-05-15T16:49:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -82,16 +103,78 @@ const render = () => {
 describe('DefiList', () => {
   it('renders DeFiList component and shows control bar', async () => {
     await act(async () => {
-      render();
+      render('with-positions');
path: ui/components/app/assets/defi-list/defi-tab.test.tsx
user: login: Prithpal-Sooriya
body: Nice reusable render logic, helps the readability of these tests.
created_at: 2025-05-15T16:57:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,88 +74,33 @@ export default function TokenCell({
     return null;
   }
 
-  const PrimaryDisplay = () =>
-    TokenCellPrimaryDisplayOverride ? (
-      <TokenCellPrimaryDisplayOverride />
-    ) : (
-      <TokenCellPrimaryDisplay
-        token={{ ...token, ...tokenDisplayInfo }}
-        privacyMode={privacyMode}
-      />
-    );
-
   return (
-    <Box
-      display={Display.Flex}
-      flexDirection={FlexDirection.Row}
-      width={BlockSize.Full}
-      height={BlockSize.Full}
-      gap={4}
-    >
-      <Box
-        as="a"
-        onClick={(e?: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
-          e?.preventDefault();
-
-          if (!onClick || showScamWarningModal) {
-            return;
-          }
-
-          onClick();
-        }}
-        display={Display.Flex}
-        flexDirection={FlexDirection.Row}
-        paddingTop={2}
-        paddingBottom={2}
-        paddingLeft={4}
-        paddingRight={4}
-        width={BlockSize.Full}
-        style={{
-          height: 62,
-          cursor: onClick ? 'pointer' : 'auto',
-          backgroundColor:
-            !disableHover && isHovered
-              ? 'var(--color-background-default-hover)'
-              : 'transparent',
-          transition: 'background-color 0.2s ease-in-out',
-        }}
-        onMouseEnter={() => !disableHover && setIsHovered(true)}
-        onMouseLeave={() => !disableHover && setIsHovered(false)}
-        data-testid="multichain-token-list-button"
-      >
-        <TokenCellBadge token={{ ...token, ...tokenDisplayInfo }} />
-        <Box
-          display={Display.Flex}
-          flexDirection={FlexDirection.Column}
-          width={BlockSize.Full}
-          style={{ flexGrow: 1, overflow: 'hidden' }}
-          justifyContent={JustifyContent.center}
-        >
-          <Box
-            display={Display.Flex}
-            flexDirection={FlexDirection.Row}
-            justifyContent={JustifyContent.spaceBetween}
-          >
-            <TokenCellTitle token={{ ...token, ...tokenDisplayInfo }} />
-            <TokenCellSecondaryDisplay
-              token={{ ...token, ...tokenDisplayInfo }}
-              handleScamWarningModal={handleScamWarningModal}
-              privacyMode={privacyMode}
-            />
-          </Box>
-
-          <Box
-            display={Display.Flex}
-            flexDirection={FlexDirection.Row}
-            justifyContent={JustifyContent.spaceBetween}
-          >
-            <TokenCellPercentChange token={{ ...token, ...tokenDisplayInfo }} />
-            <PrimaryDisplay />
-          </Box>
-        </Box>
-      </Box>
-      {/* scam warning modal, this should be higher up in the component tree */}
-      {isEvm && showScamWarningModal ? (
+    <>
+      <GenericAssetCellLayout
+        onClick={showScamWarningModal ? undefined : onClick}
+        disableHover={disableHover}
+        badge={<AssetCellBadge {...{ ...token, ...tokenDisplayInfo }} />}
path: ui/components/app/assets/token-cell/token-cell.tsx
user: login: Prithpal-Sooriya
body: I see that this was in the original logic, but yikes 🤣 

Can we move this into a variable since it is used in a few places?

```ts
const fullToken = useMemo(() => ({
  ...token,
  ...tokenDisplayInfo
}), [token, tokenDisplayInfo])
```
created_at: 2025-05-15T17:00:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,10 @@
+export const buildSymbolGroup = (symbols: string[]): string => {
+  if (symbols.length === 1) {
+    return `${symbols[0]} only`;
+  } else if (symbols.length === 2) {
+    return `${symbols[0]} +${symbols.length - 1} other`;
+  } else if (symbols.length > 2) {
+    return `${symbols[0]} +${symbols.length - 1} others`;
+  }
+  return '';
+};
path: ui/components/app/assets/util/buildSymbolGroup.ts
user: login: Prithpal-Sooriya
body: nit - since we are returning in each block, we don't need to else-if/else statements - can just use separate if statements.

This is a nice separate function though. [In mobile](https://github.com/MetaMask/metamask-mobile/pull/13925#discussion_r2081419734) we used an intermediate obj to avoid nested ternaries 😄 

created_at: 2025-05-15T17:06:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,49 @@
+import { GroupedDeFiPositions } from '@metamask/assets-controllers';
+
+/**
+ * Extracts unique token icons and symbols from nested protocol position data, and orders by ETH or WETH.
+ * This function is used within `useMemo` based on `protocolPositions`
+ *
+ * @param protocolPositions
+ */
+export const extractUniqueIconAndSymbols = (
+  protocolPositions: GroupedDeFiPositions['protocols'][keyof GroupedDeFiPositions['protocols']],
+) => {
+  if (!protocolPositions?.positionTypes) {
+    return [];
+  }
+
+  const iconsAndSymbols = Array.from(
+    new Map(
+      Object.values(protocolPositions.positionTypes)
+        .flatMap(
+          (displayTokens) =>
+            displayTokens?.positions?.flatMap(
+              (nestedToken) =>
+                nestedToken?.flatMap(
path: ui/components/app/assets/util/extractIconAndSymbol.ts
user: login: Prithpal-Sooriya
body: Lol, fair enough.
created_at: 2025-05-15T17:06:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,46 @@
 import { Driver } from '../../webdriver/driver';
-import TokenList from './token-list';
 
-class DeFiTab extends TokenList {
+class DeFiToken {
   protected readonly driver: Driver;
 
+  protected readonly tokenListItemTokenName =
+    '[data-testid="multichain-token-list-item-token-name"]';
+
+  protected readonly tokenListItemSecondaryValue =
+    '[data-testid="defi-list-market-value"]';
+
+  constructor(driver: Driver) {
+    this.driver = driver;
+  }
+
+  async check_tokenMarketValue(tokenListItemSecondaryValue: string) {
+    console.log(
+      'Check if token market value is displayed on token list item',
+      tokenListItemSecondaryValue,
+    );
+    await this.driver.waitForSelector({
+      css: this.tokenListItemSecondaryValue,
+      text: tokenListItemSecondaryValue,
+    });
+  }
+
+  async check_tokenName(tokenName: string) {
+    console.log(
+      'Check if token name is displayed on token list item',
+      tokenName,
+    );
path: test/e2e/page-objects/pages/defi-tab.ts
user: login: sahar-fehri
body: Nit; console logs :p 
created_at: 2025-05-15T17:45:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,46 @@
 import { Driver } from '../../webdriver/driver';
-import TokenList from './token-list';
 
-class DeFiTab extends TokenList {
+class DeFiToken {
   protected readonly driver: Driver;
 
+  protected readonly tokenListItemTokenName =
+    '[data-testid="multichain-token-list-item-token-name"]';
+
+  protected readonly tokenListItemSecondaryValue =
+    '[data-testid="defi-list-market-value"]';
+
+  constructor(driver: Driver) {
+    this.driver = driver;
+  }
+
+  async check_tokenMarketValue(tokenListItemSecondaryValue: string) {
+    console.log(
+      'Check if token market value is displayed on token list item',
+      tokenListItemSecondaryValue,
path: test/e2e/page-objects/pages/defi-tab.ts
user: login: sahar-fehri
body: Nit: log :D 
created_at: 2025-05-15T17:46:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -45,6 +45,17 @@
     "ui/components/multichain/account-overview/index.js",
     "ui/components/multichain/index.js"
   ],
+  [
+    "ui/components/app/assets/defi-list/cells/defi-protocol-cell.tsx",
+    "ui/components/app/assets/defi-list/defi-list.tsx",
+    "ui/components/app/assets/defi-list/defi-tab.tsx",
+    "ui/components/multichain/account-overview/account-overview-eth.tsx",
+    "ui/components/multichain/account-overview/account-overview-layout.tsx",
+    "ui/components/multichain/account-overview/account-overview-tabs.tsx",
+    "ui/components/multichain/account-overview/account-overview.tsx",
+    "ui/components/multichain/account-overview/index.js",
+    "ui/components/multichain/index.js"
path: development/circular-deps.jsonc
user: login: bergarces
body: You don't need this if you import whatever is causing this directly, instead of using the barrel file.
created_at: 2025-05-16T08:54:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,46 @@
 import { Driver } from '../../webdriver/driver';
-import TokenList from './token-list';
 
-class DeFiTab extends TokenList {
+class DeFiToken {
   protected readonly driver: Driver;
 
+  protected readonly tokenListItemTokenName =
+    '[data-testid="multichain-token-list-item-token-name"]';
+
+  protected readonly tokenListItemSecondaryValue =
+    '[data-testid="defi-list-market-value"]';
+
+  constructor(driver: Driver) {
+    this.driver = driver;
+  }
+
+  async check_tokenMarketValue(tokenListItemSecondaryValue: string) {
+    console.log(
+      'Check if token market value is displayed on token list item',
+      tokenListItemSecondaryValue,
+    );
+    await this.driver.waitForSelector({
+      css: this.tokenListItemSecondaryValue,
+      text: tokenListItemSecondaryValue,
+    });
+  }
+
+  async check_tokenName(tokenName: string) {
+    console.log(
+      'Check if token name is displayed on token list item',
+      tokenName,
+    );
path: test/e2e/page-objects/pages/defi-tab.ts
user: login: jpsains
body: Its an e2e test mate :) - the tests have console logs
created_at: 2025-05-20T10:15:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,46 @@
 import { Driver } from '../../webdriver/driver';
-import TokenList from './token-list';
 
-class DeFiTab extends TokenList {
+class DeFiToken {
   protected readonly driver: Driver;
 
+  protected readonly tokenListItemTokenName =
+    '[data-testid="multichain-token-list-item-token-name"]';
+
+  protected readonly tokenListItemSecondaryValue =
+    '[data-testid="defi-list-market-value"]';
+
+  constructor(driver: Driver) {
+    this.driver = driver;
+  }
+
+  async check_tokenMarketValue(tokenListItemSecondaryValue: string) {
+    console.log(
+      'Check if token market value is displayed on token list item',
+      tokenListItemSecondaryValue,
path: test/e2e/page-objects/pages/defi-tab.ts
user: login: jpsains
body: Its an e2e test mate :) - the tests have console logs
created_at: 2025-05-20T10:17:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -45,6 +45,17 @@
     "ui/components/multichain/account-overview/index.js",
     "ui/components/multichain/index.js"
   ],
+  [
+    "ui/components/app/assets/defi-list/cells/defi-protocol-cell.tsx",
+    "ui/components/app/assets/defi-list/defi-list.tsx",
+    "ui/components/app/assets/defi-list/defi-tab.tsx",
+    "ui/components/multichain/account-overview/account-overview-eth.tsx",
+    "ui/components/multichain/account-overview/account-overview-layout.tsx",
+    "ui/components/multichain/account-overview/account-overview-tabs.tsx",
+    "ui/components/multichain/account-overview/account-overview.tsx",
+    "ui/components/multichain/account-overview/index.js",
+    "ui/components/multichain/index.js"
path: development/circular-deps.jsonc
user: login: Prithpal-Sooriya
body: LOL, wtf barrel files 🤦🏾 
created_at: 2025-05-20T17:35:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,96 @@
+import React, { ReactNode, useState } from 'react';
+import { Box } from '../../../../component-library';
+import {
+  Display,
+  FlexDirection,
+  BlockSize,
+  JustifyContent,
+} from '../../../../../helpers/constants/design-system';
+
+type GenericAssetCellLayoutProps = {
+  onClick?: () => void;
+  disableHover?: boolean;
+  badge: ReactNode;
+  headerLeftDisplay: ReactNode;
+  headerRightDisplay: ReactNode;
+  footerLeftDisplay: ReactNode;
+  footerRightDisplay: ReactNode;
+};
+
+export default function GenericAssetCellLayout({
+  onClick,
+  disableHover = false,
+  badge,
+  headerLeftDisplay,
+  headerRightDisplay,
+  footerLeftDisplay,
+  footerRightDisplay,
+}: GenericAssetCellLayoutProps) {
+  const [isHovered, setIsHovered] = useState(false);
+
+  return (
+    <Box
+      display={Display.Flex}
+      flexDirection={FlexDirection.Row}
+      width={BlockSize.Full}
+      height={BlockSize.Full}
+      gap={4}
+    >
+      <Box
+        as="a"
+        onClick={(e?: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
path: ui/components/app/assets/asset-list/cells/generic-asset-cell-layout.tsx
user: login: Prithpal-Sooriya
body: Generic note for visibility. This was the original component that we moved. We can discuss with DS team if there is a better component we can use in future.
created_at: 2025-05-20T17:38:15Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-14T09:15:04Z
body: **CLA Signature Action:** All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.
author_association: CONTRIBUTOR
user: login: metamaskbot
created_at: 2025-05-15T15:07:30Z
body: <details><summary>Builds ready [fd24a3e]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (beta): <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15047709845/builds-beta/metamask-beta-chrome-12.17.3-beta.0.zip">chrome</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-test/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-test-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-test-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>bundle size: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15047709845/bundle-size/bundle_size.json">Bundle Size Stats</a></li>
<li>user-actions-benchmark: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15047709845/benchmarks/benchmark-chrome-browserify-userActions.json">User Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15047709845/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15047709845/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/jobs/4893530/artifacts/">all CircleCI artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/common-14.html">14</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/ui-13.html">13</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/03046848-9eac-4d89-a0fd-b03e3e471b1d/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>UI Startup Metrics (1223 ± 74 ms)</summary><table><thead><tr><th>Platform</th><th>BuildType</th><th>Page</th><th>Metric</th><th>Mean (ms)</th><th>Min (ms)</th><th>Max (ms)</th><th>Std Dev (ms)</th><th>P 75 (ms)</th><th>P 95 (ms)</th></tr></thead><tbody><tr><td rowspan="22">Chrome</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1223</td><td align="right">1073</td><td align="right">1537</td><td align="right">74</td><td align="right">1270</td><td align="right">1339</td></tr><tr><td>load</td><td align="right">1074</td><td align="right">946</td><td align="right">1342</td><td align="right">70</td><td align="right">1119</td><td align="right">1187</td></tr><tr><td>domContentLoaded</td><td align="right">1068</td><td align="right">938</td><td align="right">1338</td><td align="right">70</td><td align="right">1111</td><td align="right">1182</td></tr><tr><td>domInteractive</td><td align="right">16</td><td align="right">13</td><td align="right">29</td><td align="right">3</td><td align="right">16</td><td align="right">24</td></tr><tr><td>firstPaint</td><td align="right">769</td><td align="right">66</td><td align="right">1269</td><td align="right">424</td><td align="right">1106</td><td align="right">1175</td></tr><tr><td>backgroundConnect</td><td align="right">8</td><td align="right">4</td><td align="right">25</td><td align="right">4</td><td align="right">8</td><td align="right">21</td></tr><tr><td>firstReactRender</td><td align="right">20</td><td align="right">15</td><td align="right">39</td><td align="right">5</td><td align="right">20</td><td align="right">32</td></tr><tr><td>getState</td><td align="right">14</td><td align="right">5</td><td align="right">38</td><td align="right">7</td><td align="right">20</td><td align="right">27</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">825</td><td align="right">704</td><td align="right">1080</td><td align="right">68</td><td align="right">863</td><td align="right">943</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">5</td><td align="right">23</td><td align="right">3</td><td align="right">8</td><td align="right">14</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">2131</td><td align="right">1694</td><td align="right">2499</td><td align="right">173</td><td align="right">2239</td><td align="right">2363</td></tr><tr><td>load</td><td align="right">1670</td><td align="right">1316</td><td align="right">2055</td><td align="right">147</td><td align="right">1742</td><td align="right">1925</td></tr><tr><td>domContentLoaded</td><td align="right">1662</td><td align="right">1309</td><td align="right">2051</td><td align="right">144</td><td align="right">1737</td><td align="right">1900</td></tr><tr><td>domInteractive</td><td align="right">15</td><td align="right">11</td><td align="right">74</td><td align="right">10</td><td align="right">13</td><td align="right">43</td></tr><tr><td>firstPaint</td><td align="right">163</td><td align="right">70</td><td align="right">402</td><td align="right">65</td><td align="right">175</td><td align="right">286</td></tr><tr><td>backgroundConnect</td><td align="right">29</td><td align="right">9</td><td align="right">246</td><td align="right">29</td><td align="right">33</td><td align="right">57</td></tr><tr><td>firstReactRender</td><td align="right">153</td><td align="right">42</td><td align="right">340</td><td align="right">101</td><td align="right">259</td><td align="right">333</td></tr><tr><td>getState</td><td align="right">13</td><td align="right">4</td><td align="right">163</td><td align="right">16</td><td align="right">15</td><td align="right">27</td></tr><tr><td>initialActions</td><td align="right">3</td><td align="right">1</td><td align="right">8</td><td align="right">1</td><td align="right">4</td><td align="right">5</td></tr><tr><td>loadScripts</td><td align="right">1657</td><td align="right">1307</td><td align="right">2049</td><td align="right">145</td><td align="right">1734</td><td align="right">1899</td></tr><tr><td>setupStore</td><td align="right">17</td><td align="right">7</td><td align="right">71</td><td align="right">9</td><td align="right">21</td><td align="right">32</td></tr><tr><td rowspan="22">Firefox</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1300</td><td align="right">1126</td><td align="right">1800</td><td align="right">141</td><td align="right">1334</td><td align="right">1656</td></tr><tr><td>load</td><td align="right">1158</td><td align="right">1001</td><td align="right">1677</td><td align="right">134</td><td align="right">1193</td><td align="right">1440</td></tr><tr><td>domContentLoaded</td><td align="right">1158</td><td align="right">1001</td><td align="right">1676</td><td align="right">134</td><td align="right">1193</td><td align="right">1440</td></tr><tr><td>domInteractive</td><td align="right">98</td><td align="right">40</td><td align="right">408</td><td align="right">39</td><td align="right">105</td><td align="right">141</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">21</td><td align="right">13</td><td align="right">148</td><td align="right">15</td><td align="right">21</td><td align="right">46</td></tr><tr><td>firstReactRender</td><td align="right">23</td><td align="right">19</td><td align="right">53</td><td align="right">7</td><td align="right">22</td><td align="right">49</td></tr><tr><td>getState</td><td align="right">10</td><td align="right">4</td><td align="right">214</td><td align="right">26</td><td align="right">8</td><td align="right">10</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1139</td><td align="right">967</td><td align="right">1648</td><td align="right">131</td><td align="right">1179</td><td align="right">1418</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">4</td><td align="right">180</td><td align="right">18</td><td align="right">6</td><td align="right">11</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1553</td><td align="right">1334</td><td align="right">2023</td><td align="right">141</td><td align="right">1616</td><td align="right">1868</td></tr><tr><td>load</td><td align="right">1333</td><td align="right">1170</td><td align="right">1754</td><td align="right">125</td><td align="right">1408</td><td align="right">1615</td></tr><tr><td>domContentLoaded</td><td align="right">1332</td><td align="right">1169</td><td align="right">1753</td><td align="right">125</td><td align="right">1408</td><td align="right">1615</td></tr><tr><td>domInteractive</td><td align="right">81</td><td align="right">34</td><td align="right">289</td><td align="right">28</td><td align="right">90</td><td align="right">129</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">22</td><td align="right">14</td><td align="right">58</td><td align="right">7</td><td align="right">24</td><td align="right">39</td></tr><tr><td>firstReactRender</td><td align="right">34</td><td align="right">30</td><td align="right">49</td><td align="right">4</td><td align="right">36</td><td align="right">45</td></tr><tr><td>getState</td><td align="right">9</td><td align="right">5</td><td align="right">31</td><td align="right">4</td><td align="right">9</td><td align="right">14</td></tr><tr><td>initialActions</td><td align="right">1</td><td align="right">0</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1314</td><td align="right">1155</td><td align="right">1724</td><td align="right">124</td><td align="right">1391</td><td align="right">1592</td></tr><tr><td>setupStore</td><td align="right">10</td><td align="right">5</td><td align="right">235</td><td align="right">23</td><td align="right">8</td><td align="right">10</td></tr></tbody></table>Benchmark value 1075 exceeds gate value 1070 for chrome browserify home mean load<br>
Benchmark value 1068 exceeds gate value 1061 for chrome browserify home mean domContentLoaded<br>
Benchmark value 1182 exceeds gate value 1180 for chrome browserify home p95 domContentLoaded<br>
Benchmark value 22 exceeds gate value 18 for chrome browserify home p95 backgroundConnect<br>
Benchmark value 944 exceeds gate value 940 for chrome browserify home p95 loadScripts<br>
<b>Sum of mean exceeds: 12ms | Sum of p95 exceeds: 10ms<br>
Sum of all benchmark exceeds: 22ms</b><br>
</details>

<details><summary>Bundle size diffs [🚨 Warning! Bundle size has increased!]</summary><ul><li>background: 1024 Bytes (0.02%)</li>
<li>ui: 7.54 KiB (0.11%)</li>
<li>common: 52 Bytes (0%)</li></ul></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-05-15T16:23:31Z
body: <details><summary>Builds ready [e5d8b5a]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (beta): <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15049462928/builds-beta/metamask-beta-chrome-12.17.3-beta.0.zip">chrome</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-test/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-test-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-test-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>bundle size: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15049462928/bundle-size/bundle_size.json">Bundle Size Stats</a></li>
<li>user-actions-benchmark: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15049462928/benchmarks/benchmark-chrome-browserify-userActions.json">User Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15049462928/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15049462928/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/jobs/4894034/artifacts/">all CircleCI artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/common-14.html">14</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/ui-13.html">13</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/9187cdc6-cc7c-48ae-9144-8317d634c102/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>UI Startup Metrics (1173 ± 54 ms)</summary><table><thead><tr><th>Platform</th><th>BuildType</th><th>Page</th><th>Metric</th><th>Mean (ms)</th><th>Min (ms)</th><th>Max (ms)</th><th>Std Dev (ms)</th><th>P 75 (ms)</th><th>P 95 (ms)</th></tr></thead><tbody><tr><td rowspan="22">Chrome</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1173</td><td align="right">1083</td><td align="right">1361</td><td align="right">54</td><td align="right">1207</td><td align="right">1269</td></tr><tr><td>load</td><td align="right">1025</td><td align="right">946</td><td align="right">1185</td><td align="right">46</td><td align="right">1055</td><td align="right">1104</td></tr><tr><td>domContentLoaded</td><td align="right">1019</td><td align="right">930</td><td align="right">1179</td><td align="right">47</td><td align="right">1047</td><td align="right">1099</td></tr><tr><td>domInteractive</td><td align="right">16</td><td align="right">13</td><td align="right">25</td><td align="right">3</td><td align="right">16</td><td align="right">24</td></tr><tr><td>firstPaint</td><td align="right">716</td><td align="right">73</td><td align="right">1117</td><td align="right">399</td><td align="right">1035</td><td align="right">1086</td></tr><tr><td>backgroundConnect</td><td align="right">7</td><td align="right">4</td><td align="right">27</td><td align="right">4</td><td align="right">7</td><td align="right">21</td></tr><tr><td>firstReactRender</td><td align="right">19</td><td align="right">14</td><td align="right">46</td><td align="right">4</td><td align="right">19</td><td align="right">29</td></tr><tr><td>getState</td><td align="right">14</td><td align="right">6</td><td align="right">30</td><td align="right">7</td><td align="right">20</td><td align="right">26</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">781</td><td align="right">691</td><td align="right">941</td><td align="right">47</td><td align="right">806</td><td align="right">855</td></tr><tr><td>setupStore</td><td align="right">7</td><td align="right">4</td><td align="right">18</td><td align="right">2</td><td align="right">8</td><td align="right">11</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">2140</td><td align="right">1731</td><td align="right">2466</td><td align="right">187</td><td align="right">2283</td><td align="right">2363</td></tr><tr><td>load</td><td align="right">1673</td><td align="right">1353</td><td align="right">2066</td><td align="right">143</td><td align="right">1769</td><td align="right">1848</td></tr><tr><td>domContentLoaded</td><td align="right">1666</td><td align="right">1349</td><td align="right">2062</td><td align="right">142</td><td align="right">1762</td><td align="right">1838</td></tr><tr><td>domInteractive</td><td align="right">15</td><td align="right">12</td><td align="right">61</td><td align="right">8</td><td align="right">13</td><td align="right">38</td></tr><tr><td>firstPaint</td><td align="right">160</td><td align="right">66</td><td align="right">316</td><td align="right">54</td><td align="right">181</td><td align="right">275</td></tr><tr><td>backgroundConnect</td><td align="right">26</td><td align="right">9</td><td align="right">64</td><td align="right">13</td><td align="right">29</td><td align="right">53</td></tr><tr><td>firstReactRender</td><td align="right">147</td><td align="right">43</td><td align="right">348</td><td align="right">96</td><td align="right">259</td><td align="right">313</td></tr><tr><td>getState</td><td align="right">16</td><td align="right">4</td><td align="right">317</td><td align="right">34</td><td align="right">16</td><td align="right">25</td></tr><tr><td>initialActions</td><td align="right">3</td><td align="right">1</td><td align="right">6</td><td align="right">1</td><td align="right">3</td><td align="right">5</td></tr><tr><td>loadScripts</td><td align="right">1661</td><td align="right">1347</td><td align="right">2039</td><td align="right">142</td><td align="right">1758</td><td align="right">1831</td></tr><tr><td>setupStore</td><td align="right">15</td><td align="right">6</td><td align="right">36</td><td align="right">6</td><td align="right">19</td><td align="right">29</td></tr><tr><td rowspan="22">Firefox</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1311</td><td align="right">1144</td><td align="right">1638</td><td align="right">119</td><td align="right">1363</td><td align="right">1569</td></tr><tr><td>load</td><td align="right">1159</td><td align="right">1021</td><td align="right">1491</td><td align="right">100</td><td align="right">1209</td><td align="right">1364</td></tr><tr><td>domContentLoaded</td><td align="right">1159</td><td align="right">1020</td><td align="right">1491</td><td align="right">101</td><td align="right">1209</td><td align="right">1364</td></tr><tr><td>domInteractive</td><td align="right">97</td><td align="right">34</td><td align="right">178</td><td align="right">30</td><td align="right">108</td><td align="right">160</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">21</td><td align="right">12</td><td align="right">71</td><td align="right">10</td><td align="right">22</td><td align="right">48</td></tr><tr><td>firstReactRender</td><td align="right">23</td><td align="right">19</td><td align="right">56</td><td align="right">7</td><td align="right">23</td><td align="right">45</td></tr><tr><td>getState</td><td align="right">15</td><td align="right">4</td><td align="right">200</td><td align="right">37</td><td align="right">8</td><td align="right">27</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1142</td><td align="right">1004</td><td align="right">1464</td><td align="right">98</td><td align="right">1193</td><td align="right">1345</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">4</td><td align="right">187</td><td align="right">18</td><td align="right">6</td><td align="right">12</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1517</td><td align="right">1344</td><td align="right">2135</td><td align="right">154</td><td align="right">1562</td><td align="right">1912</td></tr><tr><td>load</td><td align="right">1291</td><td align="right">1163</td><td align="right">1843</td><td align="right">116</td><td align="right">1350</td><td align="right">1558</td></tr><tr><td>domContentLoaded</td><td align="right">1290</td><td align="right">1163</td><td align="right">1843</td><td align="right">116</td><td align="right">1349</td><td align="right">1558</td></tr><tr><td>domInteractive</td><td align="right">77</td><td align="right">54</td><td align="right">158</td><td align="right">17</td><td align="right">82</td><td align="right">104</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">24</td><td align="right">14</td><td align="right">137</td><td align="right">15</td><td align="right">24</td><td align="right">45</td></tr><tr><td>firstReactRender</td><td align="right">34</td><td align="right">28</td><td align="right">51</td><td align="right">5</td><td align="right">36</td><td align="right">45</td></tr><tr><td>getState</td><td align="right">16</td><td align="right">4</td><td align="right">247</td><td align="right">36</td><td align="right">9</td><td align="right">34</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1271</td><td align="right">1147</td><td align="right">1823</td><td align="right">113</td><td align="right">1328</td><td align="right">1488</td></tr><tr><td>setupStore</td><td align="right">14</td><td align="right">4</td><td align="right">256</td><td align="right">36</td><td align="right">8</td><td align="right">35</td></tr></tbody></table>Benchmark value 22 exceeds gate value 18 for chrome browserify home p95 backgroundConnect<br>
Benchmark value 15 exceeds gate value 11 for firefox browserify home mean getState<br>
Benchmark value 27 exceeds gate value 24 for firefox browserify home p95 getState<br>
Benchmark value 16 exceeds gate value 15 for firefox webpack home mean getState<br>
Benchmark value 15 exceeds gate value 13 for firefox webpack home mean setupStore<br>
Benchmark value 34 exceeds gate value 32 for firefox webpack home p95 getState<br>
Benchmark value 35 exceeds gate value 28 for firefox webpack home p95 setupStore<br>
<b>Sum of mean exceeds: 7ms | Sum of p95 exceeds: 16ms<br>
Sum of all benchmark exceeds: 23ms</b><br>
</details>

<details><summary>Bundle size diffs [🚨 Warning! Bundle size has increased!]</summary><ul><li>background: 1024 Bytes (0.02%)</li>
<li>ui: 7.49 KiB (0.11%)</li>
<li>common: 52 Bytes (0%)</li></ul></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-05-20T11:09:01Z
body: <details><summary>Builds ready [5bc8a6f]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (beta): <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15135314658/builds-beta/metamask-beta-chrome-12.17.3-beta.0.zip">chrome</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-test/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-test-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-test-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>bundle size: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15135314658/bundle-size/bundle_size.json">Bundle Size Stats</a></li>
<li>user-actions-benchmark: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15135314658/benchmarks/benchmark-chrome-browserify-userActions.json">User Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15135314658/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15135314658/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/jobs/4901594/artifacts/">all CircleCI artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/common-14.html">14</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/ui-13.html">13</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/aedf58ec-37d4-4236-a82f-f985d854e48a/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>UI Startup Metrics (1170 ± 51 ms)</summary><table><thead><tr><th>Platform</th><th>BuildType</th><th>Page</th><th>Metric</th><th>Mean (ms)</th><th>Min (ms)</th><th>Max (ms)</th><th>Std Dev (ms)</th><th>P 75 (ms)</th><th>P 95 (ms)</th></tr></thead><tbody><tr><td rowspan="22">Chrome</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1170</td><td align="right">1064</td><td align="right">1313</td><td align="right">51</td><td align="right">1203</td><td align="right">1260</td></tr><tr><td>load</td><td align="right">1008</td><td align="right">921</td><td align="right">1124</td><td align="right">48</td><td align="right">1039</td><td align="right">1088</td></tr><tr><td>domContentLoaded</td><td align="right">1000</td><td align="right">915</td><td align="right">1120</td><td align="right">48</td><td align="right">1030</td><td align="right">1082</td></tr><tr><td>domInteractive</td><td align="right">16</td><td align="right">12</td><td align="right">79</td><td align="right">9</td><td align="right">15</td><td align="right">24</td></tr><tr><td>firstPaint</td><td align="right">767</td><td align="right">75</td><td align="right">1126</td><td align="right">376</td><td align="right">1031</td><td align="right">1088</td></tr><tr><td>backgroundConnect</td><td align="right">9</td><td align="right">4</td><td align="right">50</td><td align="right">7</td><td align="right">8</td><td align="right">27</td></tr><tr><td>firstReactRender</td><td align="right">19</td><td align="right">13</td><td align="right">44</td><td align="right">6</td><td align="right">20</td><td align="right">33</td></tr><tr><td>getState</td><td align="right">15</td><td align="right">5</td><td align="right">69</td><td align="right">10</td><td align="right">20</td><td align="right">33</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">764</td><td align="right">672</td><td align="right">884</td><td align="right">47</td><td align="right">793</td><td align="right">843</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">5</td><td align="right">23</td><td align="right">2</td><td align="right">8</td><td align="right">12</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">2086</td><td align="right">1672</td><td align="right">2601</td><td align="right">229</td><td align="right">2246</td><td align="right">2428</td></tr><tr><td>load</td><td align="right">1599</td><td align="right">1246</td><td align="right">1954</td><td align="right">172</td><td align="right">1727</td><td align="right">1867</td></tr><tr><td>domContentLoaded</td><td align="right">1592</td><td align="right">1240</td><td align="right">1941</td><td align="right">170</td><td align="right">1720</td><td align="right">1858</td></tr><tr><td>domInteractive</td><td align="right">15</td><td align="right">11</td><td align="right">53</td><td align="right">8</td><td align="right">13</td><td align="right">39</td></tr><tr><td>firstPaint</td><td align="right">163</td><td align="right">67</td><td align="right">351</td><td align="right">59</td><td align="right">206</td><td align="right">281</td></tr><tr><td>backgroundConnect</td><td align="right">27</td><td align="right">12</td><td align="right">424</td><td align="right">42</td><td align="right">24</td><td align="right">45</td></tr><tr><td>firstReactRender</td><td align="right">144</td><td align="right">43</td><td align="right">358</td><td align="right">107</td><td align="right">277</td><td align="right">328</td></tr><tr><td>getState</td><td align="right">17</td><td align="right">4</td><td align="right">377</td><td align="right">47</td><td align="right">12</td><td align="right">34</td></tr><tr><td>initialActions</td><td align="right">3</td><td align="right">1</td><td align="right">7</td><td align="right">1</td><td align="right">3</td><td align="right">5</td></tr><tr><td>loadScripts</td><td align="right">1589</td><td align="right">1237</td><td align="right">1931</td><td align="right">168</td><td align="right">1717</td><td align="right">1847</td></tr><tr><td>setupStore</td><td align="right">37</td><td align="right">6</td><td align="right">314</td><td align="right">76</td><td align="right">19</td><td align="right">298</td></tr><tr><td rowspan="22">Firefox</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1366</td><td align="right">1164</td><td align="right">1930</td><td align="right">138</td><td align="right">1435</td><td align="right">1663</td></tr><tr><td>load</td><td align="right">1206</td><td align="right">1032</td><td align="right">1790</td><td align="right">130</td><td align="right">1265</td><td align="right">1472</td></tr><tr><td>domContentLoaded</td><td align="right">1206</td><td align="right">1032</td><td align="right">1790</td><td align="right">130</td><td align="right">1265</td><td align="right">1472</td></tr><tr><td>domInteractive</td><td align="right">99</td><td align="right">40</td><td align="right">184</td><td align="right">28</td><td align="right">106</td><td align="right">167</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">25</td><td align="right">13</td><td align="right">188</td><td align="right">22</td><td align="right">23</td><td align="right">33</td></tr><tr><td>firstReactRender</td><td align="right">23</td><td align="right">19</td><td align="right">53</td><td align="right">4</td><td align="right">24</td><td align="right">31</td></tr><tr><td>getState</td><td align="right">10</td><td align="right">5</td><td align="right">196</td><td align="right">19</td><td align="right">9</td><td align="right">12</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1185</td><td align="right">1004</td><td align="right">1774</td><td align="right">130</td><td align="right">1247</td><td align="right">1454</td></tr><tr><td>setupStore</td><td align="right">7</td><td align="right">4</td><td align="right">51</td><td align="right">7</td><td align="right">7</td><td align="right">23</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1509</td><td align="right">1320</td><td align="right">1820</td><td align="right">110</td><td align="right">1585</td><td align="right">1721</td></tr><tr><td>load</td><td align="right">1290</td><td align="right">1154</td><td align="right">1593</td><td align="right">107</td><td align="right">1377</td><td align="right">1506</td></tr><tr><td>domContentLoaded</td><td align="right">1290</td><td align="right">1153</td><td align="right">1593</td><td align="right">107</td><td align="right">1376</td><td align="right">1506</td></tr><tr><td>domInteractive</td><td align="right">78</td><td align="right">32</td><td align="right">136</td><td align="right">18</td><td align="right">86</td><td align="right">118</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">21</td><td align="right">14</td><td align="right">82</td><td align="right">7</td><td align="right">22</td><td align="right">31</td></tr><tr><td>firstReactRender</td><td align="right">34</td><td align="right">28</td><td align="right">47</td><td align="right">4</td><td align="right">36</td><td align="right">42</td></tr><tr><td>getState</td><td align="right">8</td><td align="right">4</td><td align="right">65</td><td align="right">6</td><td align="right">8</td><td align="right">11</td></tr><tr><td>initialActions</td><td align="right">1</td><td align="right">0</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1272</td><td align="right">1136</td><td align="right">1578</td><td align="right">107</td><td align="right">1357</td><td align="right">1487</td></tr><tr><td>setupStore</td><td align="right">9</td><td align="right">5</td><td align="right">78</td><td align="right">8</td><td align="right">8</td><td align="right">22</td></tr></tbody></table>Benchmark value 28 exceeds gate value 18 for chrome browserify home p95 backgroundConnect<br>
Benchmark value 37 exceeds gate value 32 for chrome webpack home mean setupStore<br>
Benchmark value 298 exceeds gate value 65 for chrome webpack home p95 setupStore<br>
Benchmark value 1663 exceeds gate value 1660 for firefox browserify home p95 uiStartup<br>
<b>Sum of mean exceeds: 5ms | Sum of p95 exceeds: 246ms<br>
Sum of all benchmark exceeds: 251ms</b><br>
</details>

<details><summary>Bundle size diffs [🚀 Bundle size reduced!]</summary><ul><li>background: -2.24 KiB (-0.04%)</li>
<li>ui: 11.43 KiB (0.16%)</li>
<li>common: -1.27 MiB (-13.82%)</li></ul></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-05-20T11:54:22Z
body: <details><summary>Builds ready [3c07176]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (beta): <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15136200391/builds-beta/metamask-beta-chrome-12.17.3-beta.0.zip">chrome</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-test/metamask-chrome-12.17.3.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-test-mv2/metamask-firefox-12.17.3.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-test-flask/metamask-flask-chrome-12.17.3-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.17.3-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>bundle size: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15136200391/bundle-size/bundle_size.json">Bundle Size Stats</a></li>
<li>user-actions-benchmark: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15136200391/benchmarks/benchmark-chrome-browserify-userActions.json">User Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15136200391/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15136200391/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/jobs/4901649/artifacts/">all CircleCI artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/common-14.html">14</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/ui-13.html">13</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/ac1f939b-4c5e-4a08-80b9-bb200f07b908/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>UI Startup Metrics (1255 ± 62 ms)</summary><table><thead><tr><th>Platform</th><th>BuildType</th><th>Page</th><th>Metric</th><th>Mean (ms)</th><th>Min (ms)</th><th>Max (ms)</th><th>Std Dev (ms)</th><th>P 75 (ms)</th><th>P 95 (ms)</th></tr></thead><tbody><tr><td rowspan="22">Chrome</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1255</td><td align="right">1128</td><td align="right">1417</td><td align="right">62</td><td align="right">1295</td><td align="right">1365</td></tr><tr><td>load</td><td align="right">1078</td><td align="right">943</td><td align="right">1230</td><td align="right">64</td><td align="right">1126</td><td align="right">1183</td></tr><tr><td>domContentLoaded</td><td align="right">1070</td><td align="right">934</td><td align="right">1220</td><td align="right">65</td><td align="right">1114</td><td align="right">1172</td></tr><tr><td>domInteractive</td><td align="right">17</td><td align="right">14</td><td align="right">39</td><td align="right">4</td><td align="right">17</td><td align="right">25</td></tr><tr><td>firstPaint</td><td align="right">779</td><td align="right">166</td><td align="right">1236</td><td align="right">417</td><td align="right">1104</td><td align="right">1180</td></tr><tr><td>backgroundConnect</td><td align="right">9</td><td align="right">4</td><td align="right">31</td><td align="right">5</td><td align="right">9</td><td align="right">25</td></tr><tr><td>firstReactRender</td><td align="right">20</td><td align="right">15</td><td align="right">54</td><td align="right">6</td><td align="right">21</td><td align="right">34</td></tr><tr><td>getState</td><td align="right">16</td><td align="right">5</td><td align="right">95</td><td align="right">11</td><td align="right">22</td><td align="right">29</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">822</td><td align="right">698</td><td align="right">986</td><td align="right">63</td><td align="right">866</td><td align="right">926</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">4</td><td align="right">34</td><td align="right">4</td><td align="right">9</td><td align="right">13</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">2161</td><td align="right">1717</td><td align="right">2633</td><td align="right">187</td><td align="right">2296</td><td align="right">2447</td></tr><tr><td>load</td><td align="right">1664</td><td align="right">1329</td><td align="right">1966</td><td align="right">132</td><td align="right">1742</td><td align="right">1914</td></tr><tr><td>domContentLoaded</td><td align="right">1657</td><td align="right">1325</td><td align="right">1953</td><td align="right">131</td><td align="right">1735</td><td align="right">1905</td></tr><tr><td>domInteractive</td><td align="right">16</td><td align="right">11</td><td align="right">67</td><td align="right">11</td><td align="right">13</td><td align="right">44</td></tr><tr><td>firstPaint</td><td align="right">166</td><td align="right">68</td><td align="right">334</td><td align="right">57</td><td align="right">194</td><td align="right">286</td></tr><tr><td>backgroundConnect</td><td align="right">23</td><td align="right">10</td><td align="right">111</td><td align="right">13</td><td align="right">26</td><td align="right">44</td></tr><tr><td>firstReactRender</td><td align="right">153</td><td align="right">43</td><td align="right">362</td><td align="right">111</td><td align="right">283</td><td align="right">346</td></tr><tr><td>getState</td><td align="right">21</td><td align="right">4</td><td align="right">370</td><td align="right">55</td><td align="right">14</td><td align="right">32</td></tr><tr><td>initialActions</td><td align="right">3</td><td align="right">1</td><td align="right">7</td><td align="right">1</td><td align="right">3</td><td align="right">5</td></tr><tr><td>loadScripts</td><td align="right">1654</td><td align="right">1324</td><td align="right">1942</td><td align="right">130</td><td align="right">1731</td><td align="right">1894</td></tr><tr><td>setupStore</td><td align="right">31</td><td align="right">6</td><td align="right">309</td><td align="right">62</td><td align="right">19</td><td align="right">259</td></tr><tr><td rowspan="22">Firefox</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1327</td><td align="right">1128</td><td align="right">1888</td><td align="right">129</td><td align="right">1377</td><td align="right">1596</td></tr><tr><td>load</td><td align="right">1183</td><td align="right">999</td><td align="right">1757</td><td align="right">128</td><td align="right">1239</td><td align="right">1449</td></tr><tr><td>domContentLoaded</td><td align="right">1183</td><td align="right">999</td><td align="right">1756</td><td align="right">128</td><td align="right">1239</td><td align="right">1448</td></tr><tr><td>domInteractive</td><td align="right">98</td><td align="right">37</td><td align="right">266</td><td align="right">33</td><td align="right">112</td><td align="right">162</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">28</td><td align="right">13</td><td align="right">243</td><td align="right">37</td><td align="right">22</td><td align="right">99</td></tr><tr><td>firstReactRender</td><td align="right">22</td><td align="right">20</td><td align="right">53</td><td align="right">5</td><td align="right">22</td><td align="right">27</td></tr><tr><td>getState</td><td align="right">7</td><td align="right">4</td><td align="right">38</td><td align="right">3</td><td align="right">8</td><td align="right">10</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1157</td><td align="right">986</td><td align="right">1728</td><td align="right">123</td><td align="right">1217</td><td align="right">1381</td></tr><tr><td>setupStore</td><td align="right">6</td><td align="right">4</td><td align="right">20</td><td align="right">2</td><td align="right">6</td><td align="right">10</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1497</td><td align="right">1337</td><td align="right">1915</td><td align="right">114</td><td align="right">1578</td><td align="right">1697</td></tr><tr><td>load</td><td align="right">1275</td><td align="right">1143</td><td align="right">1512</td><td align="right">96</td><td align="right">1337</td><td align="right">1472</td></tr><tr><td>domContentLoaded</td><td align="right">1275</td><td align="right">1143</td><td align="right">1511</td><td align="right">96</td><td align="right">1337</td><td align="right">1471</td></tr><tr><td>domInteractive</td><td align="right">76</td><td align="right">34</td><td align="right">144</td><td align="right">18</td><td align="right">78</td><td align="right">118</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">22</td><td align="right">15</td><td align="right">75</td><td align="right">9</td><td align="right">22</td><td align="right">36</td></tr><tr><td>firstReactRender</td><td align="right">34</td><td align="right">28</td><td align="right">45</td><td align="right">4</td><td align="right">36</td><td align="right">41</td></tr><tr><td>getState</td><td align="right">11</td><td align="right">4</td><td align="right">201</td><td align="right">20</td><td align="right">9</td><td align="right">27</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1257</td><td align="right">1129</td><td align="right">1494</td><td align="right">97</td><td align="right">1316</td><td align="right">1455</td></tr><tr><td>setupStore</td><td align="right">10</td><td align="right">5</td><td align="right">222</td><td align="right">22</td><td align="right">8</td><td align="right">21</td></tr></tbody></table>Benchmark value 1256 exceeds gate value 1234 for chrome browserify home mean uiStartup<br>
Benchmark value 1078 exceeds gate value 1070 for chrome browserify home mean load<br>
Benchmark value 1070 exceeds gate value 1061 for chrome browserify home mean domContentLoaded<br>
Benchmark value 16 exceeds gate value 15 for chrome browserify home mean getState<br>
Benchmark value 26 exceeds gate value 18 for chrome browserify home p95 backgroundConnect<br>
Benchmark value 259 exceeds gate value 65 for chrome webpack home p95 setupStore<br>
Benchmark value 28 exceeds gate value 25 for firefox browserify home mean backgroundConnect<br>
Benchmark value 99 exceeds gate value 70 for firefox browserify home p95 backgroundConnect<br>
<b>Sum of mean exceeds: 43ms | Sum of p95 exceeds: 231ms<br>
Sum of all benchmark exceeds: 274ms</b><br>
</details>

<details><summary>Bundle size diffs [🚀 Bundle size reduced!]</summary><ul><li>background: -2.24 KiB (-0.04%)</li>
<li>ui: 11.49 KiB (0.16%)</li>
<li>common: -1.27 MiB (-13.82%)</li></ul></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-05-20T13:55:57Z
body: <details><summary>Builds ready [d311f44]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds/metamask-chrome-12.18.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-mv2/metamask-firefox-12.18.0.zip">firefox</a></li>
<li>builds (beta): <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15138727768/builds-beta/metamask-beta-chrome-12.18.0-beta.0.zip">chrome</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-flask/metamask-flask-chrome-12.18.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.18.0-flask.0.zip">firefox</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-test/metamask-chrome-12.18.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-test-mv2/metamask-firefox-12.18.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-test-flask/metamask-flask-chrome-12.18.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.18.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>bundle size: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15138727768/bundle-size/bundle_size.json">Bundle Size Stats</a></li>
<li>user-actions-benchmark: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15138727768/benchmarks/benchmark-chrome-browserify-userActions.json">User Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15138727768/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15138727768/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/jobs/4902128/artifacts/">all CircleCI artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/ui-13.html">13</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/91c147da-c8af-45f1-b63f-4d1ddf90da8b/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>UI Startup Metrics (1216 ± 66 ms)</summary><table><thead><tr><th>Platform</th><th>BuildType</th><th>Page</th><th>Metric</th><th>Mean (ms)</th><th>Min (ms)</th><th>Max (ms)</th><th>Std Dev (ms)</th><th>P 75 (ms)</th><th>P 95 (ms)</th></tr></thead><tbody><tr><td rowspan="22">Chrome</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1216</td><td align="right">1084</td><td align="right">1436</td><td align="right">66</td><td align="right">1256</td><td align="right">1328</td></tr><tr><td>load</td><td align="right">1047</td><td align="right">916</td><td align="right">1176</td><td align="right">64</td><td align="right">1099</td><td align="right">1149</td></tr><tr><td>domContentLoaded</td><td align="right">1038</td><td align="right">910</td><td align="right">1166</td><td align="right">65</td><td align="right">1090</td><td align="right">1144</td></tr><tr><td>domInteractive</td><td align="right">15</td><td align="right">13</td><td align="right">27</td><td align="right">3</td><td align="right">16</td><td align="right">23</td></tr><tr><td>firstPaint</td><td align="right">753</td><td align="right">78</td><td align="right">1176</td><td align="right">410</td><td align="right">1079</td><td align="right">1150</td></tr><tr><td>backgroundConnect</td><td align="right">10</td><td align="right">4</td><td align="right">53</td><td align="right">8</td><td align="right">9</td><td align="right">25</td></tr><tr><td>firstReactRender</td><td align="right">22</td><td align="right">15</td><td align="right">75</td><td align="right">10</td><td align="right">21</td><td align="right">53</td></tr><tr><td>getState</td><td align="right">16</td><td align="right">5</td><td align="right">65</td><td align="right">9</td><td align="right">21</td><td align="right">30</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">798</td><td align="right">664</td><td align="right">920</td><td align="right">64</td><td align="right">846</td><td align="right">901</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">5</td><td align="right">27</td><td align="right">4</td><td align="right">8</td><td align="right">16</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">2142</td><td align="right">1603</td><td align="right">2571</td><td align="right">196</td><td align="right">2278</td><td align="right">2455</td></tr><tr><td>load</td><td align="right">1640</td><td align="right">1250</td><td align="right">1983</td><td align="right">147</td><td align="right">1735</td><td align="right">1845</td></tr><tr><td>domContentLoaded</td><td align="right">1634</td><td align="right">1242</td><td align="right">1970</td><td align="right">146</td><td align="right">1728</td><td align="right">1837</td></tr><tr><td>domInteractive</td><td align="right">16</td><td align="right">11</td><td align="right">69</td><td align="right">10</td><td align="right">13</td><td align="right">39</td></tr><tr><td>firstPaint</td><td align="right">145</td><td align="right">63</td><td align="right">325</td><td align="right">54</td><td align="right">162</td><td align="right">264</td></tr><tr><td>backgroundConnect</td><td align="right">21</td><td align="right">9</td><td align="right">56</td><td align="right">8</td><td align="right">23</td><td align="right">35</td></tr><tr><td>firstReactRender</td><td align="right">141</td><td align="right">44</td><td align="right">375</td><td align="right">102</td><td align="right">175</td><td align="right">337</td></tr><tr><td>getState</td><td align="right">17</td><td align="right">4</td><td align="right">304</td><td align="right">40</td><td align="right">14</td><td align="right">35</td></tr><tr><td>initialActions</td><td align="right">3</td><td align="right">1</td><td align="right">7</td><td align="right">1</td><td align="right">4</td><td align="right">5</td></tr><tr><td>loadScripts</td><td align="right">1631</td><td align="right">1240</td><td align="right">1959</td><td align="right">145</td><td align="right">1725</td><td align="right">1834</td></tr><tr><td>setupStore</td><td align="right">37</td><td align="right">7</td><td align="right">305</td><td align="right">75</td><td align="right">20</td><td align="right">298</td></tr><tr><td rowspan="22">Firefox</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1335</td><td align="right">1128</td><td align="right">1819</td><td align="right">130</td><td align="right">1375</td><td align="right">1628</td></tr><tr><td>load</td><td align="right">1183</td><td align="right">999</td><td align="right">1590</td><td align="right">122</td><td align="right">1232</td><td align="right">1454</td></tr><tr><td>domContentLoaded</td><td align="right">1183</td><td align="right">998</td><td align="right">1590</td><td align="right">122</td><td align="right">1231</td><td align="right">1454</td></tr><tr><td>domInteractive</td><td align="right">100</td><td align="right">35</td><td align="right">289</td><td align="right">37</td><td align="right">112</td><td align="right">166</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">25</td><td align="right">13</td><td align="right">227</td><td align="right">30</td><td align="right">21</td><td align="right">51</td></tr><tr><td>firstReactRender</td><td align="right">22</td><td align="right">19</td><td align="right">31</td><td align="right">2</td><td align="right">23</td><td align="right">27</td></tr><tr><td>getState</td><td align="right">10</td><td align="right">4</td><td align="right">211</td><td align="right">21</td><td align="right">8</td><td align="right">26</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1160</td><td align="right">990</td><td align="right">1573</td><td align="right">111</td><td align="right">1215</td><td align="right">1397</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">4</td><td align="right">76</td><td align="right">10</td><td align="right">6</td><td align="right">16</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1595</td><td align="right">1390</td><td align="right">2107</td><td align="right">151</td><td align="right">1682</td><td align="right">1941</td></tr><tr><td>load</td><td align="right">1359</td><td align="right">1187</td><td align="right">1880</td><td align="right">144</td><td align="right">1435</td><td align="right">1660</td></tr><tr><td>domContentLoaded</td><td align="right">1359</td><td align="right">1186</td><td align="right">1880</td><td align="right">144</td><td align="right">1434</td><td align="right">1659</td></tr><tr><td>domInteractive</td><td align="right">85</td><td align="right">43</td><td align="right">368</td><td align="right">34</td><td align="right">89</td><td align="right">139</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">23</td><td align="right">14</td><td align="right">72</td><td align="right">8</td><td align="right">24</td><td align="right">39</td></tr><tr><td>firstReactRender</td><td align="right">36</td><td align="right">28</td><td align="right">51</td><td align="right">5</td><td align="right">38</td><td align="right">46</td></tr><tr><td>getState</td><td align="right">12</td><td align="right">5</td><td align="right">201</td><td align="right">20</td><td align="right">10</td><td align="right">32</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1338</td><td align="right">1165</td><td align="right">1859</td><td align="right">144</td><td align="right">1405</td><td align="right">1639</td></tr><tr><td>setupStore</td><td align="right">10</td><td align="right">5</td><td align="right">68</td><td align="right">8</td><td align="right">9</td><td align="right">21</td></tr></tbody></table>Benchmark value 16 exceeds gate value 15 for chrome browserify home mean getState<br>
Benchmark value 26 exceeds gate value 18 for chrome browserify home p95 backgroundConnect<br>
Benchmark value 53 exceeds gate value 45 for chrome browserify home p95 firstReactRender<br>
Benchmark value 37 exceeds gate value 32 for chrome webpack home mean setupStore<br>
Benchmark value 2456 exceeds gate value 2454 for chrome webpack home p95 uiStartup<br>
Benchmark value 298 exceeds gate value 65 for chrome webpack home p95 setupStore<br>
Benchmark value 26 exceeds gate value 24 for firefox browserify home p95 getState<br>
Benchmark value 1941 exceeds gate value 1935 for firefox webpack home p95 uiStartup<br>
Benchmark value 1639 exceeds gate value 1630 for firefox webpack home p95 loadScripts<br>
<b>Sum of mean exceeds: 6ms | Sum of p95 exceeds: 268ms<br>
Sum of all benchmark exceeds: 274ms</b><br>
</details>

<details><summary>Bundle size diffs [🚨 Warning! Bundle size has increased!]</summary><ul><li>background: 0 Bytes (0%)</li>
<li>ui: 7.8 KiB (0.11%)</li>
<li>common: 127 Bytes (0%)</li></ul></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-05-20T15:48:58Z
body: <details><summary>Builds ready [74302d9]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds/metamask-chrome-12.18.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-mv2/metamask-firefox-12.18.0.zip">firefox</a></li>
<li>builds (beta): <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15141319503/builds-beta/metamask-beta-chrome-12.18.0-beta.0.zip">chrome</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-flask/metamask-flask-chrome-12.18.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.18.0-flask.0.zip">firefox</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-test/metamask-chrome-12.18.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-test-mv2/metamask-firefox-12.18.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-test-flask/metamask-flask-chrome-12.18.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.18.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>bundle size: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15141319503/bundle-size/bundle_size.json">Bundle Size Stats</a></li>
<li>user-actions-benchmark: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15141319503/benchmarks/benchmark-chrome-browserify-userActions.json">User Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15141319503/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/15141319503/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/jobs/4902545/artifacts/">all CircleCI artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/ui-13.html">13</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/37699803-a7df-4b0b-83aa-5d88667798ba/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>UI Startup Metrics (1188 ± 53 ms)</summary><table><thead><tr><th>Platform</th><th>BuildType</th><th>Page</th><th>Metric</th><th>Mean (ms)</th><th>Min (ms)</th><th>Max (ms)</th><th>Std Dev (ms)</th><th>P 75 (ms)</th><th>P 95 (ms)</th></tr></thead><tbody><tr><td rowspan="22">Chrome</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1188</td><td align="right">1079</td><td align="right">1313</td><td align="right">53</td><td align="right">1232</td><td align="right">1270</td></tr><tr><td>load</td><td align="right">1025</td><td align="right">936</td><td align="right">1146</td><td align="right">48</td><td align="right">1056</td><td align="right">1111</td></tr><tr><td>domContentLoaded</td><td align="right">1019</td><td align="right">931</td><td align="right">1142</td><td align="right">49</td><td align="right">1049</td><td align="right">1102</td></tr><tr><td>domInteractive</td><td align="right">15</td><td align="right">13</td><td align="right">28</td><td align="right">3</td><td align="right">16</td><td align="right">24</td></tr><tr><td>firstPaint</td><td align="right">722</td><td align="right">74</td><td align="right">1132</td><td align="right">406</td><td align="right">1048</td><td align="right">1112</td></tr><tr><td>backgroundConnect</td><td align="right">8</td><td align="right">4</td><td align="right">32</td><td align="right">5</td><td align="right">7</td><td align="right">22</td></tr><tr><td>firstReactRender</td><td align="right">19</td><td align="right">15</td><td align="right">55</td><td align="right">5</td><td align="right">19</td><td align="right">23</td></tr><tr><td>getState</td><td align="right">14</td><td align="right">5</td><td align="right">54</td><td align="right">9</td><td align="right">20</td><td align="right">30</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">779</td><td align="right">696</td><td align="right">903</td><td align="right">47</td><td align="right">808</td><td align="right">862</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">5</td><td align="right">19</td><td align="right">2</td><td align="right">8</td><td align="right">14</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">2164</td><td align="right">1747</td><td align="right">2639</td><td align="right">213</td><td align="right">2319</td><td align="right">2515</td></tr><tr><td>load</td><td align="right">1664</td><td align="right">1328</td><td align="right">2033</td><td align="right">161</td><td align="right">1765</td><td align="right">1918</td></tr><tr><td>domContentLoaded</td><td align="right">1657</td><td align="right">1325</td><td align="right">2009</td><td align="right">160</td><td align="right">1758</td><td align="right">1909</td></tr><tr><td>domInteractive</td><td align="right">15</td><td align="right">12</td><td align="right">58</td><td align="right">9</td><td align="right">13</td><td align="right">42</td></tr><tr><td>firstPaint</td><td align="right">172</td><td align="right">70</td><td align="right">383</td><td align="right">64</td><td align="right">216</td><td align="right">307</td></tr><tr><td>backgroundConnect</td><td align="right">24</td><td align="right">9</td><td align="right">97</td><td align="right">13</td><td align="right">28</td><td align="right">41</td></tr><tr><td>firstReactRender</td><td align="right">159</td><td align="right">43</td><td align="right">366</td><td align="right">117</td><td align="right">310</td><td align="right">354</td></tr><tr><td>getState</td><td align="right">28</td><td align="right">4</td><td align="right">317</td><td align="right">66</td><td align="right">14</td><td align="right">260</td></tr><tr><td>initialActions</td><td align="right">6</td><td align="right">1</td><td align="right">277</td><td align="right">27</td><td align="right">3</td><td align="right">5</td></tr><tr><td>loadScripts</td><td align="right">1654</td><td align="right">1323</td><td align="right">1998</td><td align="right">158</td><td align="right">1757</td><td align="right">1898</td></tr><tr><td>setupStore</td><td align="right">28</td><td align="right">6</td><td align="right">315</td><td align="right">55</td><td align="right">21</td><td align="right">162</td></tr><tr><td rowspan="22">Firefox</td><td rowspan="11">Browserify</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1328</td><td align="right">1124</td><td align="right">1824</td><td align="right">134</td><td align="right">1396</td><td align="right">1659</td></tr><tr><td>load</td><td align="right">1175</td><td align="right">999</td><td align="right">1669</td><td align="right">124</td><td align="right">1240</td><td align="right">1443</td></tr><tr><td>domContentLoaded</td><td align="right">1174</td><td align="right">999</td><td align="right">1669</td><td align="right">124</td><td align="right">1240</td><td align="right">1443</td></tr><tr><td>domInteractive</td><td align="right">99</td><td align="right">37</td><td align="right">271</td><td align="right">36</td><td align="right">110</td><td align="right">163</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">21</td><td align="right">13</td><td align="right">184</td><td align="right">18</td><td align="right">20</td><td align="right">33</td></tr><tr><td>firstReactRender</td><td align="right">23</td><td align="right">19</td><td align="right">59</td><td align="right">6</td><td align="right">22</td><td align="right">27</td></tr><tr><td>getState</td><td align="right">9</td><td align="right">4</td><td align="right">185</td><td align="right">18</td><td align="right">8</td><td align="right">10</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">5</td><td align="right">1</td><td align="right">0</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1156</td><td align="right">986</td><td align="right">1651</td><td align="right">122</td><td align="right">1219</td><td align="right">1425</td></tr><tr><td>setupStore</td><td align="right">7</td><td align="right">4</td><td align="right">72</td><td align="right">8</td><td align="right">6</td><td align="right">12</td></tr><tr><td rowspan="11">Webpack</td><td rowspan="11">Home</td><td>uiStartup</td><td align="right">1686</td><td align="right">1472</td><td align="right">2309</td><td align="right">167</td><td align="right">1791</td><td align="right">2049</td></tr><tr><td>load</td><td align="right">1435</td><td align="right">1242</td><td align="right">1892</td><td align="right">153</td><td align="right">1546</td><td align="right">1790</td></tr><tr><td>domContentLoaded</td><td align="right">1434</td><td align="right">1241</td><td align="right">1891</td><td align="right">153</td><td align="right">1546</td><td align="right">1789</td></tr><tr><td>domInteractive</td><td align="right">85</td><td align="right">37</td><td align="right">304</td><td align="right">33</td><td align="right">90</td><td align="right">127</td></tr><tr><td>firstPaint</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td><td align="right">NaN</td></tr><tr><td>backgroundConnect</td><td align="right">27</td><td align="right">17</td><td align="right">220</td><td align="right">21</td><td align="right">26</td><td align="right">58</td></tr><tr><td>firstReactRender</td><td align="right">37</td><td align="right">32</td><td align="right">51</td><td align="right">4</td><td align="right">38</td><td align="right">45</td></tr><tr><td>getState</td><td align="right">15</td><td align="right">5</td><td align="right">253</td><td align="right">33</td><td align="right">10</td><td align="right">30</td></tr><tr><td>initialActions</td><td align="right">1</td><td align="right">0</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">1</td></tr><tr><td>loadScripts</td><td align="right">1410</td><td align="right">1221</td><td align="right">1862</td><td align="right">154</td><td align="right">1525</td><td align="right">1765</td></tr><tr><td>setupStore</td><td align="right">12</td><td align="right">6</td><td align="right">268</td><td align="right">26</td><td align="right">9</td><td align="right">22</td></tr></tbody></table>cc: @HowardBraham<br>
Benchmark value 22 exceeds gate value 18 for chrome browserify home p95 backgroundConnect<br>
Benchmark value 2515 exceeds gate value 2454 for chrome webpack home p95 uiStartup<br>
Benchmark value 260 exceeds gate value 195 for chrome webpack home p95 getState<br>
Benchmark value 162 exceeds gate value 65 for chrome webpack home p95 setupStore<br>
Benchmark value 1686 exceeds gate value 1615 for firefox webpack home mean uiStartup<br>
Benchmark value 1435 exceeds gate value 1380 for firefox webpack home mean load<br>
Benchmark value 1435 exceeds gate value 1380 for firefox webpack home mean domContentLoaded<br>
Benchmark value 28 exceeds gate value 26 for firefox webpack home mean backgroundConnect<br>
Benchmark value 1411 exceeds gate value 1360 for firefox webpack home mean loadScripts<br>
Benchmark value 2049 exceeds gate value 1935 for firefox webpack home p95 uiStartup<br>
Benchmark value 1790 exceeds gate value 1660 for firefox webpack home p95 load<br>
Benchmark value 1789 exceeds gate value 1660 for firefox webpack home p95 domContentLoaded<br>
Benchmark value 58 exceeds gate value 49 for firefox webpack home p95 backgroundConnect<br>
Benchmark value 1765 exceeds gate value 1630 for firefox webpack home p95 loadScripts<br>
<b>Sum of mean exceeds: 234ms | Sum of p95 exceeds: 744ms<br>
Sum of all benchmark exceeds: 978ms</b><br>
</details>

<details><summary>Bundle size diffs [🚨 Warning! Bundle size has increased!]</summary><ul><li>background: 0 Bytes (0%)</li>
<li>ui: 7.81 KiB (0.11%)</li>
<li>common: 127 Bytes (0%)</li></ul></details>


author_association: COLLABORATOR