From c7fe19352c4d39ddcc13efa7f1f9cbd70758c887 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Fri, 21 Nov 2025 20:04:26 +0530 Subject: [PATCH] fix: cp-13.10.1 dapp swap fix conversion rate for pol native token (#38102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix conversion rate for POL native token. CHANGELOG entry: Fixes: https://github.com/MetaMask/MetaMask-planning/issues/6327 1. Trigger swap including POL native token 2. Check that metrics are recorded correctly and dapp-swap UI shows correct values TODO - [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. - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] 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. --- > [!NOTE] > Fixes USD conversion for Polygon native token by mapping POL’s special address and adds targeted unit tests. > > - **Hook `useDappSwapUSDValues` (`ui/pages/.../useDappSwapUSDValues.ts`)**: > - Map Polygon native token USD rate: when `chainId === CHAIN_IDS.POLYGON`, set the native asset’s address rate from `0x0000000000000000000000000000000000001010`. > - Switch `isNativeAddress` to `helpers/utils/token-insights` and import `CHAIN_IDS`. > - Refactor exchange-rate fetch to async IIFE within `useAsyncResult`. > - **Tests (`ui/pages/.../useDappSwapUSDValues.test.ts`)**: > - Enhance `runHook` to accept custom token addresses and confirmation. > - Add Polygon-specific test asserting fiat rates include both native addresses with correct USD value. > - Mock token details and rates accordingly. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ccd13a65db1362793254b4871cfcab8a6a927b88. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). --- .../useDappSwapUSDValues.test.ts | 44 +++++++++++++++++-- .../useDappSwapUSDValues.ts | 19 ++++++-- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts index 5872d9900d5f..a1229292f1f4 100644 --- a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts +++ b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts @@ -1,4 +1,6 @@ import { BigNumber } from 'bignumber.js'; +import { CHAIN_IDS } from '@metamask/transaction-controller'; +import { Hex } from '@metamask/utils'; import { act } from '@testing-library/react'; import { getMockConfirmStateForTransaction } from '../../../../../../test/data/confirmations/helper'; @@ -10,18 +12,23 @@ import * as TokenUtils from '../../../utils/token'; import { Confirmation } from '../../../types/confirm'; import { useDappSwapUSDValues } from './useDappSwapUSDValues'; -async function runHook() { +async function runHook( + tokenAddresses?: Hex[], + mockConfirmation?: Confirmation, +) { const response = renderHookWithConfirmContextProvider( () => useDappSwapUSDValues({ - tokenAddresses: [ + tokenAddresses: tokenAddresses ?? [ '0x0000000000000000000000000000000000000000', '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', ], destTokenAddress: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', }), - getMockConfirmStateForTransaction(mockSwapConfirmation as Confirmation), + getMockConfirmStateForTransaction( + mockConfirmation ?? (mockSwapConfirmation as Confirmation), + ), ); await act(async () => { @@ -98,4 +105,35 @@ describe('useDappSwapUSDValues', () => { '0xfdcc3dd6671eab0709a4c0f3f53de9a333d80798': 1, }); }); + + it('return correct fiat rates token on Polygon', async () => { + jest.spyOn(Utils, 'fetchTokenExchangeRates').mockResolvedValue({ + '0x0000000000000000000000000000000000001010': 4052.27, + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 0.999804, + }); + jest.spyOn(TokenUtils, 'fetchAllTokenDetails').mockResolvedValue({ + '0x0000000000000000000000000000000000000000': { + symbol: 'POL', + decimals: '18', + } as TokenStandAndDetails, + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': { + symbol: 'USDT', + decimals: '6', + } as TokenStandAndDetails, + }); + + const result = await runHook( + [ + '0x0000000000000000000000000000000000000000', + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + ], + { ...mockSwapConfirmation, chainId: CHAIN_IDS.POLYGON } as Confirmation, + ); + + expect(result.fiatRates).toEqual({ + '0x0000000000000000000000000000000000000000': 4052.27, + '0x0000000000000000000000000000000000001010': 4052.27, + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 0.999804, + }); + }); }); diff --git a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts index 22778665590b..2365dcfc3b1d 100644 --- a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts +++ b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts @@ -5,7 +5,7 @@ import { getNativeAssetForChainId, isNativeAddress, } from '@metamask/bridge-controller'; -import { TransactionMeta } from '@metamask/transaction-controller'; +import { CHAIN_IDS, TransactionMeta } from '@metamask/transaction-controller'; import { useCallback } from 'react'; import { TokenStandAndDetails } from '../../../../../store/actions'; @@ -15,6 +15,8 @@ import { fetchAllTokenDetails } from '../../../utils/token'; import { getTokenValueFromRecord } from '../../../utils/dapp-swap-comparison-utils'; import { useConfirmContext } from '../../../context/confirm'; +const POLYGON_NATIVE_ASSET = '0x0000000000000000000000000000000000001010'; + export function useDappSwapUSDValues({ tokenAddresses = [], destTokenAddress, @@ -30,11 +32,22 @@ export function useDappSwapUSDValues({ const { value: fiatRates, pending: fiatRatesPending } = useAsyncResult< Record - >(() => { + >(async () => { const addresses = tokenAddresses.filter( (tokenAddress) => !isNativeAddress(tokenAddress), ); - return fetchTokenExchangeRates('usd', addresses as Hex[], chainId); + const exchangeRates = await fetchTokenExchangeRates( + 'usd', + addresses as Hex[], + chainId, + ); + + if (chainId === CHAIN_IDS.POLYGON) { + const nativeAddress = getNativeAssetForChainId(chainId).address; + exchangeRates[nativeAddress] = exchangeRates[POLYGON_NATIVE_ASSET]; + } + + return exchangeRates; }, [chainId, tokenAddresses?.length]); const { value: tokenDetails, pending: tokenDetailsPending } = useAsyncResult<