From 4e5772662cb4c7bf1663fe6853e6bcab3f58409c Mon Sep 17 00:00:00 2001 From: gabrielkerekes Date: Wed, 16 Jun 2021 10:42:26 +0200 Subject: [PATCH] fix(cardano): don't allow duplicate withdrawals --- .../fixtures/cardano/sign_tx.failed.json | 38 +++++++++++++++++++ core/src/apps/cardano/sign_tx.py | 7 ++++ 2 files changed, 45 insertions(+) diff --git a/common/tests/fixtures/cardano/sign_tx.failed.json b/common/tests/fixtures/cardano/sign_tx.failed.json index 469d06e1a5..a3d09442cf 100644 --- a/common/tests/fixtures/cardano/sign_tx.failed.json +++ b/common/tests/fixtures/cardano/sign_tx.failed.json @@ -555,6 +555,44 @@ "error_message": "Invalid withdrawal" } }, + + { + "description": "Duplicate withdrawal", + "parameters": { + "protocol_magic": 764824073, + "network_id": 1, + "fee": 42, + "ttl": 10, + "certificates": [], + "withdrawals": [ + { + "path": "m/1852'/1815'/0'/2/0", + "amount": "1000" + }, + { + "path": "m/1852'/1815'/0'/2/0", + "amount": "2000" + } + ], + "auxiliary_data": null, + "inputs": [ + { + "path": "m/1852'/1815'/0'/0/0", + "prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7", + "prev_index": 0 + } + ], + "outputs": [ + { + "address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2", + "amount": "3003112" + } + ] + }, + "result": { + "error_message": "Duplicate withdrawals" + } + }, { "description": "Auxiliary data blob is incomplete", "parameters": { diff --git a/core/src/apps/cardano/sign_tx.py b/core/src/apps/cardano/sign_tx.py index 479ae64fad..7fb16bc7ad 100644 --- a/core/src/apps/cardano/sign_tx.py +++ b/core/src/apps/cardano/sign_tx.py @@ -309,6 +309,7 @@ def _validate_certificates( def _validate_withdrawals(withdrawals: list[CardanoTxWithdrawalType]) -> None: + seen_withdrawals = set() for withdrawal in withdrawals: if not SCHEMA_STAKING_ANY_ACCOUNT.match(withdrawal.path): raise INVALID_WITHDRAWAL @@ -316,6 +317,12 @@ def _validate_withdrawals(withdrawals: list[CardanoTxWithdrawalType]) -> None: if not 0 <= withdrawal.amount < LOVELACE_MAX_SUPPLY: raise INVALID_WITHDRAWAL + path_tuple = tuple(withdrawal.path) + if path_tuple in seen_withdrawals: + raise wire.ProcessError("Duplicate withdrawals") + else: + seen_withdrawals.add(path_tuple) + def _cborize_signed_tx( keychain: seed.Keychain, msg: CardanoSignTx