(Fix) - Calculates gas for SpendingLimit transactions (#1773)

* Bug: Use link tag instead of javascript navigation in apps list (#1770)

* Use list instead of programmable navigation

* add declaration for styled-components theme

* (Fix) - Calculates gas for SpendingLimit transactions (#1773)

* Calculates gas for spendingLimit transactions

* Adds TransactionFees component inside UpdateSafeModal

* Fix send collectible gas calculation

Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
This commit is contained in:
Agustin Pane 2021-01-14 08:36:55 -03:00 committed by GitHub
parent 8a774f2e66
commit 10f1891f8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 34 deletions

View File

@ -21,6 +21,7 @@ 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'
import { sameString } from 'src/utils/strings'
export enum EstimationStatus {
LOADING = 'LOADING',
@ -28,13 +29,19 @@ export enum EstimationStatus {
SUCCESS = 'SUCCESS',
}
const checkIfTxIsExecution = (threshold: number, preApprovingOwner?: string, txConfirmations?: number): boolean =>
txConfirmations === threshold || !!preApprovingOwner || threshold === 1
const checkIfTxIsExecution = (
threshold: number,
preApprovingOwner?: string,
txConfirmations?: number,
txType?: string,
): boolean =>
txConfirmations === threshold || !!preApprovingOwner || threshold === 1 || sameString(txType, 'spendingLimit')
const checkIfTxIsApproveAndExecution = (threshold: number, txConfirmations: number): boolean =>
txConfirmations + 1 === threshold
const checkIfTxIsApproveAndExecution = (threshold: number, txConfirmations: number, txType?: string): boolean =>
txConfirmations + 1 === threshold || sameString(txType, 'spendingLimit')
const checkIfTxIsCreation = (txConfirmations: number): boolean => txConfirmations === 0
const checkIfTxIsCreation = (txConfirmations: number, txType?: string): boolean =>
txConfirmations === 0 && !sameString(txType, 'spendingLimit')
type TransactionEstimationProps = {
txData: string
@ -115,6 +122,7 @@ type UseEstimateTransactionGasProps = {
preApprovingOwner?: string
operation?: number
safeTxGas?: number
txType?: string
}
type TransactionGasEstimationResult = {
@ -136,6 +144,7 @@ export const useEstimateTransactionGas = ({
preApprovingOwner,
operation,
safeTxGas,
txType,
}: UseEstimateTransactionGasProps): TransactionGasEstimationResult => {
const [gasEstimation, setGasEstimation] = useState<TransactionGasEstimationResult>({
txEstimationExecutionStatus: EstimationStatus.LOADING,
@ -159,9 +168,9 @@ export const useEstimateTransactionGas = ({
return
}
const isExecution = checkIfTxIsExecution(Number(threshold), preApprovingOwner, txConfirmations?.size)
const isCreation = checkIfTxIsCreation(txConfirmations?.size || 0)
const approvalAndExecution = checkIfTxIsApproveAndExecution(Number(threshold), txConfirmations?.size || 0)
const isExecution = checkIfTxIsExecution(Number(threshold), preApprovingOwner, txConfirmations?.size, txType)
const isCreation = checkIfTxIsCreation(txConfirmations?.size || 0, txType)
const approvalAndExecution = checkIfTxIsApproveAndExecution(Number(threshold), txConfirmations?.size || 0, txType)
try {
const isOffChainSignature = checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion)
@ -235,6 +244,7 @@ export const useEstimateTransactionGas = ({
safeVersion,
smartContractWallet,
safeTxGas,
txType,
])
return gasEstimation

View File

@ -6,7 +6,6 @@ import {
SAFE_MASTER_COPY_ADDRESS,
getGnosisSafeInstanceAt,
} from 'src/logic/contracts/safeContracts'
import { DELEGATE_CALL } from 'src/logic/safe/transactions'
import { getWeb3 } from 'src/logic/wallets/getWeb3'
import { MultiSend } from 'src/types/contracts/MultiSend.d'
@ -49,7 +48,7 @@ export const getEncodedMultiSendCallData = (txs: MultiSendTx[], web3: Web3): str
return encodedMultiSendCallData
}
export const upgradeSafeToLatestVersion = async (safeAddress: string, createTransaction): Promise<void> => {
export const getUpgradeSafeTransactionHash = async (safeAddress: string): Promise<string> => {
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
const fallbackHandlerTxData = safeInstance.methods.setFallbackHandler(DEFAULT_FALLBACK_HANDLER_ADDRESS).encodeABI()
const updateSafeTxData = safeInstance.methods.changeMasterCopy(SAFE_MASTER_COPY_ADDRESS).encodeABI()
@ -69,17 +68,5 @@ export const upgradeSafeToLatestVersion = async (safeAddress: string, createTran
]
const web3 = getWeb3()
const encodeMultiSendCallData = getEncodedMultiSendCallData(txs, web3)
createTransaction({
safeAddress,
to: MULTI_SEND_ADDRESS,
valueInWei: 0,
txData: encodeMultiSendCallData,
notifiedTransaction: 'STANDARD_TX',
enqueueSnackbar: () => {},
closeSnackbar: () => {},
operation: DELEGATE_CALL,
})
return
return getEncodedMultiSendCallData(txs, web3)
}

View File

@ -64,7 +64,7 @@ const ReviewCollectible = ({ onClose, onPrev, tx }: Props): React.ReactElement =
isCreation,
} = useEstimateTransactionGas({
txData: data,
txRecipient: tx.recipientAddress,
txRecipient: tx.assetAddress,
})
useEffect(() => {

View File

@ -120,6 +120,7 @@ const ReviewTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactElement =>
} = useEstimateTransactionGas({
txData: data,
txRecipient,
txType: tx.txType,
})
const submitTx = async () => {

View File

@ -19,7 +19,7 @@ import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackb
import { getNotificationsFromTxType, enhanceSnackbarForAction } from 'src/logic/notifications'
import { sameAddress } from 'src/logic/wallets/ethAddresses'
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
import UpdateSafeModal from 'src/routes/safe/components/Settings/UpdateSafeModal'
import { UpdateSafeModal } from 'src/routes/safe/components/Settings/UpdateSafeModal'
import { grantedSelector } from 'src/routes/safe/container/selector'
import updateSafe from 'src/logic/safe/store/actions/updateSafe'
import Link from 'src/components/layout/Link'

View File

@ -1,9 +1,7 @@
import IconButton from '@material-ui/core/IconButton'
import Close from '@material-ui/icons/Close'
import { withStyles } from '@material-ui/styles'
import React from 'react'
import React, { useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import { bindActionCreators } from 'redux'
import { styles } from './style'
@ -13,17 +11,61 @@ import Button from 'src/components/layout/Button'
import Hairline from 'src/components/layout/Hairline'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import { upgradeSafeToLatestVersion } from 'src/logic/safe/utils/upgradeSafe'
import { getUpgradeSafeTransactionHash } from 'src/logic/safe/utils/upgradeSafe'
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
import { makeStyles } from '@material-ui/core'
import { TransactionFees } from 'src/components/TransactionsFees'
import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas'
import { MULTI_SEND_ADDRESS } from 'src/logic/contracts/safeContracts'
import { DELEGATE_CALL } from 'src/logic/safe/transactions'
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
const UpdateSafeModal = ({ classes, onClose, safeAddress }) => {
const useStyles = makeStyles(styles)
type Props = {
onClose: () => void
safeAddress: string
}
export const UpdateSafeModal = ({ onClose, safeAddress }: Props): React.ReactElement => {
const classes = useStyles()
const dispatch = useDispatch()
const [multiSendCallData, setMultiSendCallData] = useState(EMPTY_DATA)
useEffect(() => {
const calculateUpgradeSafeModal = async () => {
const encodeMultiSendCallData = await getUpgradeSafeTransactionHash(safeAddress)
setMultiSendCallData(encodeMultiSendCallData)
}
calculateUpgradeSafeModal()
}, [safeAddress])
const handleSubmit = async () => {
// Call the update safe method
await upgradeSafeToLatestVersion(safeAddress, bindActionCreators(createTransaction, dispatch))
dispatch(
createTransaction({
safeAddress,
to: MULTI_SEND_ADDRESS,
valueInWei: '0',
txData: multiSendCallData,
notifiedTransaction: 'STANDARD_TX',
operation: DELEGATE_CALL,
}),
)
onClose()
}
const {
gasCostFormatted,
txEstimationExecutionStatus,
isExecution,
isCreation,
isOffChainSignature,
} = useEstimateTransactionGas({
txData: multiSendCallData,
txRecipient: safeAddress,
})
return (
<>
<Row align="center" className={classes.heading} grow>
@ -56,6 +98,15 @@ const UpdateSafeModal = ({ classes, onClose, safeAddress }) => {
have to confirm the update in case more than one confirmation is required for this Safe.
</Paragraph>
</Row>
<Row>
<TransactionFees
gasCostFormatted={gasCostFormatted}
isExecution={isExecution}
isCreation={isCreation}
isOffChainSignature={isOffChainSignature}
txEstimationExecutionStatus={txEstimationExecutionStatus}
/>
</Row>
</Block>
<Hairline style={{ position: 'absolute', bottom: 85 }} />
<Row align="center" className={classes.buttonRow}>
@ -72,5 +123,3 @@ const UpdateSafeModal = ({ classes, onClose, safeAddress }) => {
</>
)
}
export default withStyles(styles as any)(UpdateSafeModal)

View File

@ -1,6 +1,7 @@
import { lg, md, secondaryText, sm } from 'src/theme/variables'
import { createStyles } from '@material-ui/core'
export const styles = () => ({
export const styles = createStyles({
heading: {
padding: `${sm} ${lg}`,
justifyContent: 'space-between',