diff --git a/components/brave_wallet/browser/brave_wallet_constants.h b/components/brave_wallet/browser/brave_wallet_constants.h index e8adae7de103..bafd8dc55a45 100644 --- a/components/brave_wallet/browser/brave_wallet_constants.h +++ b/components/brave_wallet/browser/brave_wallet_constants.h @@ -543,6 +543,8 @@ constexpr webui::LocalizedString kLocalizedStrings[] = { IDS_BRAVE_WALLET_ADDRESS_MISSING_CHECKSUM_INFO_WARNING}, {"braveWalletNotValidChecksumAddressError", IDS_BRAVE_WALLET_NOT_VALID_CHECKSUM_ADDRESS_ERROR}, + {"braveWalletMissingGasLimitError", + IDS_BRAVE_WALLET_MISSING_GAS_LIMIT_ERROR}, {"braveWalletQueueOf", IDS_BRAVE_WALLET_QUEUE_OF}, {"braveWalletQueueNext", IDS_BRAVE_WALLET_QUEUE_NEXT}, {"braveWalletQueueFirst", IDS_BRAVE_WALLET_QUEUE_FIRST}, diff --git a/components/brave_wallet_ui/common/hooks/transaction-parser.test.ts b/components/brave_wallet_ui/common/hooks/transaction-parser.test.ts index 0bff6d8cde62..99f9e19cc88c 100644 --- a/components/brave_wallet_ui/common/hooks/transaction-parser.test.ts +++ b/components/brave_wallet_ui/common/hooks/transaction-parser.test.ts @@ -579,4 +579,72 @@ describe('useTransactionParser hook', () => { }) }) }) + + describe('check for empty gas limit', () => { + describe.each([ + ['ERC20Approve', BraveWallet.TransactionType.ERC20Approve], + ['ERC20Transfer', BraveWallet.TransactionType.ERC20Transfer], + ['ERC721TransferFrom', BraveWallet.TransactionType.ERC721TransferFrom], + ['ERC721SafeTransferFrom', BraveWallet.TransactionType.ERC721SafeTransferFrom], + ['ETHSend', BraveWallet.TransactionType.ETHSend], + ['Other', BraveWallet.TransactionType.Other] + ])('%s', (_, txType) => { + it('should return missingGasLimitError if gas limit is zero or empty', () => { + const { result: { current: transactionParser } } = renderHook(() => useTransactionParser( + mockNetwork, [mockAccount], [], [], [mockERC20Token] + )) + + const baseMockTransactionInfo = { + ...getMockedTransactionInfo(), + txType, + txArgs: [ + 'mockRecipient', + 'mockAmount' + ] + } + + const mockTransactionInfo1 = { + ...baseMockTransactionInfo, + txData: { + ...baseMockTransactionInfo.txData, + baseData: { + ...baseMockTransactionInfo.txData.baseData, + gasLimit: '' + } + } + } + const parsedTransaction1 = transactionParser(mockTransactionInfo1) + expect(parsedTransaction1.gasLimit).toEqual('') + expect(parsedTransaction1.missingGasLimitError).toBeTruthy() + + const mockTransactionInfo2 = { + ...baseMockTransactionInfo, + txData: { + ...baseMockTransactionInfo.txData, + baseData: { + ...baseMockTransactionInfo.txData.baseData, + gasLimit: '0x0' + } + } + } + const parsedTransaction2 = transactionParser(mockTransactionInfo2) + expect(parsedTransaction2.gasLimit).toEqual('0') + expect(parsedTransaction2.missingGasLimitError).toBeTruthy() + + const mockTransactionInfo3 = { + ...baseMockTransactionInfo, + txData: { + ...baseMockTransactionInfo.txData, + baseData: { + ...baseMockTransactionInfo.txData.baseData, + gasLimit: '0x1' + } + } + } + const parsedTransaction3 = transactionParser(mockTransactionInfo3) + expect(parsedTransaction3.gasLimit).toEqual('1') + expect(parsedTransaction3.missingGasLimitError).toBeUndefined() + }) + }) + }) }) diff --git a/components/brave_wallet_ui/common/hooks/transaction-parser.ts b/components/brave_wallet_ui/common/hooks/transaction-parser.ts index 9216941cc166..c7de476e88b1 100644 --- a/components/brave_wallet_ui/common/hooks/transaction-parser.ts +++ b/components/brave_wallet_ui/common/hooks/transaction-parser.ts @@ -40,6 +40,7 @@ interface ParsedTransactionFees { gasFee: string gasFeeFiat: string isEIP1559Transaction: boolean + missingGasLimitError?: string } interface ParsedTransaction extends ParsedTransactionFees { @@ -72,6 +73,24 @@ interface ParsedTransaction extends ParsedTransactionFees { } export function useTransactionFeesParser (selectedNetwork: BraveWallet.EthereumChain, networkSpotPrice: string) { + /** + * Checks if a given gasLimit is empty or zero-value, and returns an + * appropriate localized error string. + * + * @remarks + * + * This function may only be used on ALL transaction types. + * + * @param gasLimit - The parsed gasLimit string. + * @returns Localized string describing the error, or undefined in case of + * no error. + */ + const checkForMissingGasLimitError = React.useCallback((gasLimit: string): string | undefined => { + return (gasLimit === '' || normalizeNumericValue(gasLimit) === '0') + ? getLocale('braveWalletMissingGasLimitError') + : undefined + }, []) + return React.useCallback((transactionInfo: BraveWallet.TransactionInfo): ParsedTransactionFees => { const { txData } = transactionInfo const { baseData: { gasLimit, gasPrice }, maxFeePerGas, maxPriorityFeePerGas } = txData @@ -88,7 +107,8 @@ export function useTransactionFeesParser (selectedNetwork: BraveWallet.EthereumC maxPriorityFeePerGas: normalizeNumericValue(maxPriorityFeePerGas), gasFee, gasFeeFiat: formatFiatBalance(gasFee, selectedNetwork.decimals, networkSpotPrice), - isEIP1559Transaction + isEIP1559Transaction, + missingGasLimitError: checkForMissingGasLimitError(gasLimit) } }, [selectedNetwork, networkSpotPrice]) } diff --git a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/index.tsx b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/index.tsx index 148382e84353..3a1ce0779923 100644 --- a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/index.tsx +++ b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/index.tsx @@ -253,7 +253,8 @@ function ConfirmTransactionPanel (props: Props) { return ( !!transactionDetails.sameAddressError || !!transactionDetails.contractAddressError || - transactionDetails.insufficientFundsError + transactionDetails.insufficientFundsError || + !!transactionDetails.missingGasLimitError ) }, [transactionDetails]) @@ -468,6 +469,12 @@ function ConfirmTransactionPanel (props: Props) { } + {transactionDetails.missingGasLimitError && + + {transactionDetails.missingGasLimitError} + + } + The receiving address is a token's contract address Missing checksum information Invalid checksum information + Missing gas limit of next first