60 / 30 / 10 routing
Every claimed epoch is divided three ways by a rule that cannot be changed after deployment.
Source
Pons creator fees
Claimed in ETH from the fee escrow
Router
Plouto Revenue Router
Immutable 60 / 30 / 10 · no admin override
- 60%
Buyback & retirement
Market purchases, permanently removed from circulation.
- 30%
Staker rewards
ETH streamed to locked Gravity positions.
- 10%
Plouto Reserve
Security, infrastructure, automation and future protocol-owned liquidity.
The constants
uint256 public constant BUYBACK_BPS = 6000; // 60%uint256 public constant STAKER_BPS = 3000; // 30%uint256 public constant RESERVE_BPS = 1000; // 10%uint256 public constant BPS = 10_000;constant in Solidity means the value is inlined at compile time. There is no storage slot, so there is nothing for an admin function to write to — even a malicious upgrade would require deploying a different contract entirely, and Pons would then have to be persuaded to redirect fees to it through its own timelocked recipient change.
The dust rule
Integer division loses remainders. Rather than let them accumulate as unallocated dust, the reserve share absorbs them:
toBuybacks = (amount * BUYBACK_BPS) / BPS;toStakers = (amount * STAKER_BPS) / BPS;toReserve = amount - toBuybacks - toStakers;The two larger shares round down; the reserve takes whatever is left. This guarantees exactness for any input:
toBuybacks + toStakers + toReserve == amountAn invariant test asserts this across randomised amounts, and a fuzz test asserts it specifically for values from 1 wei to 1,000 ETH.
Worked example
For an awkward amount of 1,000,000,000,000,000,007 wei (1 ETH + 7 wei):
| Share | Calculation | Result |
|---|---|---|
| Buybacks | ⌊amount × 6000 / 10000⌋ | 600,000,000,000,000,004 |
| Stakers | ⌊amount × 3000 / 10000⌋ | 300,000,000,000,000,002 |
| Reserve | amount − above two | 100,000,000,000,000,001 |
| Total | 1,000,000,000,000,000,007 |
The reserve receives one wei more than a naive 10% would give. That is the dust rule doing its job.
Why these particular numbers
- 60% to buybacks is the largest share because retirement is the mechanism that benefits every holder, not only those with a position open.
- 30% to stakers compensates the specific cost stakers bear: locked, illiquid capital for a fixed term.
- 10% to reserve is sized to fund upkeep without meaningfully competing with the other two.
They are not derived from a model. They are a stated policy, fixed before launch so that nobody has to trust a future decision.
Routing is gated, claiming is not
routeUnallocatedRevenue() reverts with NotInitialized() until the registry has a registered token, because the buyback destination does not exist before PLOUTO does.
claimPonsFees() is not gated. Fees can be claimed and held from the moment the router exists, so revenue is never stranded in the escrow waiting for a launch.
Pausing
PAUSER_ROLE can pause routing. It cannot pause claiming, and it cannot redirect anything. A pause means "hold the split", not "hold the money somewhere else".
Verifying a split
Every route emits:
event RevenueRouted( uint256 amount, uint256 toBuybacks, uint256 toStakers, uint256 toReserve, uint256 totalRevenueRouted, uint256 routeIndex);and appends a RouteRecord readable via getRoute(index). The Core page renders the full history, and you can reconstruct it independently from logs — see indexing revenue.