From 67af60ef7168134761c9a099d0023be0bb68c902 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Thu, 21 Jan 2021 15:26:25 -0300 Subject: [PATCH 1/4] Adds isEmptyAddress method --- src/logic/wallets/ethAddresses.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/logic/wallets/ethAddresses.ts b/src/logic/wallets/ethAddresses.ts index 834e6654..891da66a 100644 --- a/src/logic/wallets/ethAddresses.ts +++ b/src/logic/wallets/ethAddresses.ts @@ -1,12 +1,18 @@ import { List } from 'immutable' import { SafeRecord } from 'src/logic/safe/store/models/safe' import { sameString } from 'src/utils/strings' +import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' export const sameAddress = (firstAddress: string | undefined, secondAddress: string | undefined): boolean => { return sameString(firstAddress, secondAddress) } +export const isEmptyAddress = (address: string | undefined): boolean => { + if (!address) return true + return sameAddress(address, EMPTY_DATA) || sameAddress(address, ZERO_ADDRESS) +} + export const shortVersionOf = (value: string, cut: number): string => { if (!value) { return 'Unknown' From b6577f8e6f0ff6bd4f483ae6618df456c3680bff Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Thu, 21 Jan 2021 15:26:44 -0300 Subject: [PATCH 2/4] Updates isCancelTransaction logic and tests --- .../__tests__/transactionHelpers.test.ts | 92 +++++++++++++++++++ .../transactions/utils/transactionHelpers.ts | 43 ++++++++- 2 files changed, 130 insertions(+), 5 deletions(-) diff --git a/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts b/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts index c4e80e91..86d342c8 100644 --- a/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts +++ b/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts @@ -23,6 +23,7 @@ import { isUpgradeTransaction, } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' import { getERC20DecimalsAndSymbol } from 'src/logic/tokens/utils/tokenHelpers' +import { DELEGATE_CALL } from 'src/logic/safe/transactions' const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' const safeAddress2 = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' @@ -91,6 +92,7 @@ describe('isInnerTransaction', () => { describe('isCancelTransaction', () => { const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' + const mockedETHAccount = '0xd76e0B566e218a80F4c96458FE09a322EBAa9aF2' it('It should return false if given a inner transaction with empty data', () => { // given const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null }) @@ -111,6 +113,96 @@ describe('isCancelTransaction', () => { // then expect(result).toBe(false) }) + it('It should return false if the transaction recipient is not the safeAddress', () => { + // given + const transaction = getMockedTxServiceModel({ to: mockedETHAccount, value: '0', data: null }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the transaction value is not empty', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '100', data: null }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the transaction data is not empty', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: mockedETHAccount }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the transaction operation is not call', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, operation: DELEGATE_CALL }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the transaction baseGas is not empty', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, baseGas: 10 }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the transaction gasPrice is not empty', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, gasPrice: '10' }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the transaction gasToken is not empty', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, gasToken: mockedETHAccount }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return false if the refundReceiver is not empty', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, refundReceiver: mockedETHAccount }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(false) + }) + it('It should return true for a transaction with everything empty except for to parameter equals to the safeAddress,', () => { + // given + const transaction = getMockedTxServiceModel({ to: safeAddress }) + + // when + const result = isCancelTransaction(transaction, safeAddress) + + // then + expect(result).toBe(true) + }) }) describe('isPendingTransaction', () => { diff --git a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts index b776b71c..ddf2d4d3 100644 --- a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts +++ b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts @@ -2,7 +2,7 @@ import { List } from 'immutable' import { getNetworkInfo } from 'src/config' import { getERC20DecimalsAndSymbol, isSendERC20Transaction } from 'src/logic/tokens/utils/tokenHelpers' import { getERC721Symbol, isSendERC721Transaction } from 'src/logic/collectibles/utils' -import { sameAddress, ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' +import { isEmptyAddress, sameAddress, ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' import { makeConfirmation } from 'src/logic/safe/store/models/confirmation' import { Confirmation } from 'src/logic/safe/store/models/types/confirmation' @@ -31,6 +31,7 @@ import { TypedDataUtils } from 'eth-sig-util' import { ProviderRecord } from 'src/logic/wallets/store/model/provider' import { SafeRecord } from 'src/logic/safe/store/models/safe' import { DataDecoded, DecodedParams } from 'src/routes/safe/store/models/types/transactions.d' +import { CALL } from 'src/logic/safe/transactions' export const isEmptyData = (data?: string | null): boolean => { return !data || data === EMPTY_DATA @@ -48,8 +49,40 @@ export const isInnerTransaction = (tx: TxServiceModel | Transaction, safeAddress return isSameAddress && Number(tx.value) === 0 } -export const isCancelTransaction = (tx: TxServiceModel | Transaction, safeAddress: string): boolean => { - return isInnerTransaction(tx, safeAddress) && isEmptyData(tx.data) +export const isCancelTransaction = (tx: TxServiceModel, safeAddress: string): boolean => { + if (!sameAddress(tx.to, safeAddress)) { + return false + } + + if (Number(tx.value)) { + return false + } + + if (tx.data && !isEmptyData(tx.data)) { + return false + } + + if (tx.operation !== CALL) { + return false + } + + if (tx.baseGas) { + return false + } + + if (Number(tx.gasPrice)) { + return false + } + + if (tx.gasToken && !isEmptyAddress(tx.gasToken)) { + return false + } + + if (tx.refundReceiver && !isEmptyAddress(tx.refundReceiver)) { + return false + } + + return true } export const isPendingTransaction = (tx: Transaction, cancelTx: Transaction): boolean => { @@ -73,11 +106,11 @@ export const isUpgradeTransaction = (tx: TxServiceModel): boolean => { ) } -export const isOutgoingTransaction = (tx: TxServiceModel, safeAddress?: string): boolean => { +export const isOutgoingTransaction = (tx: TxServiceModel, safeAddress: string): boolean => { return !sameAddress(tx.to, safeAddress) && !isEmptyData(tx.data) } -export const isCustomTransaction = async (tx: TxServiceModel, safeAddress?: string): Promise => { +export const isCustomTransaction = async (tx: TxServiceModel, safeAddress: string): Promise => { const isOutgoing = isOutgoingTransaction(tx, safeAddress) const isErc20 = await isSendERC20Transaction(tx) const isUpgrade = isUpgradeTransaction(tx) From a604da1b6cfdea2f0ee0f46ee1c02d15617a2e56 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Thu, 21 Jan 2021 17:46:32 -0300 Subject: [PATCH 3/4] Fix prettier --- .../store/actions/__tests__/transactionHelpers.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts b/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts index 86d342c8..a639ead5 100644 --- a/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts +++ b/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts @@ -185,7 +185,12 @@ describe('isCancelTransaction', () => { }) it('It should return false if the refundReceiver is not empty', () => { // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, refundReceiver: mockedETHAccount }) + const transaction = getMockedTxServiceModel({ + to: safeAddress, + value: '0', + data: null, + refundReceiver: mockedETHAccount, + }) // when const result = isCancelTransaction(transaction, safeAddress) From f47bc7f175814849c6623c990fe8161cd972d766 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Fri, 22 Jan 2021 09:03:01 +0100 Subject: [PATCH 4/4] Set v2.17.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 01320285..027addfe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "safe-react", - "version": "2.17.1", + "version": "2.17.2", "description": "Allowing crypto users manage funds in a safer way", "website": "https://github.com/gnosis/safe-react#readme", "bugs": {