Fix/2292 dont trigger transactions with not enough signatures (#2312)
* Check if the transaction confirmations reaches the threshold * Added a notification when transaction doesn't have the confirmations * Added confirmations verification before opening the execute modal
This commit is contained in:
parent
e0e23255ad
commit
55b40f91be
|
@ -30,6 +30,7 @@ const NOTIFICATION_IDS = {
|
|||
TX_WAITING_MSG: 'TX_WAITING_MSG',
|
||||
TX_CONFIRMATION_EXECUTED_MSG: 'TX_CONFIRMATION_EXECUTED_MSG',
|
||||
TX_CONFIRMATION_FAILED_MSG: 'TX_CONFIRMATION_FAILED_MSG',
|
||||
TX_FETCH_SIGNATURES_ERROR_MSG: 'TX_FETCH_SIGNATURES_ERROR_MSG',
|
||||
SAFE_NAME_CHANGED_MSG: 'SAFE_NAME_CHANGED_MSG',
|
||||
OWNER_NAME_CHANGE_EXECUTED_MSG: 'OWNER_NAME_CHANGE_EXECUTED_MSG',
|
||||
SIGN_SETTINGS_CHANGE_MSG: 'SIGN_SETTINGS_CHANGE_MSG',
|
||||
|
@ -65,7 +66,6 @@ export const NOTIFICATIONS: Record<NotificationId, Notification> = {
|
|||
message: 'Error connecting to your wallet',
|
||||
options: { variant: ERROR, persist: true },
|
||||
},
|
||||
|
||||
// Regular/Custom Transactions
|
||||
SIGN_TX_MSG: {
|
||||
message: 'Please sign the transaction',
|
||||
|
@ -107,6 +107,11 @@ export const NOTIFICATIONS: Record<NotificationId, Notification> = {
|
|||
options: { variant: ERROR, persist: false, autoHideDuration: shortDuration },
|
||||
},
|
||||
|
||||
TX_FETCH_SIGNATURES_ERROR_MSG: {
|
||||
message: 'Couldn’t fetch all signatures for this transaction. Please reload page and try again',
|
||||
options: { variant: ERROR, persist: true },
|
||||
},
|
||||
|
||||
// Safe Name
|
||||
SAFE_NAME_CHANGED_MSG: {
|
||||
message: 'Safe name changed',
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import { MouseEvent as ReactMouseEvent, useCallback, useContext, useMemo, useRef } from 'react'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
import { Transaction } from 'src/logic/safe/store/models/types/gateway.d'
|
||||
import { MultiSigExecutionDetails, Transaction } from 'src/logic/safe/store/models/types/gateway.d'
|
||||
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
|
||||
import { addressInList } from 'src/routes/safe/components/Transactions/TxList/utils'
|
||||
import { useTransactionActions } from './useTransactionActions'
|
||||
import { TransactionActionStateContext } from 'src/routes/safe/components/Transactions/TxList/TxActionProvider'
|
||||
import { TxHoverContext } from 'src/routes/safe/components/Transactions/TxList/TxHoverProvider'
|
||||
import { TxLocationContext } from 'src/routes/safe/components/Transactions/TxList/TxLocationProvider'
|
||||
import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar'
|
||||
import { NOTIFICATIONS } from 'src/logic/notifications'
|
||||
|
||||
type ActionButtonsHandlers = {
|
||||
canCancel: boolean
|
||||
|
@ -24,18 +26,29 @@ export const useActionButtonsHandlers = (transaction: Transaction): ActionButton
|
|||
const actionContext = useRef(useContext(TransactionActionStateContext))
|
||||
const hoverContext = useRef(useContext(TxHoverContext))
|
||||
const locationContext = useRef(useContext(TxLocationContext))
|
||||
const dispatch = useDispatch()
|
||||
const { canCancel, canConfirmThenExecute, canExecute } = useTransactionActions(transaction)
|
||||
|
||||
const handleConfirmButtonClick = useCallback(
|
||||
(event: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
event.stopPropagation()
|
||||
if (transaction.txDetails?.detailedExecutionInfo?.type === 'MULTISIG') {
|
||||
const details = transaction.txDetails?.detailedExecutionInfo as MultiSigExecutionDetails
|
||||
if (
|
||||
(canExecute && details.confirmationsRequired > details.confirmations.length) ||
|
||||
(canConfirmThenExecute && details.confirmationsRequired - 1 > details.confirmations.length)
|
||||
) {
|
||||
dispatch(enqueueSnackbar(NOTIFICATIONS.TX_FETCH_SIGNATURES_ERROR_MSG))
|
||||
return
|
||||
}
|
||||
}
|
||||
actionContext.current.selectAction({
|
||||
actionSelected: canExecute || canConfirmThenExecute ? 'execute' : 'confirm',
|
||||
transactionId: transaction.id,
|
||||
txLocation: locationContext.current.txLocation,
|
||||
})
|
||||
},
|
||||
[canConfirmThenExecute, canExecute, transaction.id],
|
||||
[canConfirmThenExecute, canExecute, dispatch, transaction.id, transaction.txDetails?.detailedExecutionInfo],
|
||||
)
|
||||
|
||||
const handleCancelButtonClick = useCallback(
|
||||
|
|
|
@ -29,12 +29,14 @@ import { isThresholdReached } from 'src/routes/safe/components/Transactions/TxLi
|
|||
import { Overwrite } from 'src/types/helpers'
|
||||
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
|
||||
import { makeConfirmation } from 'src/logic/safe/store/models/confirmation'
|
||||
import { NOTIFICATIONS } from 'src/logic/notifications'
|
||||
import {
|
||||
ExpandedTxDetails,
|
||||
isMultiSigExecutionDetails,
|
||||
Operation,
|
||||
Transaction,
|
||||
} from 'src/logic/safe/store/models/types/gateway.d'
|
||||
import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar'
|
||||
|
||||
export const APPROVE_TX_MODAL_SUBMIT_BTN_TEST_ID = 'approve-tx-modal-submit-btn'
|
||||
export const REJECT_TX_MODAL_SUBMIT_BTN_TEST_ID = 'reject-tx-modal-submit-btn'
|
||||
|
@ -237,7 +239,6 @@ export const ApproveTxModal = ({
|
|||
origin,
|
||||
id,
|
||||
} = useTxInfo(transaction)
|
||||
|
||||
const {
|
||||
gasLimit,
|
||||
gasPriceFormatted,
|
||||
|
@ -263,32 +264,36 @@ export const ApproveTxModal = ({
|
|||
const handleExecuteCheckbox = () => setApproveAndExecute((prevApproveAndExecute) => !prevApproveAndExecute)
|
||||
|
||||
const approveTx = (txParameters: TxParameters) => {
|
||||
dispatch(
|
||||
processTransaction({
|
||||
safeAddress,
|
||||
tx: {
|
||||
id,
|
||||
baseGas,
|
||||
confirmations,
|
||||
data,
|
||||
gasPrice,
|
||||
gasToken,
|
||||
nonce,
|
||||
operation,
|
||||
origin,
|
||||
refundReceiver,
|
||||
safeTxGas,
|
||||
safeTxHash,
|
||||
to,
|
||||
value,
|
||||
},
|
||||
userAddress,
|
||||
notifiedTransaction: TX_NOTIFICATION_TYPES.CONFIRMATION_TX,
|
||||
approveAndExecute: canExecute && approveAndExecute && isTheTxReadyToBeExecuted,
|
||||
ethParameters: txParameters,
|
||||
thresholdReached,
|
||||
}),
|
||||
)
|
||||
if (thresholdReached && confirmations.size < _threshold) {
|
||||
dispatch(enqueueSnackbar(NOTIFICATIONS.TX_FETCH_SIGNATURES_ERROR_MSG))
|
||||
} else {
|
||||
dispatch(
|
||||
processTransaction({
|
||||
safeAddress,
|
||||
tx: {
|
||||
id,
|
||||
baseGas,
|
||||
confirmations,
|
||||
data,
|
||||
gasPrice,
|
||||
gasToken,
|
||||
nonce,
|
||||
operation,
|
||||
origin,
|
||||
refundReceiver,
|
||||
safeTxGas,
|
||||
safeTxHash,
|
||||
to,
|
||||
value,
|
||||
},
|
||||
userAddress,
|
||||
notifiedTransaction: TX_NOTIFICATION_TYPES.CONFIRMATION_TX,
|
||||
approveAndExecute: canExecute && approveAndExecute && isTheTxReadyToBeExecuted,
|
||||
ethParameters: txParameters,
|
||||
thresholdReached,
|
||||
}),
|
||||
)
|
||||
}
|
||||
onClose()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue