From 241c1aa1ff494bc15f674b5799e748ef1766ae26 Mon Sep 17 00:00:00 2001 From: Aaron Cook Date: Fri, 7 Mar 2025 14:53:11 +0100 Subject: [PATCH] refactor: reduce mock signature complexity --- .../helpers/message-verifier.helper.spec.ts | 4 +- .../messages/messages.controller.spec.ts | 10 +- ...firmations.transactions.controller.spec.ts | 5 +- ...tion-by-id.transactions.controller.spec.ts | 2 +- ...ns-by-safe.transactions.controller.spec.ts | 2 +- ...ransaction.transactions.controller.spec.ts | 438 +++++++++--------- .../transaction-verifier.helper.spec.ts | 9 +- 7 files changed, 228 insertions(+), 242 deletions(-) diff --git a/src/domain/messages/helpers/message-verifier.helper.spec.ts b/src/domain/messages/helpers/message-verifier.helper.spec.ts index fc8b93713b..21b04a8915 100644 --- a/src/domain/messages/helpers/message-verifier.helper.spec.ts +++ b/src/domain/messages/helpers/message-verifier.helper.spec.ts @@ -252,7 +252,7 @@ describe('MessageVerifierHelper', () => { safe, message: message.message, messageHash: message.messageHash, - signature: `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, + signature: `0x${'-'.repeat(128)}${v}`, }); }).toThrow(new HttpExceptionNoLog('Could not recover address', 422)); @@ -610,7 +610,7 @@ describe('MessageVerifierHelper', () => { safe, message: message.message, messageHash: message.messageHash, - signature: `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, + signature: `0x${'-'.repeat(128)}${v}`, }); }).toThrow(new HttpExceptionNoLog('Could not recover address', 422)); diff --git a/src/routes/messages/messages.controller.spec.ts b/src/routes/messages/messages.controller.spec.ts index d395095f75..33716a761c 100644 --- a/src/routes/messages/messages.controller.spec.ts +++ b/src/routes/messages/messages.controller.spec.ts @@ -1035,10 +1035,7 @@ describe('Messages controller', () => { .send( createMessageDtoBuilder() .with('message', message.message) - .with( - 'signature', - `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, - ) + .with('signature', `0x${'-'.repeat(128)}${v}`) .build(), ) .expect(422) @@ -1568,10 +1565,7 @@ describe('Messages controller', () => { ) .send( updateMessageSignatureDtoBuilder() - .with( - 'signature', - `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, - ) + .with('signature', `0x${'-'.repeat(128)}${v}`) .build(), ) .expect(422) diff --git a/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts index f165ad775f..0832d497ab 100644 --- a/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts @@ -509,10 +509,7 @@ describe('Add transaction confirmations - Transactions Controller (Unit)', () => ) as MultisigTransaction; const v = transaction.confirmations![0].signature?.slice(-2); const addConfirmationDto = addConfirmationDtoBuilder() - .with( - 'signature', - `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, - ) + .with('signature', `0x${'-'.repeat(128)}${v}`) .build(); await request(app.getHttpServer()) diff --git a/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts index fb0461bb2e..edfd350a5b 100644 --- a/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts @@ -1392,7 +1392,7 @@ describe('Get by id - Transactions Controller (Unit)', () => { signatureType, }); const v = multisigTransaction.confirmations![0].signature?.slice(-2); - multisigTransaction.confirmations![0].signature = `0x--------------------------------------------------------------------------------------------------------------------------------${v}`; + multisigTransaction.confirmations![0].signature = `0x${'-'.repeat(128)}${v}`; const getSafeUrl = `${chain.transactionService}/api/v1/safes/${safe.address}`; const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chain.chainId}`; diff --git a/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts index 85aaa2847d..1ee219b79b 100644 --- a/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts @@ -1077,7 +1077,7 @@ describe('List queued transactions by Safe - Transactions Controller (Unit)', () }; const nonce1 = await getTransaction(1); const v = nonce1.confirmations![0].signature?.slice(-2); - nonce1.confirmations![0].signature = `0x--------------------------------------------------------------------------------------------------------------------------------${v}`; + nonce1.confirmations![0].signature = `0x${'-'.repeat(128)}${v}`; const nonce2 = await getTransaction(2); const transactions: Array = [ multisigToJson(nonce1) as MultisigTransaction, diff --git a/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts index bd398b8b2b..0bc144e0f2 100644 --- a/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts @@ -801,10 +801,7 @@ describe('Propose transaction - Transactions Controller (Unit)', () => { .with('refundReceiver', transaction.refundReceiver) .with('safeTxHash', transaction.safeTxHash) .with('sender', transaction.confirmations![0].owner) - .with( - 'signature', - `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, - ) + .with('signature', `0x${'-'.repeat(128)}${v}`) .build(); const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chain.chainId}`; const getMultisigTransactionUrl = `${chain.transactionService}/api/v1/multisig-transactions/${proposeTransactionDto.safeTxHash}/`; @@ -1171,229 +1168,230 @@ describe('Propose transaction - Transactions Controller (Unit)', () => { source: 'PROPOSAL', }); }); - + // TODO: Move to TODOs further up - it('should allow delegate calls if the contract is included in the list of trusted contracts', async () => { - const baseConfiguration = configuration(); - const testConfiguration = (): typeof baseConfiguration => ({ - ...baseConfiguration, - features: { - ...baseConfiguration.features, - ethSign: true, - trustedDelegateCall: true, - trustedForDelegateCallContractsList: true, - }, - }); - await initApp(testConfiguration); + it('should allow delegate calls if the contract is included in the list of trusted contracts', async () => { + const baseConfiguration = configuration(); + const testConfiguration = (): typeof baseConfiguration => ({ + ...baseConfiguration, + features: { + ...baseConfiguration.features, + ethSign: true, + trustedDelegateCall: true, + trustedForDelegateCallContractsList: true, + }, + }); + await initApp(testConfiguration); - const chainId = faker.string.numeric(); - const safeAddress = getAddress(faker.finance.ethereumAddress()); - const chain = chainBuilder().with('chainId', chainId).build(); - const privateKey = generatePrivateKey(); - const signer = privateKeyToAccount(privateKey); - const safe = safeBuilder() - .with('address', safeAddress) - .with('owners', [signer.address]) - .build(); - const safeApps = [safeAppBuilder().build()]; - const transaction = await multisigTransactionBuilder() - .with('safe', safeAddress) - .with('nonce', safe.nonce) - .with('operation', Operation.DELEGATE) - .buildWithConfirmations({ - chainId, - safe, - signers: [signer], + const chainId = faker.string.numeric(); + const safeAddress = getAddress(faker.finance.ethereumAddress()); + const chain = chainBuilder().with('chainId', chainId).build(); + const privateKey = generatePrivateKey(); + const signer = privateKeyToAccount(privateKey); + const safe = safeBuilder() + .with('address', safeAddress) + .with('owners', [signer.address]) + .build(); + const safeApps = [safeAppBuilder().build()]; + const transaction = await multisigTransactionBuilder() + .with('safe', safeAddress) + .with('nonce', safe.nonce) + .with('operation', Operation.DELEGATE) + .buildWithConfirmations({ + chainId, + safe, + signers: [signer], + }); + const contractPage = pageBuilder() + .with('results', [ + contractBuilder().with('trustedForDelegateCall', true).build(), + contractBuilder() + .with('trustedForDelegateCall', true) + .with('address', transaction.to) // transaction.to address is a trusted contract + .build(), + contractBuilder().with('trustedForDelegateCall', true).build(), + ]) + .build(); + const proposeTransactionDto = proposeTransactionDtoBuilder() + .with('to', transaction.to) + .with('value', transaction.value) + .with('data', transaction.data) + .with('nonce', transaction.nonce.toString()) + .with('operation', transaction.operation) + .with('safeTxGas', transaction.safeTxGas!.toString()) + .with('baseGas', transaction.baseGas!.toString()) + .with('gasPrice', transaction.gasPrice!) + .with('gasToken', transaction.gasToken!) + .with('refundReceiver', transaction.refundReceiver) + .with('safeTxHash', transaction.safeTxHash) + .with('sender', transaction.confirmations![0].owner) + .with('signature', transaction.confirmations![0].signature) + .build(); + const transactions = pageBuilder().build(); + const token = tokenBuilder().build(); + const gasToken = tokenBuilder().build(); + networkService.get.mockImplementation(({ url }) => { + const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chainId}`; + const getMultisigTransactionUrl = `${chain.transactionService}/api/v1/multisig-transactions/${proposeTransactionDto.safeTxHash}/`; + const getMultisigTransactionsUrl = `${chain.transactionService}/api/v1/safes/${safe.address}/multisig-transactions/`; + const getSafeUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}`; + const getSafeAppsUrl = `${safeConfigUrl}/api/v1/safe-apps/`; + const getContractsUrl = `${chain.transactionService}/api/v1/contracts/`; + const getTokenUrl = `${chain.transactionService}/api/v1/tokens/${transaction.to}`; + const getGasTokenContractUrl = `${chain.transactionService}/api/v1/tokens/${transaction.gasToken}`; + switch (url) { + case getChainUrl: + return Promise.resolve({ data: rawify(chain), status: 200 }); + case getMultisigTransactionUrl: + return Promise.resolve({ + data: rawify(multisigToJson(transaction)), + status: 200, + }); + case getMultisigTransactionsUrl: + return Promise.resolve({ data: rawify(transactions), status: 200 }); + case getSafeUrl: + return Promise.resolve({ data: rawify(safe), status: 200 }); + case getSafeAppsUrl: + return Promise.resolve({ data: rawify(safeApps), status: 200 }); + case getContractsUrl: + return Promise.resolve({ data: rawify(contractPage), status: 200 }); + case getTokenUrl: + return Promise.resolve({ data: rawify(token), status: 200 }); + case getGasTokenContractUrl: + return Promise.resolve({ data: rawify(gasToken), status: 200 }); + default: + return Promise.reject(new Error(`Could not match ${url}`)); + } }); - const contractPage = pageBuilder() - .with('results', [ - contractBuilder().with('trustedForDelegateCall', true).build(), - contractBuilder() - .with('trustedForDelegateCall', true) - .with('address', transaction.to) // transaction.to address is a trusted contract - .build(), - contractBuilder().with('trustedForDelegateCall', true).build(), - ]) - .build(); - const proposeTransactionDto = proposeTransactionDtoBuilder() - .with('to', transaction.to) - .with('value', transaction.value) - .with('data', transaction.data) - .with('nonce', transaction.nonce.toString()) - .with('operation', transaction.operation) - .with('safeTxGas', transaction.safeTxGas!.toString()) - .with('baseGas', transaction.baseGas!.toString()) - .with('gasPrice', transaction.gasPrice!) - .with('gasToken', transaction.gasToken!) - .with('refundReceiver', transaction.refundReceiver) - .with('safeTxHash', transaction.safeTxHash) - .with('sender', transaction.confirmations![0].owner) - .with('signature', transaction.confirmations![0].signature) - .build(); - const transactions = pageBuilder().build(); - const token = tokenBuilder().build(); - const gasToken = tokenBuilder().build(); - networkService.get.mockImplementation(({ url }) => { - const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chainId}`; - const getMultisigTransactionUrl = `${chain.transactionService}/api/v1/multisig-transactions/${proposeTransactionDto.safeTxHash}/`; - const getMultisigTransactionsUrl = `${chain.transactionService}/api/v1/safes/${safe.address}/multisig-transactions/`; - const getSafeUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}`; - const getSafeAppsUrl = `${safeConfigUrl}/api/v1/safe-apps/`; - const getContractsUrl = `${chain.transactionService}/api/v1/contracts/`; - const getTokenUrl = `${chain.transactionService}/api/v1/tokens/${transaction.to}`; - const getGasTokenContractUrl = `${chain.transactionService}/api/v1/tokens/${transaction.gasToken}`; - switch (url) { - case getChainUrl: - return Promise.resolve({ data: rawify(chain), status: 200 }); - case getMultisigTransactionUrl: - return Promise.resolve({ - data: rawify(multisigToJson(transaction)), - status: 200, - }); - case getMultisigTransactionsUrl: - return Promise.resolve({ data: rawify(transactions), status: 200 }); - case getSafeUrl: - return Promise.resolve({ data: rawify(safe), status: 200 }); - case getSafeAppsUrl: - return Promise.resolve({ data: rawify(safeApps), status: 200 }); - case getContractsUrl: - return Promise.resolve({ data: rawify(contractPage), status: 200 }); - case getTokenUrl: - return Promise.resolve({ data: rawify(token), status: 200 }); - case getGasTokenContractUrl: - return Promise.resolve({ data: rawify(gasToken), status: 200 }); - default: - return Promise.reject(new Error(`Could not match ${url}`)); - } - }); - networkService.post.mockImplementation(({ url }) => { - const proposeTransactionUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}/multisig-transactions/`; - switch (url) { - case proposeTransactionUrl: - return Promise.resolve({ data: rawify({}), status: 200 }); - default: - return Promise.reject(new Error(`Could not match ${url}`)); - } + networkService.post.mockImplementation(({ url }) => { + const proposeTransactionUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}/multisig-transactions/`; + switch (url) { + case proposeTransactionUrl: + return Promise.resolve({ data: rawify({}), status: 200 }); + default: + return Promise.reject(new Error(`Could not match ${url}`)); + } + }); + await request(app.getHttpServer()) + .post(`/v1/chains/${chainId}/transactions/${safeAddress}/propose`) + .send(proposeTransactionDto) + .expect(200) + .expect(({ body }) => + expect(body).toEqual( + expect.objectContaining({ + txId: `multisig_${safeAddress}_${transaction.safeTxHash}`, + }), + ), + ); }); - await request(app.getHttpServer()) - .post(`/v1/chains/${chainId}/transactions/${safeAddress}/propose`) - .send(proposeTransactionDto) - .expect(200) - .expect(({ body }) => - expect(body).toEqual( - expect.objectContaining({ - txId: `multisig_${safeAddress}_${transaction.safeTxHash}`, - }), - ), - ); - }); - it('should disallow delegate calls if the contract is not included in the list of trusted contracts', async () => { - const baseConfiguration = configuration(); - const testConfiguration = (): typeof baseConfiguration => ({ - ...baseConfiguration, - features: { - ...baseConfiguration.features, - ethSign: true, - trustedDelegateCall: true, - trustedForDelegateCallContractsList: true, - }, - }); - await initApp(testConfiguration); + it('should disallow delegate calls if the contract is not included in the list of trusted contracts', async () => { + const baseConfiguration = configuration(); + const testConfiguration = (): typeof baseConfiguration => ({ + ...baseConfiguration, + features: { + ...baseConfiguration.features, + ethSign: true, + trustedDelegateCall: true, + trustedForDelegateCallContractsList: true, + }, + }); + await initApp(testConfiguration); - const chainId = faker.string.numeric(); - const safeAddress = getAddress(faker.finance.ethereumAddress()); - const chain = chainBuilder().with('chainId', chainId).build(); - const privateKey = generatePrivateKey(); - const signer = privateKeyToAccount(privateKey); - const safe = safeBuilder() - .with('address', safeAddress) - .with('owners', [signer.address]) - .build(); - const safeApps = [safeAppBuilder().build()]; - const transaction = await multisigTransactionBuilder() - .with('safe', safeAddress) - .with('nonce', safe.nonce) - .with('operation', Operation.DELEGATE) - .buildWithConfirmations({ - chainId, - safe, - signers: [signer], + const chainId = faker.string.numeric(); + const safeAddress = getAddress(faker.finance.ethereumAddress()); + const chain = chainBuilder().with('chainId', chainId).build(); + const privateKey = generatePrivateKey(); + const signer = privateKeyToAccount(privateKey); + const safe = safeBuilder() + .with('address', safeAddress) + .with('owners', [signer.address]) + .build(); + const safeApps = [safeAppBuilder().build()]; + const transaction = await multisigTransactionBuilder() + .with('safe', safeAddress) + .with('nonce', safe.nonce) + .with('operation', Operation.DELEGATE) + .buildWithConfirmations({ + chainId, + safe, + signers: [signer], + }); + const contractPage = pageBuilder() + .with('results', [ + // transaction.to address is not in the list of trusted contracts + contractBuilder().with('trustedForDelegateCall', true).build(), + contractBuilder().with('trustedForDelegateCall', true).build(), + ]) + .build(); + const proposeTransactionDto = proposeTransactionDtoBuilder() + .with('to', transaction.to) + .with('value', transaction.value) + .with('data', transaction.data) + .with('nonce', transaction.nonce.toString()) + .with('operation', transaction.operation) + .with('safeTxGas', transaction.safeTxGas!.toString()) + .with('baseGas', transaction.baseGas!.toString()) + .with('gasPrice', transaction.gasPrice!) + .with('gasToken', transaction.gasToken!) + .with('refundReceiver', transaction.refundReceiver) + .with('safeTxHash', transaction.safeTxHash) + .with('sender', transaction.confirmations![0].owner) + .with('signature', transaction.confirmations![0].signature) + .build(); + const transactions = pageBuilder().build(); + const token = tokenBuilder().build(); + const gasToken = tokenBuilder().build(); + networkService.get.mockImplementation(({ url }) => { + const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chainId}`; + const getMultisigTransactionUrl = `${chain.transactionService}/api/v1/multisig-transactions/${proposeTransactionDto.safeTxHash}/`; + const getMultisigTransactionsUrl = `${chain.transactionService}/api/v1/safes/${safe.address}/multisig-transactions/`; + const getSafeUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}`; + const getSafeAppsUrl = `${safeConfigUrl}/api/v1/safe-apps/`; + const getContractsUrl = `${chain.transactionService}/api/v1/contracts/`; + const getTokenUrl = `${chain.transactionService}/api/v1/tokens/${transaction.to}`; + const getGasTokenContractUrl = `${chain.transactionService}/api/v1/tokens/${transaction.gasToken}`; + switch (url) { + case getChainUrl: + return Promise.resolve({ data: rawify(chain), status: 200 }); + case getMultisigTransactionUrl: + return Promise.resolve({ + data: rawify(multisigToJson(transaction)), + status: 200, + }); + case getMultisigTransactionsUrl: + return Promise.resolve({ data: rawify(transactions), status: 200 }); + case getSafeUrl: + return Promise.resolve({ data: rawify(safe), status: 200 }); + case getSafeAppsUrl: + return Promise.resolve({ data: rawify(safeApps), status: 200 }); + case getContractsUrl: + return Promise.resolve({ data: rawify(contractPage), status: 200 }); + case getTokenUrl: + return Promise.resolve({ data: rawify(token), status: 200 }); + case getGasTokenContractUrl: + return Promise.resolve({ data: rawify(gasToken), status: 200 }); + default: + return Promise.reject(new Error(`Could not match ${url}`)); + } }); - const contractPage = pageBuilder() - .with('results', [ - // transaction.to address is not in the list of trusted contracts - contractBuilder().with('trustedForDelegateCall', true).build(), - contractBuilder().with('trustedForDelegateCall', true).build(), - ]) - .build(); - const proposeTransactionDto = proposeTransactionDtoBuilder() - .with('to', transaction.to) - .with('value', transaction.value) - .with('data', transaction.data) - .with('nonce', transaction.nonce.toString()) - .with('operation', transaction.operation) - .with('safeTxGas', transaction.safeTxGas!.toString()) - .with('baseGas', transaction.baseGas!.toString()) - .with('gasPrice', transaction.gasPrice!) - .with('gasToken', transaction.gasToken!) - .with('refundReceiver', transaction.refundReceiver) - .with('safeTxHash', transaction.safeTxHash) - .with('sender', transaction.confirmations![0].owner) - .with('signature', transaction.confirmations![0].signature) - .build(); - const transactions = pageBuilder().build(); - const token = tokenBuilder().build(); - const gasToken = tokenBuilder().build(); - networkService.get.mockImplementation(({ url }) => { - const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chainId}`; - const getMultisigTransactionUrl = `${chain.transactionService}/api/v1/multisig-transactions/${proposeTransactionDto.safeTxHash}/`; - const getMultisigTransactionsUrl = `${chain.transactionService}/api/v1/safes/${safe.address}/multisig-transactions/`; - const getSafeUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}`; - const getSafeAppsUrl = `${safeConfigUrl}/api/v1/safe-apps/`; - const getContractsUrl = `${chain.transactionService}/api/v1/contracts/`; - const getTokenUrl = `${chain.transactionService}/api/v1/tokens/${transaction.to}`; - const getGasTokenContractUrl = `${chain.transactionService}/api/v1/tokens/${transaction.gasToken}`; - switch (url) { - case getChainUrl: - return Promise.resolve({ data: rawify(chain), status: 200 }); - case getMultisigTransactionUrl: - return Promise.resolve({ - data: rawify(multisigToJson(transaction)), - status: 200, - }); - case getMultisigTransactionsUrl: - return Promise.resolve({ data: rawify(transactions), status: 200 }); - case getSafeUrl: - return Promise.resolve({ data: rawify(safe), status: 200 }); - case getSafeAppsUrl: - return Promise.resolve({ data: rawify(safeApps), status: 200 }); - case getContractsUrl: - return Promise.resolve({ data: rawify(contractPage), status: 200 }); - case getTokenUrl: - return Promise.resolve({ data: rawify(token), status: 200 }); - case getGasTokenContractUrl: - return Promise.resolve({ data: rawify(gasToken), status: 200 }); - default: - return Promise.reject(new Error(`Could not match ${url}`)); - } - }); - networkService.post.mockImplementation(({ url }) => { - const proposeTransactionUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}/multisig-transactions/`; - switch (url) { - case proposeTransactionUrl: - return Promise.resolve({ data: rawify({}), status: 200 }); - default: - return Promise.reject(new Error(`Could not match ${url}`)); - } - }); - await request(app.getHttpServer()) - .post(`/v1/chains/${chainId}/transactions/${safeAddress}/propose`) - .send(proposeTransactionDto) - .expect(422) - .expect({ - message: 'Delegate call is disabled', - statusCode: 422, + networkService.post.mockImplementation(({ url }) => { + const proposeTransactionUrl = `${chain.transactionService}/api/v1/safes/${safeAddress}/multisig-transactions/`; + switch (url) { + case proposeTransactionUrl: + return Promise.resolve({ data: rawify({}), status: 200 }); + default: + return Promise.reject(new Error(`Could not match ${url}`)); + } }); + await request(app.getHttpServer()) + .post(`/v1/chains/${chainId}/transactions/${safeAddress}/propose`) + .send(proposeTransactionDto) + .expect(422) + .expect({ + message: 'Delegate call is disabled', + statusCode: 422, + }); + }); }); }); diff --git a/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts b/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts index 1a8b8598d2..384d3a198c 100644 --- a/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts +++ b/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts @@ -483,7 +483,7 @@ describe('TransactionVerifierHelper', () => { signatureType, }); const v = transaction.confirmations![0].signature?.slice(-2); - transaction.confirmations![0].signature = `0x--------------------------------------------------------------------------------------------------------------------------------${v}`; + transaction.confirmations![0].signature = `0x${'-'.repeat(128)}${v}`; expect(() => { return target.verifyApiTransaction({ chainId, safe, transaction }); @@ -1126,10 +1126,7 @@ describe('TransactionVerifierHelper', () => { .with('refundReceiver', transaction.refundReceiver) .with('safeTxHash', transaction.safeTxHash) .with('sender', transaction.confirmations![0].owner) - .with( - 'signature', - `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, - ) + .with('signature', `0x${'-'.repeat(128)}${v}`) .build(); await expect( @@ -1815,7 +1812,7 @@ describe('TransactionVerifierHelper', () => { chainId, safe, transaction, - signature: `0x--------------------------------------------------------------------------------------------------------------------------------${v}`, + signature: `0x${'-'.repeat(128)}${v}`, }); }).toThrow(new Error('Could not recover address'));