Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
18508c3
Makes getGasEstimationTxResponse exportable
Agupane Nov 30, 2020
34749fb
Add check for failing txs on approveTxModal
Agupane Nov 30, 2020
5baebb7
Adds styles for reviewTx
Agupane Dec 1, 2020
5a676b7
Adds useTxSuccessCheck hook
Agupane Dec 1, 2020
6dd2639
Remove hook
Agupane Dec 1, 2020
f614c3c
Adds checkIfTxWillFail function
Agupane Dec 1, 2020
a73b764
Uses checkIfTxWillFailAsync on reviewTx modal
Agupane Dec 1, 2020
0452997
Improves approveTx modal
Agupane Dec 1, 2020
1661be8
Add check for failing transaction in contract interaction modal
Agupane Dec 2, 2020
b3d92e6
Add check for reviewCollectible
Agupane Dec 2, 2020
5d97475
Fix check on sendFunds reviewTx
Agupane Dec 2, 2020
89253ab
Adds styling for contractInteraction modal
Agupane Dec 2, 2020
117e94a
Fix gas calculation for native token transfers
Agupane Dec 2, 2020
73cc229
Remove logs
Agupane Dec 2, 2020
94b5c03
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Dec 3, 2020
5922302
Rename estimateDataGasCosts to parseRequiredTxGasResponse
Agupane Dec 4, 2020
977d026
Refactor checkIfExecTxWill usage
Agupane Dec 4, 2020
1652773
Refactor checkIfTxWillFailAsync in ReviewTx
Agupane Dec 4, 2020
9a689f5
Use getPreValidatedSignatures in createTransaction()
Agupane Dec 4, 2020
f74e516
Refactor estimateTxGasCosts
Agupane Dec 4, 2020
a7011bf
Refactor ReviewTx: extract useEffects to hooks
Agupane Dec 4, 2020
528aea7
Merge branch 'development' into feature/1048-tx-will-fail-warning
Dec 5, 2020
c69ffca
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Dec 9, 2020
60baeae
Remove unnecessary gas transfer amount
Agupane Dec 9, 2020
4b0db6b
Refactor estimateTxGasCosts: extract checkIfTxIsExecution and estimat…
Agupane Dec 9, 2020
72680d4
Fix tx amount
Agupane Dec 9, 2020
e6b361c
Moves useCheckIfTransactionWillFail to logic/hooks folder
Agupane Dec 9, 2020
402ed43
Replaces useEffect usage with useCheckIfTransactionWillFail hook
Agupane Dec 9, 2020
e100113
Improves modal's wording
Agupane Dec 9, 2020
c716cef
Merge branch 'development' of https://github.com/gnosis/safe-react in…
Agupane Dec 9, 2020
49641a4
Remove comment
Agupane Dec 9, 2020
c184d3b
Merge branch 'development' into feature/1048-tx-will-fail-warning
fernandomg Dec 9, 2020
1a2bfc8
Merge branch 'development' into feature/1048-tx-will-fail-warning
fernandomg Dec 10, 2020
eaec906
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Dec 10, 2020
6c98251
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Dec 11, 2020
983551f
Fix error parsing the cancel transaction error message from GETH nodes
Agupane Dec 11, 2020
0c0a106
Remove useCheckIfTransactionWillFail
Agupane Dec 11, 2020
54bd701
Replace useCheckIfTransactionWillFail from modals with useEstimateTra…
Agupane Dec 11, 2020
4ea2553
Replace estimateGasCosts from every review tx modal with useEstimateT…
Agupane Dec 11, 2020
a6685cc
Replace estimateGasCosts from every review tx modal with useEstimateT…
Agupane Dec 11, 2020
a8a3e21
Extract isExecution calculation to useEstimateTransactionGas
Agupane Dec 11, 2020
c461954
Creates TransactionFailText
Agupane Dec 11, 2020
21fbeda
Uses TransactionFailText in the review modals
Agupane Dec 11, 2020
ad27d74
Merge branch 'development' of https://github.com/gnosis/safe-react in…
Agupane Dec 11, 2020
343e1f0
Remove unnecessary styles
Agupane Dec 11, 2020
0c208b7
Fix imports
Agupane Dec 11, 2020
b162729
Remove css
Agupane Dec 11, 2020
74abb25
Fix missing style
Agupane Dec 11, 2020
d42cdc4
Remove duplicated function
Agupane Dec 11, 2020
e57ac46
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Dec 11, 2020
7a7bfc7
Merge branch 'development' into feature/1048-tx-will-fail-warning
Dec 14, 2020
fae6a16
Fix modal height
Agupane Dec 14, 2020
da08f32
Fix wrong selector usage
Agupane Dec 14, 2020
220278c
Merge branch 'feature/1048-tx-will-fail-warning' of https://github.co…
Agupane Dec 14, 2020
3df879b
Fix missing null check on cancel tx confirmations
Agupane Dec 14, 2020
da1d5d8
Add guard for CLOSE_SNACKBAR action when tx was already dismissed
Agupane Dec 14, 2020
00ccae2
Improves useEstimateTransactionGas in review custom tx and contract i…
Agupane Dec 14, 2020
513e6cb
Merge branch 'release/v2.17.0' of https://github.com/gnosis/safe-reac…
Agupane Dec 14, 2020
0299c03
Merge branch 'development' into feature/1048-tx-will-fail-warning
Dec 14, 2020
6346317
Fix hook dependency
Agupane Dec 15, 2020
e8d73be
Merge branch 'feature/1048-tx-will-fail-warning' of https://github.co…
Agupane Dec 15, 2020
abe70f2
Merge branch 'development' of https://github.com/gnosis/safe-react in…
Agupane Dec 16, 2020
fcfd8bb
Fix review replace/remove/add owner modals styling
Agupane Dec 16, 2020
7f7c638
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Dec 22, 2020
1b2815b
Refactor response of useEstimateTransactionGas
Agupane Dec 23, 2020
ccf8a4e
Remove safeAddress as param to the useEstimateTransactionGas
Agupane Dec 23, 2020
0742742
Improves how threshold is obtained in useEstimateTransactionGas.tsx
Agupane Dec 23, 2020
0f739ef
Merge branch 'development' of https://github.com/gnosis/safe-react in…
Agupane Dec 23, 2020
a10bb19
Merge branch 'feature/1048-tx-will-fail-warning' of https://github.c…
Agupane Dec 23, 2020
9d498b1
Rename gasCostHumanReadable to gasCostFormatted
Agupane Dec 23, 2020
e60730d
Add operation to useEstimateTransactionGas
Agupane Jan 4, 2021
7ceda35
Refactor ConfirmTransactionModal to use useEstimateTransactionGas
Agupane Jan 4, 2021
f768d4c
Refactor proccessTransaction to use getPreValidatedSignatures method
Agupane Jan 4, 2021
694e450
Fix default export of ApproveTxModal
Agupane Jan 4, 2021
2c5f21d
Rename estimateExecTransactionGas to estimateGasForTransactionCreation
Agupane Jan 5, 2021
40ec65d
Make estimateGasForTransactionCreation throw error instead of 0 gas
Agupane Jan 5, 2021
a1ac679
Adds estimateGasForTransactionExecution and estimateGasForTransaction…
Agupane Jan 5, 2021
25bbd33
Move estimateTransactionGas to useEstimateTransactionGas
Agupane Jan 5, 2021
316240b
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Jan 6, 2021
7895924
Type and refactor generateSignaturesFromTxConfirmations
Agupane Jan 6, 2021
d8d64c9
Uses confirmations to estimateGasForTransactionExecution
Agupane Jan 6, 2021
88d36f8
Adds TransactionFeesText component
Agupane Jan 6, 2021
6550458
Update text
Agupane Jan 6, 2021
53ef32a
Update text
Agupane Jan 6, 2021
dafe620
Remove unnecessary condition
Agupane Jan 6, 2021
7c6ba58
Pass more parameters to estimateGasForTransactionExecution
Agupane Jan 6, 2021
9c5bb19
Merge with 1048-tx-will-fail-warning
Agupane Jan 6, 2021
c6efa91
Removes unnecessary parameter in getNewTxNonce
Agupane Jan 6, 2021
f9fb706
Moves checkIfOffChainSignatureIsPossible to safeTxSigner.ts
Agupane Jan 6, 2021
e0b3af6
Fix check for null confirmations
Agupane Jan 6, 2021
d819531
Uses checkIfOffChainSignatureIsPossible on createTransaction.ts
Agupane Jan 6, 2021
4ab94ac
Move TransactionFailText inside TransactionFees component
Agupane Jan 6, 2021
1f06259
Remove unnecessary awaits
Agupane Jan 7, 2021
bee96c5
Pass safeTxGas to useEstimateTransactionGas.tsx
Agupane Jan 8, 2021
63cab3f
Fix gas iteration on estimateGasForTransactionExecution
Agupane Jan 8, 2021
00919c7
Fix estimateGasForTransactionExecution calculation
Agupane Jan 8, 2021
d25e907
Fix generateSignaturesFromTxConfirmations calculation
Agupane Jan 8, 2021
fccd8d1
Remove unnecessary Promise and await
Jan 8, 2021
289b6e2
Fix estimateGasForTransactionExecution for preApproving owner case
Agupane Jan 8, 2021
b8d0878
Merge branch 'feature/refactor-gas-calculation' of https://github.com…
Agupane Jan 8, 2021
7ca4b64
Improve logging
Agupane Jan 8, 2021
7f29a64
Merge branch 'feature/1048-tx-will-fail-warning' into feature/refacto…
Agupane Jan 8, 2021
71fb956
Remove log
Agupane Jan 11, 2021
db15da9
Fix typo
Agupane Jan 11, 2021
b02f929
Uses operation in useEstimateTransactionGas
Agupane Jan 11, 2021
40dabdd
Uses operation in useEstimateTransactionGas
Agupane Jan 11, 2021
64d4fc3
Merge branch 'feature/1048-tx-will-fail-warning' into feature/refacto…
Agupane Jan 11, 2021
0a77aa3
Fix missing dependency
Agupane Jan 11, 2021
0f3b305
Merge pull request #1756 from gnosis/feature/refactor-gas-calculation
Jan 11, 2021
74aeebb
Merge branch 'development' into feature/1048-tx-will-fail-warning
Agupane Jan 12, 2021
4386c3b
Merge branch 'development' into feature/1048-tx-will-fail-warning
Jan 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const useStyles = makeStyles(
position: 'absolute',
top: '120px',
width: '500px',
height: '540px',
height: '580px',
borderRadius: sm,
backgroundColor: '#ffffff',
boxShadow: '0 0 5px 0 rgba(74, 85, 121, 0.5)',
Expand Down
56 changes: 56 additions & 0 deletions src/components/TransactionFailText/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createStyles, makeStyles } from '@material-ui/core'
import { sm } from 'src/theme/variables'
import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas'
import Row from 'src/components/layout/Row'
import Paragraph from 'src/components/layout/Paragraph'
import Img from 'src/components/layout/Img'
import InfoIcon from 'src/assets/icons/info_red.svg'
import React from 'react'
import { useSelector } from 'react-redux'
import { safeThresholdSelector } from 'src/logic/safe/store/selectors'

const styles = createStyles({
executionWarningRow: {
display: 'flex',
alignItems: 'center',
},
warningIcon: {
marginRight: sm,
},
})

const useStyles = makeStyles(styles)

type TransactionFailTextProps = {
txEstimationExecutionStatus: EstimationStatus
isExecution: boolean
}

export const TransactionFailText = ({
txEstimationExecutionStatus,
isExecution,
}: TransactionFailTextProps): React.ReactElement | null => {
const classes = useStyles()
const threshold = useSelector(safeThresholdSelector)

if (txEstimationExecutionStatus !== EstimationStatus.FAILURE) {
return null
}

let errorMessage = 'To save gas costs, avoid creating the transaction.'
if (isExecution) {
errorMessage =
threshold && threshold > 1
? `To save gas costs, cancel this transaction`
: `To save gas costs, avoid executing the transaction.`
}

return (
<Row align="center">
<Paragraph color="error" className={classes.executionWarningRow}>
<Img alt="Info Tooltip" height={16} src={InfoIcon} className={classes.warningIcon} />
This transaction will most likely fail. {errorMessage}
</Paragraph>
</Row>
)
}
43 changes: 43 additions & 0 deletions src/components/TransactionsFees/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas'
import Paragraph from 'src/components/layout/Paragraph'
import { getNetworkInfo } from 'src/config'
import { TransactionFailText } from 'src/components/TransactionFailText'

type TransactionFailTextProps = {
txEstimationExecutionStatus: EstimationStatus
gasCostFormatted: string
isExecution: boolean
isCreation: boolean
isOffChainSignature: boolean
}
const { nativeCoin } = getNetworkInfo()

export const TransactionFees = ({
gasCostFormatted,
isExecution,
isCreation,
isOffChainSignature,
txEstimationExecutionStatus,
}: TransactionFailTextProps): React.ReactElement | null => {
let transactionAction
if (isCreation) {
transactionAction = 'create'
} else if (isExecution) {
transactionAction = 'execute'
} else {
transactionAction = 'approve'
}

return (
<>
<Paragraph>
You&apos;re about to {transactionAction} a transaction and will have to confirm it with your currently connected
wallet.
{!isOffChainSignature &&
` Make sure you have ${gasCostFormatted} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`}
</Paragraph>
<TransactionFailText txEstimationExecutionStatus={txEstimationExecutionStatus} isExecution={isExecution} />
</>
)
}
241 changes: 241 additions & 0 deletions src/logic/hooks/useEstimateTransactionGas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import { useEffect, useState } from 'react'
import {
estimateGasForTransactionApproval,
estimateGasForTransactionCreation,
estimateGasForTransactionExecution,
} from 'src/logic/safe/transactions/gas'
import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue'
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
import { calculateGasPrice } from 'src/logic/wallets/ethTransactions'
import { getNetworkInfo } from 'src/config'
import { useSelector } from 'react-redux'
import {
safeCurrentVersionSelector,
safeParamAddressFromStateSelector,
safeThresholdSelector,
} from 'src/logic/safe/store/selectors'
import { CALL } from 'src/logic/safe/transactions'
import { providerSelector } from '../wallets/store/selectors'

import { List } from 'immutable'
import { Confirmation } from 'src/logic/safe/store/models/types/confirmation'
import { checkIfOffChainSignatureIsPossible } from 'src/logic/safe/safeTxSigner'
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'

export enum EstimationStatus {
LOADING = 'LOADING',
FAILURE = 'FAILURE',
SUCCESS = 'SUCCESS',
}

const checkIfTxIsExecution = (threshold: number, preApprovingOwner?: string, txConfirmations?: number): boolean =>
txConfirmations === threshold || !!preApprovingOwner || threshold === 1

const checkIfTxIsApproveAndExecution = (threshold: number, txConfirmations: number): boolean =>
txConfirmations + 1 === threshold

const checkIfTxIsCreation = (txConfirmations: number): boolean => txConfirmations === 0

type TransactionEstimationProps = {
txData: string
safeAddress: string
txRecipient: string
txConfirmations?: List<Confirmation>
txAmount?: string
operation?: number
gasPrice?: string
gasToken?: string
refundReceiver?: string // Address of receiver of gas payment (or 0 if tx.origin).
safeTxGas?: number
from?: string
isExecution: boolean
isCreation: boolean
isOffChainSignature?: boolean
approvalAndExecution?: boolean
}

const estimateTransactionGas = async ({
txData,
safeAddress,
txRecipient,
txConfirmations,
txAmount,
operation,
gasPrice,
gasToken,
refundReceiver,
safeTxGas,
from,
isExecution,
isCreation,
isOffChainSignature = false,
approvalAndExecution,
}: TransactionEstimationProps): Promise<number> => {
if (isCreation) {
return estimateGasForTransactionCreation(safeAddress, txData, txRecipient, txAmount || '0', operation || CALL)
}

if (!from) {
throw new Error('No from provided for approving or execute transaction')
}

if (isExecution) {
return estimateGasForTransactionExecution({
safeAddress,
txRecipient,
txConfirmations,
txAmount: txAmount || '0',
txData,
operation: operation || CALL,
from,
gasPrice: gasPrice || '0',
gasToken: gasToken || ZERO_ADDRESS,
refundReceiver: refundReceiver || ZERO_ADDRESS,
safeTxGas: safeTxGas || 0,
approvalAndExecution,
})
}

return estimateGasForTransactionApproval({
safeAddress,
operation: operation || CALL,
txData,
txAmount: txAmount || '0',
txRecipient,
from,
isOffChainSignature,
})
}

type UseEstimateTransactionGasProps = {
txData: string
txRecipient: string
txConfirmations?: List<Confirmation>
txAmount?: string
preApprovingOwner?: string
operation?: number
safeTxGas?: number
}

type TransactionGasEstimationResult = {
txEstimationExecutionStatus: EstimationStatus
gasEstimation: number // Amount of gas needed for execute or approve the transaction
gasCost: string // Cost of gas in raw format (estimatedGas * gasPrice)
gasCostFormatted: string // Cost of gas in format '< | > 100'
gasPrice: string // Current price of gas unit
isExecution: boolean // Returns true if the user will execute the tx or false if it just signs it
isCreation: boolean // Returns true if the transaction is a creation transaction
isOffChainSignature: boolean // Returns true if offChainSignature is available
}

export const useEstimateTransactionGas = ({
txRecipient,
txData,
txConfirmations,
txAmount,
preApprovingOwner,
operation,
safeTxGas,
}: UseEstimateTransactionGasProps): TransactionGasEstimationResult => {
const [gasEstimation, setGasEstimation] = useState<TransactionGasEstimationResult>({
txEstimationExecutionStatus: EstimationStatus.LOADING,
gasEstimation: 0,
gasCost: '0',
gasCostFormatted: '< 0.001',
gasPrice: '0',
isExecution: false,
isCreation: false,
isOffChainSignature: false,
})
const { nativeCoin } = getNetworkInfo()
const safeAddress = useSelector(safeParamAddressFromStateSelector)
const threshold = useSelector(safeThresholdSelector)
const safeVersion = useSelector(safeCurrentVersionSelector)
const { account: from, smartContractWallet } = useSelector(providerSelector)

useEffect(() => {
const estimateGas = async () => {
if (!txData.length) {
return
}

const isExecution = checkIfTxIsExecution(Number(threshold), preApprovingOwner, txConfirmations?.size)
const isCreation = checkIfTxIsCreation(txConfirmations?.size || 0)
const approvalAndExecution = checkIfTxIsApproveAndExecution(Number(threshold), txConfirmations?.size || 0)

try {
const isOffChainSignature = checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion)

const gasEstimation = await estimateTransactionGas({
safeAddress,
txRecipient,
txData,
txAmount,
txConfirmations,
isExecution,
isCreation,
isOffChainSignature,
operation,
from,
safeTxGas,
approvalAndExecution,
})
const gasPrice = await calculateGasPrice()
const estimatedGasCosts = gasEstimation * parseInt(gasPrice, 10)
const gasCost = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals)
const gasCostFormatted = formatAmount(gasCost)

let txEstimationExecutionStatus = EstimationStatus.SUCCESS

if (gasEstimation <= 0) {
txEstimationExecutionStatus = isOffChainSignature ? EstimationStatus.SUCCESS : EstimationStatus.FAILURE
}

setGasEstimation({
txEstimationExecutionStatus,
gasEstimation,
gasCost,
gasCostFormatted,
gasPrice,
isExecution,
isCreation,
isOffChainSignature,
})
} catch (error) {
console.warn(error.message)
// We put a fixed the amount of gas to let the user try to execute the tx, but it's not accurate so it will probably fail
const gasEstimation = 10000
const gasCost = fromTokenUnit(gasEstimation, nativeCoin.decimals)
const gasCostFormatted = formatAmount(gasCost)
setGasEstimation({
txEstimationExecutionStatus: EstimationStatus.FAILURE,
gasEstimation,
gasCost,
gasCostFormatted,
gasPrice: '1',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious, why not -1? I think it's more standard

Copy link
Contributor Author

@Agupane Agupane Jan 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid a negative cost that could confuse the user, maybe 0 it's better. The calculation shouldn't be used because we are returning an FAILURE on the estimation status, but just to be sure

isExecution,
isCreation,
isOffChainSignature: false,
})
}
}

estimateGas()
}, [
txData,
safeAddress,
txRecipient,
txConfirmations,
txAmount,
preApprovingOwner,
nativeCoin.decimals,
threshold,
from,
operation,
safeVersion,
smartContractWallet,
safeTxGas,
])

return gasEstimation
}
2 changes: 1 addition & 1 deletion src/logic/notifications/store/reducer/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default handleActions(
const { dismissAll, key } = action.payload

if (key) {
return state.update(key, (prev) => prev.set('dismissed', true))
return state.update(key, (prev) => prev?.set('dismissed', true))
}
if (dismissAll) {
return state.withMutations((map) => {
Expand Down
Loading