From 6b07d50195ce8c04af1c734f2102c9c65a5897c0 Mon Sep 17 00:00:00 2001 From: benthecarman Date: Wed, 7 Oct 2026 02:02:15 -0500 Subject: [PATCH] Reject LSPS1 orders with the wrong refund address When we create an LSPS1 order, we now check the refund address in the LSP's response. If the LSP returns an on-chain payment option whose refund_onchain_address doesn't match the one we sent, we reject the order. A response without the field is still accepted, since the field is optional. This guards against buggy or misconfigured LSPs. It isn't theft protection: a malicious LSP can just decline to refund. Reported by Project Loupe. Co-Authored-By: Claude Opus 5.5 --- src/liquidity/client/lsps1.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/liquidity/client/lsps1.rs b/src/liquidity/client/lsps1.rs index 30c1b0943c..d6549ccbf8 100644 --- a/src/liquidity/client/lsps1.rs +++ b/src/liquidity/client/lsps1.rs @@ -157,7 +157,7 @@ where request_id = client_handler.create_order( &lsps1_node.node_id, order_params.clone(), - Some(refund_address), + Some(refund_address.clone()), ); PendingRequestGuard::insert( &self.pending_create_order_requests, @@ -189,6 +189,20 @@ where return Err(Error::LiquidityRequestFailed); } + if let Some(received_refund_address) = response + .payment_options + .onchain + .as_ref() + .and_then(|o| o.refund_onchain_address.as_ref()) + .filter(|addr| addr.script_pubkey() != refund_address.script_pubkey()) + { + log_error!( + self.logger, + "Aborting LSPS1 request as LSP-provided refund address doesn't match our order. Expected: {}, Received: {}", refund_address, received_refund_address + ); + return Err(Error::LiquidityRequestFailed); + } + Ok(response) }