1,000,000 base units equals 1.000000 SDUSD.
Calculate the sale reward
20,000,000, a rate of 1,000 bps, and a per-sale cap of 1,500,000, the percentage calculation produces 2,000,000, so the cap limits the reward to 1,500,000 base units, or 1.5 SDUSD.
Full four-person path
Use nearest-first weights[5000, 2500, 1500, 1000].
The more distant allocations are rounded down. The nearest eligible contributor receives the remaining base units so that allocations sum exactly to the reserved reward. Tiny rewards can produce zero amounts at some levels; percentage displays must not imply fractional base units are paid.
Two people with renormalization
Only the first two weights,5000 and 2500, are eligible. Normalize them to 10,000 basis points. The implementation gives the rounding remainder to the nearest weight, yielding [6667, 3333].
For a reward of 1000, the allocations are [667, 333]. For 1,000,000, they are [666700, 333300]. The implementation first normalizes weights at basis-point precision, so do not replace it with a floating-point two-thirds calculation and expect identical base units.
Two people with return-unused
The original eligible weights total7500 bps. For a reward of 1000, reserve 750, allocate [500, 250], and leave 250 unallocated in available rewards.
For a reward of 1001, reserve floor(1001 × 7500 / 10000) = 750; allocate [500, 250]; the remaining 251 is unallocated. The split still conserves the reserved amount exactly.
One person or a direct purchase
With renormalization, one eligible contributor receives the whole reward. With return-unused, that contributor receives the amount permitted by their original weight, subject to integer rounding. A direct purchase uses node ID zero and has no eligible recipients. Its reserved distributor reward is zero; this is different from a one-person path.Invalid paths are rejected
The selected path must belong to the campaign and satisfy the contract’s eligibility checks. An ineligible buyer or merchant in paid ancestry is not silently removed to produce a more convenient split. Refresh a rejected checkout and explain the actual issue rather than presenting a shortened fabricated path.Use the shared implementation
Repository contributors can usecomputeReward, normalizeWeights, allocatePolicyReward, and simulatePolicy from @spoke/protocol. The contract’s PolicyMath is the settlement implementation. The shared test vectors and contract tests are the comparison point; keep all calculations in integers.