Validate all common fields in LSPS1 `is_valid` order check
What changed, and why it matters
This commit fixes validation checks in a Lightning service feature (LSPS1) that lets users place orders for liquidity. Previously, the code did not verify that an order's requested channel size and confirmation settings stayed within the service's advertised limits. The patch adds those missing checks and also protects against a rare integer overflow when adding two balance amounts together. A malicious or malformed order could have slipped through and caused the service to accept terms it never intended to offer.
Review whether any other bLIP-51 common-field validations are still missing, and consider adding unit tests covering boundary values, overflow cases, and each newly enforced minimum.
Security signals we found
Missing input validation against protocol limits (bLIP-51)
Integer overflow protection via `checked_add`
Cross-field consistency checks added to order acceptance logic
Evidence from the diff
The patch updates is_valid() in lightning-liquidity/src/lsps1/service.rs to cross-validate LSPS1OrderParams against LSPS1Options per bLIP-51. It adds: (1) checked_add of lsp_balance_sat and client_balance_sat to prevent u64 overflow when computing total channel balance; (2) a range check that the total channel balance lies within [min_channel_balance_sat, max_channel_balance_sat]; (3) required_channel_confirmations >= min_required_channel_confirmations; and (4) funding_confirms_within_blocks >= min_funding_confirms_within_blocks. These were common-field validations that existed in the spec but were missing from the implementation.
Changed components
lightning-liquidity/src/lsps1/service.rsLSPS1 order validation (`is_valid`)LSPS1OrderParams / LSPS1Options handlingInspect captured patch +11 / −1
diff --git a/lightning-liquidity/src/lsps1/service.rs b/lightning-liquidity/src/lsps1/service.rs
index e776ae2..0ac2420 100644
--- a/lightning-liquidity/src/lsps1/service.rs
+++ b/lightning-liquidity/src/lsps1/service.rs
@@ -929,6 +929,11 @@ fn check_range(min: u64, max: u64, value: u64) -> bool {
}
fn is_valid(order: &LSPS1OrderParams, options: &LSPS1Options) -> bool {
+ let channel_balance_sat = match order.lsp_balance_sat.checked_add(order.client_balance_sat) {
+ Some(sum) => sum,
+ None => return false,
+ };
+
check_range(
options.min_initial_client_balance_sat,
options.max_initial_client_balance_sat,
@@ -941,5 +946,10 @@ fn is_valid(order: &LSPS1OrderParams, options: &LSPS1Options) -> bool {
1,
options.max_channel_expiry_blocks.into(),
order.channel_expiry_blocks.into(),
- )
+ ) && check_range(
+ options.min_channel_balance_sat,
+ options.max_channel_balance_sat,
+ channel_balance_sat,
+ ) && order.required_channel_confirmations >= options.min_required_channel_confirmations
+ && order.funding_confirms_within_blocks >= options.min_funding_confirms_within_blocks
}
Why this scored 47/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.