From ecb27661393c9f80383f984cae1824807a209890 Mon Sep 17 00:00:00 2001 From: ChainBid Developer Date: Sat, 29 Aug 2026 17:03:48 +0100 Subject: [PATCH] refactor: extract basis-points range validation into assert_valid_bps (#704) --- contracts/split/src/lib.rs | 2 -- contracts/split/src/validation.rs | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/contracts/split/src/lib.rs b/contracts/split/src/lib.rs index 874d3bf..f634c0b 100644 --- a/contracts/split/src/lib.rs +++ b/contracts/split/src/lib.rs @@ -71,8 +71,6 @@ mod storage_keys; mod migrations; -mod validation; - use error::ContractError; use validation::assert_valid_bps; use soroban_sdk::crypto::bls12_381::{Fr, G1Affine}; diff --git a/contracts/split/src/validation.rs b/contracts/split/src/validation.rs index f90a3ea..4f3d599 100644 --- a/contracts/split/src/validation.rs +++ b/contracts/split/src/validation.rs @@ -97,6 +97,25 @@ pub fn assert_bps_total(total: u32) -> Result<(), ContractError> { Ok(()) } +/// Issue #704: Validate that a single basis-point value is within the legal +/// range `[0, BASIS_POINTS_TOTAL]` (i.e. `0..=10_000`). +/// +/// Per-invoice options such as `penalty_bps`, `tax_bps`, and +/// `insurance_premium_bps` are stored as `u32` basis points and must never +/// exceed 100%. Callers invoke this guard before writing storage so an +/// out-of-range value is rejected atomically. The three existing call sites +/// use `.expect("… must be ≤ 10000")`, so this returns a `Result` and lets the +/// caller choose how to surface the failure. +/// +/// # Errors +/// Returns `Err(ContractError::InvalidRatio)` when `bps > BASIS_POINTS_TOTAL`. +pub fn assert_valid_bps(bps: u32) -> Result<(), ContractError> { + if bps > BASIS_POINTS_TOTAL { + return Err(ContractError::InvalidRatio); + } + Ok(()) +} + #[cfg(test)] mod tests { use super::*;