Protocol
Settlement Logic
Atomic execution flow, validation checks, and SEP-41 token interactions.
The settlement function transforms a pending payment into finalized token transfers and immutable distribution records.
Settlement Mechanics
Settlement can only be invoked once per payment. Re-executing causes Error::PaymentAlreadySettled.
Source Code Walkthrough
rustcontracts/splitpay/src/contract.rs
// 1. Authenticate payerlet mut payment = get_payment(&env, payment_id)?;payment.payer.require_auth();// 2. Validate active pool & 10,000 BPSlet members = get_pool_members(&env, payment.pool_id)?;let mut total_shares: u32 = 0;for m in members.iter() { total_shares = total_shares.checked_add(m.share_bps).ok_or(Error::ArithmeticOverflow)?;}if total_shares != MAX_BPS { return Err(Error::InvalidTotalShares);}// 3. Compute allocations & assign remainder to index 0let mut allocations = Vec::new(&env);let mut allocated_sum: i128 = 0;for m in members.iter() { let alloc = payment.amount.checked_mul(m.share_bps as i128)? .checked_div(BPS_DENOMINATOR)?; allocated_sum = allocated_sum.checked_add(alloc)?; allocations.push_back(alloc);}let remainder = payment.amount.checked_sub(allocated_sum)?;if remainder > 0 && !allocations.is_empty() { let first = allocations.get(0).unwrap().checked_add(remainder)?; allocations.set(0, first);}Two-Step Token Transfer
The contract uses a clean two-step transfer model:
- Step 1: Total payment amount is transferred from
payment.payertocontract_address. - Step 2: Contract loops through members and transfers their calculated
allocdirectly to their address.