From 5cc1683a1bbb9d2a4fb88c150bee9c0c8bc820f6 Mon Sep 17 00:00:00 2001 From: jwinterm Date: Sun, 7 Jun 2026 16:33:59 -0400 Subject: [PATCH] Contracts: validate num_participants before fee math num_participants is divided into the kernel cost, so 0 caused a divide-by-zero (inf -> garbage fee). Validate it in context::create, the common setup path for every party: the initiator's value comes from args and the signer's from the slate, so this also rejects a tampered slate. Only 1 (self-spend) and 2 (standard) are supported today; lift the upper bound when multi-party contracts are implemented. Addresses PR #754 review (wallet_args.rs:1039). --- libwallet/src/contract/context.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libwallet/src/contract/context.rs b/libwallet/src/contract/context.rs index 15a5489..1f967ff 100644 --- a/libwallet/src/contract/context.rs +++ b/libwallet/src/contract/context.rs @@ -81,6 +81,17 @@ where K: Keychain + 'a, { debug!("Creating a new contract context"); + // Validate num_participants before any fee math (kernel cost is divided by it, so 0 + // would be a divide-by-zero). This is the common setup path for every party (the + // signer's value comes from the slate), so it also guards against a tampered slate. + // Only 1 (self-spend) and 2 (standard) are implemented today; lift this when + // multi-party contracts are supported. + if setup_args.num_participants < 1 || setup_args.num_participants > 2 { + return Err(Error::GenericError(format!( + "Unsupported num_participants: {} (expected 1 or 2)", + setup_args.num_participants + ))); + } // sender should always refresh outputs updater::refresh_outputs(w, keychain_mask, parent_key_id, false)?;