From 18b634a5913a5c2613bac2de3d20c0dceb94926e Mon Sep 17 00:00:00 2001 From: selsta Date: Tue, 28 Apr 2026 01:25:31 +0200 Subject: [PATCH] wallet2: reject duplicate outputs in reserve proofs --- src/wallet/wallet2.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index dc5847b74..c7250f9c0 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -12662,6 +12662,15 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr catch(...) {} THROW_WALLET_EXCEPTION_IF(!loaded, error::wallet_internal_error, "Failed to parse reserve proof signature data"); + + std::unordered_set seen_key_images; + std::set> seen_outputs; + for (const reserve_proof_entry &proof : proofs) + { + THROW_WALLET_EXCEPTION_IF(!seen_key_images.insert(proof.key_image).second, error::wallet_internal_error, "Duplicate key image in reserve proof"); + THROW_WALLET_EXCEPTION_IF(!seen_outputs.emplace(proof.txid, proof.index_in_tx).second, error::wallet_internal_error, "Duplicate output in reserve proof"); + } + THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(address.m_spend_public_key) == 0, error::wallet_internal_error, "The given address isn't found in the proof");