From 0784092012a703482e321cd3f25ce561ca77094a Mon Sep 17 00:00:00 2001 From: Manuel Gellfart Date: Wed, 27 Mar 2024 11:23:23 +0100 Subject: [PATCH] Revert "fix: safeTxGas for rejection txs (#3452)" (#3487) This reverts commit 1dc5e3ea1aa0e37b2126b4c270b5e8be9f82323a. --- src/components/tx-flow/SafeTxProvider.tsx | 7 ++-- src/components/tx/SignOrExecuteForm/hooks.ts | 26 +++++++++++- src/services/tx/tx-sender/recommendedNonce.ts | 41 ++++++++++++++++++- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/components/tx-flow/SafeTxProvider.tsx b/src/components/tx-flow/SafeTxProvider.tsx index 4f37c1a05f..b4864a1f4a 100644 --- a/src/components/tx-flow/SafeTxProvider.tsx +++ b/src/components/tx-flow/SafeTxProvider.tsx @@ -2,7 +2,7 @@ import { createContext, useState, useEffect } from 'react' import type { Dispatch, ReactNode, SetStateAction, ReactElement } from 'react' import type { SafeTransaction } from '@safe-global/safe-core-sdk-types' import { createTx } from '@/services/tx/tx-sender' -import { useRecommendedNonce } from '../tx/SignOrExecuteForm/hooks' +import { useRecommendedNonce, useSafeTxGas } from '../tx/SignOrExecuteForm/hooks' import { Errors, logError } from '@/services/exceptions' import type { EIP712TypedData } from '@safe-global/safe-gateway-typescript-sdk' @@ -45,12 +45,13 @@ const SafeTxProvider = ({ children }: { children: ReactNode }): ReactElement => // Signed txs cannot be updated const isSigned = safeTx && safeTx.signatures.size > 0 - // Recommended nonce + // Recommended nonce and safeTxGas const recommendedNonce = useRecommendedNonce() + const recommendedSafeTxGas = useSafeTxGas(safeTx) // Priority to external nonce, then to the recommended one const finalNonce = isSigned ? safeTx?.data.nonce : nonce ?? recommendedNonce ?? safeTx?.data.nonce - const finalSafeTxGas = isSigned ? safeTx?.data.safeTxGas : safeTxGas ?? safeTx?.data.safeTxGas + const finalSafeTxGas = isSigned ? safeTx?.data.safeTxGas : safeTxGas ?? recommendedSafeTxGas ?? safeTx?.data.safeTxGas // Update the tx when the nonce or safeTxGas change useEffect(() => { diff --git a/src/components/tx/SignOrExecuteForm/hooks.ts b/src/components/tx/SignOrExecuteForm/hooks.ts index 3b343aa1e9..c7a4669ea9 100644 --- a/src/components/tx/SignOrExecuteForm/hooks.ts +++ b/src/components/tx/SignOrExecuteForm/hooks.ts @@ -14,7 +14,7 @@ import { dispatchTxSigning, } from '@/services/tx/tx-sender' import { useHasPendingTxs } from '@/hooks/usePendingTxs' -import { getNonces } from '@/services/tx/tx-sender/recommendedNonce' +import { getSafeTxGas, getNonces } from '@/services/tx/tx-sender/recommendedNonce' import useAsync from '@/hooks/useAsync' import { useUpdateBatch } from '@/hooks/useDraftBatch' import { type TransactionDetails } from '@safe-global/safe-gateway-typescript-sdk' @@ -170,6 +170,30 @@ export const useRecommendedNonce = (): number | undefined => { return recommendedNonce } +export const useSafeTxGas = (safeTx: SafeTransaction | undefined): string | undefined => { + const { safeAddress, safe } = useSafeInfo() + + // Memoize only the necessary params so that the useAsync hook is not called every time safeTx changes + const safeTxParams = useMemo(() => { + return !safeTx?.data?.to + ? undefined + : { + to: safeTx?.data.to, + value: safeTx?.data?.value, + data: safeTx?.data?.data, + operation: safeTx?.data?.operation, + } + }, [safeTx?.data.to, safeTx?.data.value, safeTx?.data.data, safeTx?.data.operation]) + + const [safeTxGas] = useAsync(() => { + if (!safe.chainId || !safeAddress || !safeTxParams || !safe.version) return + + return getSafeTxGas(safe.chainId, safeAddress, safe.version, safeTxParams) + }, [safeAddress, safe.chainId, safe.version, safeTxParams]) + + return safeTxGas +} + export const useAlreadySigned = (safeTx: SafeTransaction | undefined): boolean => { const wallet = useWallet() const hasSigned = diff --git a/src/services/tx/tx-sender/recommendedNonce.ts b/src/services/tx/tx-sender/recommendedNonce.ts index fd8fd8ecf2..aa83ed1f4b 100644 --- a/src/services/tx/tx-sender/recommendedNonce.ts +++ b/src/services/tx/tx-sender/recommendedNonce.ts @@ -1,6 +1,45 @@ -import { getNonces as fetchNonces } from '@safe-global/safe-gateway-typescript-sdk' +import { + Operation, + postSafeGasEstimation, + getNonces as fetchNonces, + type SafeTransactionEstimation, +} from '@safe-global/safe-gateway-typescript-sdk' +import type { MetaTransactionData, SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' +import { isLegacyVersion } from '@/hooks/coreSDK/safeCoreSDK' import { Errors, logError } from '@/services/exceptions' +const fetchRecommendedParams = async ( + chainId: string, + safeAddress: string, + txParams: MetaTransactionData, +): Promise => { + return postSafeGasEstimation(chainId, safeAddress, { + to: txParams.to, + value: txParams.value, + data: txParams.data, + operation: (txParams.operation as unknown as Operation) || Operation.CALL, + }) +} + +export const getSafeTxGas = async ( + chainId: string, + safeAddress: string, + safeVersion: string, + safeTxData: SafeTransactionDataPartial, +): Promise => { + const isSafeTxGasRequired = isLegacyVersion(safeVersion) + + // For 1.3.0+ Safes safeTxGas is not required + if (!isSafeTxGasRequired) return '0' + + try { + const estimation = await fetchRecommendedParams(chainId, safeAddress, safeTxData) + return estimation.safeTxGas + } catch (e) { + logError(Errors._616, e) + } +} + export const getNonces = async (chainId: string, safeAddress: string) => { try { return await fetchNonces(chainId, safeAddress)