From 9fb69f40168c78c8fa4205e8c3e68737af5916ac Mon Sep 17 00:00:00 2001 From: digiwand <20778143+digiwand@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:37:03 +0700 Subject: [PATCH] fix: Permit message, dataTree value incorrectly using default ERC20 decimals for non-ERC20 token values (#28142) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Removes bug where fetchErc20Decimals was used in `ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx` info component and passed to the message dataTree to be used. fetchErc20Decimals was incorrectly used as it cannot be assumed that the token contract is an ERC20 standard. Fixed by calling useGetTokenStandardAndDetails instead which will use the default 18 decimals digit if the standard is an ERC20 token with no decimals found in the details. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/28142?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/metamask-extension/issues/28118 ## **Manual testing steps** 1. Go to test-dapp 2. Test Permit button 3. Observe both the simulation and message value display "3,000" (contract is not an ERC20 standard so it does not apply default 18 decimals) ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] 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. --- .../confirm/info/typed-sign/typed-sign.tsx | 20 ++++++------------- .../__snapshots__/confirm.test.tsx.snap | 12 +++++------ .../hooks/useGetTokenStandardAndDetails.ts | 6 +++++- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx index fa5e61caef1f..f14107c1fd8a 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; import { isValidAddress } from 'ethereumjs-util'; @@ -14,11 +14,11 @@ import { import { ConfirmInfoSection } from '../../../../../../components/app/confirm/info/row/section'; import { useI18nContext } from '../../../../../../hooks/useI18nContext'; import { SignatureRequestType } from '../../../../types/confirm'; +import { useGetTokenStandardAndDetails } from '../../../../hooks/useGetTokenStandardAndDetails'; import { isOrderSignatureRequest, isPermitSignatureRequest, } from '../../../../utils'; -import { fetchErc20Decimals } from '../../../../utils/token'; import { useConfirmContext } from '../../../../context/confirm'; import { selectUseTransactionSimulations } from '../../../../selectors/preferences'; import { ConfirmInfoRowTypedSignData } from '../../row/typed-sign-data/typedSignData'; @@ -31,7 +31,6 @@ const TypedSignInfo: React.FC = () => { const useTransactionSimulations = useSelector( selectUseTransactionSimulations, ); - const [decimals, setDecimals] = useState(0); if (!currentConfirmation?.msgParams) { return null; @@ -44,17 +43,10 @@ const TypedSignInfo: React.FC = () => { const isPermit = isPermitSignatureRequest(currentConfirmation); const isOrder = isOrderSignatureRequest(currentConfirmation); - const chainId = currentConfirmation.chainId as string; + const tokenContract = isPermit || isOrder ? verifyingContract : undefined; + const { decimalsNumber } = useGetTokenStandardAndDetails(tokenContract); - useEffect(() => { - (async () => { - if (!isPermit && !isOrder) { - return; - } - const tokenDecimals = await fetchErc20Decimals(verifyingContract); - setDecimals(tokenDecimals); - })(); - }, [verifyingContract]); + const chainId = currentConfirmation.chainId as string; const toolTipMessage = isSnapId(currentConfirmation.msgParams.origin) ? t('requestFromInfoSnap') @@ -99,7 +91,7 @@ const TypedSignInfo: React.FC = () => { > diff --git a/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap b/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap index e1e7633ac055..acc76e3c1bb3 100644 --- a/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap +++ b/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap @@ -349,7 +349,7 @@ exports[`Confirm should match snapshot for signature - typed sign - V4 - PermitB >
{ + if (!tokenAddress) { + return { decimalsNumber: undefined }; + } + const { value: details } = useAsyncResult( async () => (await memoizedGetTokenStandardAndDetails(