diff --git a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx
index c565150fd9ca..7f5d08e6e824 100644
--- a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx
+++ b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx
@@ -342,7 +342,12 @@ const ContractInteraction = memo(() => {
-
+
{tokenDecimals !== undefined ? (
<>
diff --git a/packages/plugin-infra/src/web3/EVM/useERC20TokenApproveCallback.ts b/packages/plugin-infra/src/web3/EVM/useERC20TokenApproveCallback.ts
index 41bf0e70d8cb..7b9872eb59bb 100644
--- a/packages/plugin-infra/src/web3/EVM/useERC20TokenApproveCallback.ts
+++ b/packages/plugin-infra/src/web3/EVM/useERC20TokenApproveCallback.ts
@@ -1,5 +1,6 @@
import type { NonPayableTx } from '@masknet/web3-contracts/types/types'
import { isLessThan, NetworkPluginID, toFixed } from '@masknet/web3-shared-base'
+import { once } from 'lodash-unified'
import { useCallback, useMemo } from 'react'
import { useAsyncFn } from 'react-use'
import { useERC20TokenContract } from './useERC20TokenContract'
@@ -79,16 +80,13 @@ export function useERC20TokenApproveCallback(address?: string, amount?: string,
// send transaction and wait for hash
return new Promise(async (resolve, reject) => {
- const revalidate = () => {
+ const revalidate = once(() => {
revalidateBalance()
revalidateAllowance()
- }
+ })
erc20Contract.methods
.approve(spender, useExact ? amount : MaxUint256)
.send(config as NonPayableTx)
- .on(TransactionEventType.RECEIPT, () => {
- revalidate()
- })
.on(TransactionEventType.CONFIRMATION, (no, receipt) => {
revalidate()
resolve(receipt.transactionHash)