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
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: 2 additions & 0 deletions src/logic/safe/store/actions/createTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import semverSatisfies from 'semver/functions/satisfies'
import { ThunkAction } from 'redux-thunk'

import { onboardUser } from 'src/components/ConnectButton'
import { decodeMethods } from 'src/logic/contracts/methodIds'
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
import { getNotificationsFromTxType } from 'src/logic/notifications'
import {
Expand Down Expand Up @@ -205,6 +206,7 @@ const createTransaction = (
confirmations: [], // this is used to determine if a tx is pending or not. See `calculateTransactionStatus` helper
value: txArgs.valueInWei,
safeTxHash,
dataDecoded: decodeMethods(txArgs.data),
submissionDate: new Date().toISOString(),
}
const mockedTx = await mockTransaction(txToMock, safeAddress, state)
Expand Down
39 changes: 23 additions & 16 deletions src/logic/safe/store/actions/processTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { fromJS } from 'immutable'
import semverSatisfies from 'semver/functions/satisfies'

import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
Expand All @@ -20,9 +19,9 @@ import {
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils'

import { getErrorMessage } from 'src/test/utils/ethereumErrors'
import { makeConfirmation } from '../models/confirmation'
import { storeTx } from './createTransaction'
import { TransactionStatus } from '../models/types/transaction'
import { TransactionStatus } from 'src/logic/safe/store/models/types/transaction'
import { makeConfirmation } from 'src/logic/safe/store/models/confirmation'

const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddress, tx, userAddress }) => async (
dispatch,
Expand Down Expand Up @@ -85,6 +84,8 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
dispatch(closeSnackbarAction(beforeExecutionKey))

await saveTxToHistory({ ...txArgs, signature })
// TODO: while we wait for the tx to be stored in the service and later update the tx info
// we should update the tx status in the store to disable owners' action buttons
dispatch(enqueueSnackbar(notificationsQueue.afterExecution.moreConfirmationsNeeded))

dispatch(fetchTransactions(safeAddress))
Expand All @@ -105,9 +106,7 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres

const txToMock: TxToMock = {
...txArgs,
confirmations: txArgs.confirmations, // this is used to determine if a tx is pending or not. See `calculateTransactionStatus` helper
value: txArgs.valueInWei,
submissionDate: txArgs.submissionDate,
}
const mockedTx = await mockTransaction(txToMock, safeAddress, state)

Expand All @@ -123,10 +122,14 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
await Promise.all([
saveTxToHistory({ ...txArgs, txHash }),
storeTx(
mockedTx.updateIn(
['ownersWithPendingActions', mockedTx.isCancellationTx ? 'reject' : 'confirm'],
(previous) => previous.push(from),
),
mockedTx.withMutations((record) => {
record
.updateIn(
['ownersWithPendingActions', mockedTx.isCancellationTx ? 'reject' : 'confirm'],
(previous) => previous.push(from),
)
.set('status', TransactionStatus.PENDING)
}),
safeAddress,
dispatch,
state,
Expand Down Expand Up @@ -175,16 +178,20 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
: TransactionStatus.FAILED,
)
.updateIn(['ownersWithPendingActions', 'reject'], (prev) => prev.clear())
.updateIn(['ownersWithPendingActions', 'confirm'], (prev) => prev.clear())
})
: mockedTx.withMutations((record) => {
record
.updateIn(['ownersWithPendingActions', toStoreTx.isCancellationTx ? 'reject' : 'confirm'], (previous) =>
previous.pop(),
)
.set('status', TransactionStatus.AWAITING_CONFIRMATIONS)
})
: mockedTx.set('status', TransactionStatus.AWAITING_CONFIRMATIONS)

await storeTx(
toStoreTx.withMutations((record) => {
record
.set('confirmations', fromJS([...tx.confirmations, makeConfirmation({ owner: from })]))
.updateIn(['ownersWithPendingActions', toStoreTx.isCancellationTx ? 'reject' : 'confirm'], (previous) =>
previous.pop(from),
)
toStoreTx.update('confirmations', (confirmations) => {
const index = confirmations.findIndex(({ owner }) => owner === from)
return index === -1 ? confirmations.push(makeConfirmation({ owner: from })) : confirmations
}),
safeAddress,
dispatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { TypedDataUtils } from 'eth-sig-util'
import { Token } from 'src/logic/tokens/store/model/token'
import { ProviderRecord } from 'src/logic/wallets/store/model/provider'
import { SafeRecord } from 'src/logic/safe/store/models/safe'
import { DecodedParams } from 'src/routes/safe/store/models/types/transactions.d'
import { DataDecoded, DecodedParams } from 'src/routes/safe/store/models/types/transactions.d'

export const isEmptyData = (data?: string | null): boolean => {
return !data || data === EMPTY_DATA
Expand Down Expand Up @@ -316,6 +316,7 @@ export type TxToMock = TxArgs & {
safeTxHash: string
value: string
submissionDate: string
dataDecoded: DataDecoded | null
}

export const mockTransaction = (tx: TxToMock, safeAddress: string, state: AppReduxState): Promise<Transaction> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ const OwnersColumn = ({
displayButtonRow = false
}

// TODO: simplify this whole logic around tx status, it's getting hard to maintain and follow
const showConfirmBtn =
!tx.isExecuted &&
tx.status !== 'pending' &&
Expand All @@ -151,7 +152,8 @@ const OwnersColumn = ({
!currentUserAlreadyConfirmed &&
!thresholdReached

const showExecuteBtn = canExecute && !tx.isExecuted && thresholdReached
const showExecuteBtn =
canExecute && !tx.isExecuted && thresholdReached && tx.status !== 'pending' && cancelTx.status !== 'pending'

const showRejectBtn =
!cancelTx.isExecuted &&
Expand All @@ -163,7 +165,13 @@ const OwnersColumn = ({
!cancelThresholdReached &&
displayButtonRow

const showExecuteRejectBtn = !cancelTx.isExecuted && !tx.isExecuted && canExecuteCancel && cancelThresholdReached
const showExecuteRejectBtn =
!cancelTx.isExecuted &&
!tx.isExecuted &&
canExecuteCancel &&
cancelThresholdReached &&
tx.status !== 'pending' &&
cancelTx.status !== 'pending'

const txThreshold = cancelTx.isExecuted ? tx.confirmations.size : threshold
const cancelThreshold = tx.isExecuted ? cancelTx.confirmations.size : threshold
Expand Down