split.gno
2.00 Kb · 53 lines
1package memba_market_core_v2
2
3// SplitProceedsBPS computes the three-way split of a sale price into platform fee,
4// creator royalty, and seller proceeds, with the platform fee in basis points
5// supplied by the caller (read per-lane from memba_market_config) instead of the
6// frozen FeeBPS constant. This is the spine that lets every engine charge a
7// DAO-tunable, per-lane fee while sharing one audited money-math implementation.
8//
9// `feeBPS` is validated to [0, MaxFeeBPS] — the 5% ceiling the DAO can never exceed
10// — so a misconfigured or compromised config realm cannot make an engine overcharge.
11// `royaltyAmount` is the actual amount from RoyaltyInfo (NOT bps); floored at 0 and
12// clamped to MaxRoyaltyBPS of price. A zero fee is permitted (feeBPS may legitimately
13// be 0, or round to 0 on a small price); engines that must guarantee non-zero protocol
14// revenue (e.g. fungible OTC partial fills) enforce a per-fill minimum notional at
15// their call site — that is an engine concern, not pure money-math.
16func SplitProceedsBPS(price, feeBPS, royaltyAmount int64) (fee, royalty, seller int64) {
17 if price < MinPrice {
18 panic("price below minimum")
19 }
20 if price > MaxPrice {
21 panic("price above maximum")
22 }
23 if feeBPS < 0 {
24 panic("feeBPS negative")
25 }
26 if feeBPS > MaxFeeBPS {
27 panic("feeBPS above maximum")
28 }
29 fee = price * feeBPS / 10000
30 royalty = royaltyAmount
31 if royalty < 0 {
32 royalty = 0
33 }
34 maxRoy := price * MaxRoyaltyBPS / 10000
35 if royalty > maxRoy {
36 royalty = maxRoy
37 }
38 if fee+royalty >= price {
39 panic("fee plus royalty exceeds price")
40 }
41 seller = price - fee - royalty
42 if seller <= 0 {
43 panic("seller amount not positive")
44 }
45 return
46}
47
48// SplitProceeds is the frozen FeeBPS (2.0%) conformance path, kept behaviorally
49// identical to memba_nft_market_v3's splitProceeds. It delegates to SplitProceedsBPS
50// with the default FeeBPS so existing engines are unchanged.
51func SplitProceeds(price, royaltyAmount int64) (fee, royalty, seller int64) {
52 return SplitProceedsBPS(price, FeeBPS, royaltyAmount)
53}