wallet2: check for overflow when calculating fee from weight
What changed, and why it matters
This commit adds an overflow check when the Monero wallet calculates transaction fees from a transaction's weight. Before the patch, multiplying a large 'weight' value by a non-zero 'base_fee' could silently wrap around to a tiny number, potentially causing the wallet to propose an incorrect (possibly far too low) fee. The fix now throws an internal wallet error instead of silently producing a wrong result.
Review all callers of calculate_fee_from_weight() to confirm weight and base_fee are bounded or attacker-influenced only through controlled paths; consider adding similar overflow checks to calculate_fee() and other fee helpers; include a regression test with boundary values.
Security signals we found
Integer overflow in fee calculation
Silent arithmetic wraparound prevented
Wallet-internal error thrown on overflow
Transaction fee correctness / economic safety
Evidence from the diff
In src/wallet/wallet2.cpp, calculate_fee_from_weight() now validates that weight <= UINT64_MAX / base_fee before performing the 64-bit unsigned multiplication weight * base_fee. Without this guard, an attacker-controlled or pathological weight/base_fee pair could overflow uint64_t, producing a truncated fee value. The subsequent fee_quantization_mask rounding would then operate on that corrupted value. The patch is a defensive guard but does not show the complete caller context or demonstrate a reachable trigger.
Changed components
src/wallet/wallet2.cppcalculate_fee_from_weight()Monero wallet fee computationInspect captured patch +2 / −0
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 49d65e4..46d7086 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -306,6 +306,8 @@ uint64_t calculate_fee(uint64_t fee_per_kb, size_t bytes)
uint64_t calculate_fee_from_weight(uint64_t base_fee, uint64_t weight, uint64_t fee_quantization_mask)
{
+ THROW_WALLET_EXCEPTION_IF(base_fee != 0 && weight > std::numeric_limits<uint64_t>::max() / base_fee,
+ tools::error::wallet_internal_error, "Fee calculation overflow");
uint64_t fee = weight * base_fee;
fee = (fee + fee_quantization_mask - 1) / fee_quantization_mask * fee_quantization_mask;
return fee;
Why this scored 59/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.