diff --git a/packages/bitcore-node/src/providers/chain-state/evm/api/gnosis.ts b/packages/bitcore-node/src/providers/chain-state/evm/api/gnosis.ts index 9eaffb4ae6..e55b1e1926 100644 --- a/packages/bitcore-node/src/providers/chain-state/evm/api/gnosis.ts +++ b/packages/bitcore-node/src/providers/chain-state/evm/api/gnosis.ts @@ -160,6 +160,10 @@ export class GnosisApi { const transactionQuery = getCSP(chain, network).getWalletTransactionQuery(params); delete transactionQuery.wallets; delete transactionQuery['wallets.0']; + // effects.* addresses were stored raw (lowercase) until 1df63364f and were + // never backfilled (fixEvmTxToFromAddressesCase.js only rewrites top-level + // to/from), so match either casing + const eitherCase = (address: string) => ({ $in: [address, address.toLowerCase()] }); let query; if (tokenAddress) { query = { @@ -176,13 +180,13 @@ export class GnosisApi { }, { ...transactionQuery, - 'effects.contractAddress': tokenAddress, - 'effects.from': normalizedMultisigContractAddress + 'effects.contractAddress': eitherCase(tokenAddress), + 'effects.from': eitherCase(normalizedMultisigContractAddress) }, { ...transactionQuery, - 'effects.contractAddress': tokenAddress, - 'effects.to': normalizedMultisigContractAddress + 'effects.contractAddress': eitherCase(tokenAddress), + 'effects.to': eitherCase(normalizedMultisigContractAddress) } ] }; @@ -191,7 +195,7 @@ export class GnosisApi { $or: [ { ...transactionQuery, to: normalizedMultisigContractAddress }, { ...transactionQuery, 'internal.action.to': normalizedMultisigContractAddress.toLowerCase() }, - { ...transactionQuery, 'effects.to': normalizedMultisigContractAddress } + { ...transactionQuery, 'effects.to': eitherCase(normalizedMultisigContractAddress) } ] }; } diff --git a/packages/bitcore-node/src/providers/chain-state/evm/api/routes.ts b/packages/bitcore-node/src/providers/chain-state/evm/api/routes.ts index 8c4e3b1545..b3e4ffc600 100644 --- a/packages/bitcore-node/src/providers/chain-state/evm/api/routes.ts +++ b/packages/bitcore-node/src/providers/chain-state/evm/api/routes.ts @@ -238,6 +238,15 @@ export class EVMRouter { private streamGnosisWalletTransactions(router: Router) { router.get(`/api/${this.chain}/:network/ethmultisig/transactions/:multisigContractAddress`, async (req, res) => { const { network, multisigContractAddress } = req.params; + const { tokenAddress } = req.query; + // Validate and return a helpful 400 before toChecksumAddress throws downstream (which + // would surface as a 500). isAddress(x, false) accepts exactly what toChecksumAddress accepts. + if (!Web3.utils.isAddress(multisigContractAddress, false)) { + return res.status(400).send('Invalid multisig contract address'); + } + if (tokenAddress !== undefined && (typeof tokenAddress !== 'string' || !Web3.utils.isAddress(tokenAddress, false))) { + return res.status(400).send('Invalid token address'); + } try { return await Gnosis.streamGnosisWalletTransactions({ chain: this.chain, diff --git a/packages/bitcore-node/test/unit/models/transaction.test.ts b/packages/bitcore-node/test/unit/models/transaction.test.ts index e261e31297..189ca6c395 100644 --- a/packages/bitcore-node/test/unit/models/transaction.test.ts +++ b/packages/bitcore-node/test/unit/models/transaction.test.ts @@ -504,8 +504,8 @@ describe('Transaction Model', function() { expect(findQuery.$or).to.deep.include({ chain: 'ETH', network: 'mainnet', - 'effects.contractAddress': gnosisBusdToken, - 'effects.to': gnosisMultisigContractAddress + 'effects.contractAddress': { $in: [gnosisBusdToken, gnosisBusdToken.toLowerCase()] }, + 'effects.to': { $in: [gnosisMultisigContractAddress, gnosisMultisigContractAddress.toLowerCase()] } }); }); @@ -528,8 +528,8 @@ describe('Transaction Model', function() { expect(findQuery.$or).to.deep.include({ chain: 'ETH', network: 'mainnet', - 'effects.contractAddress': gnosisBusdToken, - 'effects.to': gnosisMultisigContractAddress + 'effects.contractAddress': { $in: [gnosisBusdToken, gnosisBusdToken.toLowerCase()] }, + 'effects.to': { $in: [gnosisMultisigContractAddress, gnosisMultisigContractAddress.toLowerCase()] } }); });