The split math
Gross-referenced WAD shares, floor rounding, where the dust lands, and exact conservation.
Five numbers in, five legs out, and an identity that holds to the wei: every harvest is a pure function of the gross fees and the four WAD shares — floors on the shares, exact subtraction on the remainders, dust always landing with a named recipient.
The five legs, derived
Every share is WAD-scaled (1e18 = 100%), and every share leg is the floor of its WAD product against the gross of its own side. The two recipient legs are then computed by subtraction, never by a third multiplication:
If the remainder were computed as ⌊gross · restShareWad / 1e18⌋, three independent floors could under-count the gross by up to 2 wei per side, every harvest — value slowly orphaned on the hook. Subtraction makes conservation structural: the legs sum to the gross byte-for-byte because the last leg is defined as whatever makes them.
The conservation identity
The floors always round against the automated legs and toward the named recipient — division dust is at most 1 wei per share leg per harvest, it lands in a real address's pocket, and it is never minted and never lost. The stateful fuzz campaign interleaves harvests with pumps and shields in the same frames — exactly where a bookkeeping slip between the ledgers would hide — and the identity holds throughout.
The set-time validation, per side
| rule | why it exists |
|---|---|
compound + buyback ≤ 1e18 (secondary) · compound + burn ≤ 1e18 (main) | shares over 100% would make the subtraction underflow — rejected at write time, not discovered mid-harvest |
| shares sum below 100% ⟹ that side's recipient must be live | below-100% means a remainder can exist, and value never goes nowhere |
burnShare must be 0 when main is native | the network token has no supply to destroy — the config is rejected rather than the burn silently failing later |
Because everything is checked when setProgramConfig writes the rules, harvest-time is calculation only — there is no configuration state a harvest can discover to be invalid, which is one of the reasons a swap can carry one safely.
Edits and their timing
A config edit is forward-only: fees already pending under the old rules are still split by whatever config is live at the moment the harvest actually runs — the split is a function of (gross, config-now), with no memory. If precise attribution across a rule change matters to you, harvest manually first, then edit.
FAQ
What does "gross-referenced" mean for the shares?+
All WAD shares of a side apply to that side's GROSS harvested amount, not to a running remainder — so 30% + 30% means exactly 30% and 30%, and the recipient gets exactly 40%.
Where does rounding dust go?+
Shares floor; the recipient's remainder is computed by subtraction, so the legs sum to the gross byte-for-byte. Dust systematically favors the remainder leg.
Is conservation actually proven?+
Yes — invariant PI5 asserts the delivery identity across randomized campaigns: everything acquired equals everything compounded + burned + delivered + booked, wei-exact.
How is 100% per side validated?+
Each side's two shares may sum to at most 1e18 (100%). Above that, setProgramConfig and launch revert with BadConfig at write-time — never at trade-time.
Do both sides settle in the same harvest?+
Yes — one harvest collects both fee assets and runs both sides' splits in the same transaction, so the two ledgers never drift apart.