Remainder Handling
Protocol

Remainder Handling

Deterministic zero-loss policy awarding remainder stroops to index 0.

Because integer division drops fractional remainders, protocols must have a strict, deterministic rule for fractional tokens (stroops) so that zero funds disappear.

The Rounding Problem

Consider an odd payment of 100 stroops split across 3 members with shares of 3,333 BPS, 3,333 BPS, and 3,334 BPS (total = 10,000 BPS):

  • Member 0: 100 * 3,333 / 10,000 = 33 stroops
  • Member 1: 100 * 3,333 / 10,000 = 33 stroops
  • Member 2: 100 * 3,334 / 10,000 = 33 stroops
  • Sum of raw allocations = 99 stroops (1 stroop difference!)

Deterministic Remainder Policy

SplitPay solves this deterministically: the difference between total payment and allocated sum is added to member index 0 (the primary pool member):

rustcontracts/splitpay/src/contract.rs
let remainder = total_amount.checked_sub(allocated_sum)?;
if remainder > 0 && !allocations.is_empty() {
let first_alloc = allocations.get(0).unwrap();
let new_first = first_alloc.checked_add(remainder)?;
allocations.set(0, new_first);
}

Concrete Math Walkthrough

MemberShareRaw CalculationRemainder PolicyFinal Allocation
Member 03,333 BPS33+1 (Remainder)34 stroops
Member 13,333 BPS33+033 stroops
Member 23,334 BPS33+033 stroops
Total10,000 BPS99+1100 stroops (Exact)