Reward Distributor
5-channel MEV revenue splitting with bootstrap/steady-state transitions, circuit breaker, and fee curve guardrails.
Reward Distributor
The Reward Distributor drains accumulated tips from forti-tips PDA vaults and splits the revenue across 5 destination channels per the tokenomics v3.1 specification. It supports bootstrap and steady-state split configurations with a 30-day linear transition between them.
1. What It Does
Every bundle that lands on-chain through the AXIO block engine generates tips. Those tips accumulate in 8 rotating forti-tips PDA vaults. The Reward Distributor is a permissionless crank that:
- Reads the current balance of a forti-tips vault (above rent-exempt minimum)
- Computes the effective split percentages for the current slot
- Distributes lamports to 5 destination accounts in a single atomic transaction
- Updates cumulative accounting on-chain
Anyone can crank the Distribute instruction -- no special authority is needed. This ensures tips flow even if the AXIO team is offline.
2. The 5 Channels
Revenue is split across 5 destination channels. All percentages are configured in basis points (10,000 = 100%) and must sum to exactly 10,000.
| Channel | Destination | Purpose |
|---|---|---|
| Reserve Injection | aXNT stake pool reserve | Raises the aXNT exchange rate for all holders |
| veAXIO Stakers | veAXIO reward pool | Distributed to veAXIO holders proportional to effective balance |
| Buyback | AXIO buyback module | Market purchases of AXIO to support token price |
| Treasury | Protocol treasury | Development, operations, grants |
| Validator Incentives | Validator incentive pool | Performance-weighted bonuses for validators |
Bootstrap Split vs Steady-State Split
The program stores two complete split configurations. The admin sets both at initialization:
pub struct SplitConfig {
pub reserve_injection_bps: u16, // aXNT reserve
pub ve_stakers_bps: u16, // veAXIO holders
pub buyback_bps: u16, // AXIO buyback
pub treasury_bps: u16, // Treasury
pub validator_incentives_bps: u16, // Validator bonuses
}Both configurations must independently sum to 10,000 bps. The active split depends on the program phase:
| Phase | Active Split | Typical Focus |
|---|---|---|
| Bootstrap | bootstrap_split | Higher validator incentives and reserve injection to attract early participants |
| Transition | Blended (linear) | Gradual shift over ~30 days |
| Steady-State | steady_state_split | Balanced distribution for long-term sustainability |
3. 30-Day Transition Blending
When the admin calls BeginTransition, the program records the current slot and a duration (default ~6,480,000 slots, approximately 30 days). During the transition window, every Distribute call computes a blended split:
weight_steady = elapsed_slots * 10,000 / transition_duration_slots
weight_bootstrap = 10,000 - weight_steady
blended_channel = (bootstrap_value * weight_bootstrap + steady_value * weight_steady) / 10,000This produces a smooth linear interpolation from bootstrap percentages to steady-state percentages. Once elapsed >= duration, the transition completes automatically and all subsequent distributions use the pure steady-state split.
Transition Example
Assume bootstrap allocates 30% to validator incentives and steady-state allocates 15%:
| Day | Weight (Steady) | Validator Incentive % |
|---|---|---|
| 0 | 0% | 30.0% |
| 7 | 23% | 26.5% |
| 15 | 50% | 22.5% |
| 22 | 73% | 19.1% |
| 30 | 100% | 15.0% |
4. Circuit Breaker
The circuit breaker is a safety mechanism that halves all distributions when the veAXIO lock rate drops below a threshold. This prevents excessive emissions when governance participation is low.
| Parameter | Default | Description |
|---|---|---|
min_lock_rate_bps | 3,000 (30%) | Minimum veAXIO lock rate before breaker triggers |
circuit_breaker_tripped | false | Current breaker state |
When tripped:
effective_amount = available_lamports / 2The remaining 50% stays in the source vault for the next distribution cycle. The admin toggles the breaker via SetCircuitBreaker. The undistributed half is not lost -- it accumulates and will be distributed once the breaker resets.
5. Fee Curve Guardrails
Two immutable parameters enforce hard limits on the validator/protocol revenue split. These cannot be changed after initialization:
| Guardrail | Value | Meaning |
|---|---|---|
validator_floor_bps | 6,000 (60%) | Validators always keep at least 60% of total MEV |
protocol_ceiling_bps | 4,000 (40%) | Protocol never takes more than 40% of total MEV |
These are on-chain constants that no admin action can override. They ensure validators are never squeezed below a fair share regardless of governance decisions about the 5-channel split.
6. PDA Derivation
| Account | Seeds | Description |
|---|---|---|
| DistributorConfig | ["distributor"] | Global config, one per deployment |
const [configPda] = PublicKey.findProgramAddressSync(
[Buffer.from("distributor")],
REWARD_DISTRIBUTOR_PROGRAM_ID
);7. Instructions
7.1 Initialize
Create the distributor config with both split configurations. Admin only.
Parameters:
| Parameter | Type | Description |
|---|---|---|
bootstrap_split | SplitConfig | Bootstrap phase percentages (must sum to 10,000 bps) |
steady_state_split | SplitConfig | Steady-state percentages (must sum to 10,000 bps) |
bootstrap_active | bool | Start in bootstrap mode |
Accounts:
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | Admin | Yes | No | Program admin |
| 1 | DistributorConfig PDA | No | Yes | Config account (created) |
| 2 | Reserve Vault | No | No | aXNT reserve destination |
| 3 | veAXIO Reward Pool | No | No | veAXIO staker destination |
| 4 | Buyback Account | No | No | Buyback destination |
| 5 | Treasury Account | No | No | Treasury destination |
| 6 | Validator Incentive Account | No | No | Validator incentive destination |
| 7 | System Program | No | No | System program |
Default values set at initialization:
transition_duration_slots: 6,480,000 (~30 days)min_lock_rate_bps: 3,000 (30%)validator_floor_bps: 6,000 (60%)protocol_ceiling_bps: 4,000 (40%)
7.2 Distribute
Drain a forti-tips vault and split the lamports across the 5 channels. Permissionless -- anyone can crank this.
Parameters: None.
Accounts:
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | Cranker | Yes | No | Pays transaction fee |
| 1 | DistributorConfig PDA | No | Yes | Config (updated with accounting) |
| 2 | Source (forti-tips PDA) | No | Yes | One of 8 rotating tip vaults |
| 3 | Reserve Vault | No | Yes | aXNT reserve destination |
| 4 | veAXIO Reward Pool | No | Yes | veAXIO staker destination |
| 5 | Buyback Account | No | Yes | Buyback destination |
| 6 | Treasury Account | No | Yes | Treasury destination |
| 7 | Validator Incentive Account | No | Yes | Validator incentive destination |
| 8 | System Program | No | No | System program |
| 9 | Clock Sysvar | No | No | For current slot |
The instruction drains the source vault down to its rent-exempt minimum. If the circuit breaker is tripped, only 50% of the available balance is distributed. The validator incentive channel receives the remainder after rounding to avoid dust accumulation.
All 5 destination accounts are validated against the stored config. Passing incorrect accounts causes the transaction to fail.
7.3 BeginTransition
Start the 30-day linear transition from bootstrap to steady-state splits. Admin only. Fails if bootstrap is not active or a transition is already in progress.
Parameters:
| Parameter | Type | Description |
|---|---|---|
duration_slots | u64 | Transition duration in slots (~6,480,000 for 30 days) |
Accounts:
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | Admin | Yes | No | Must match config admin |
| 1 | DistributorConfig PDA | No | Yes | Config (updated with transition state) |
| 2 | Clock Sysvar | No | No | For transition start slot |
7.4 SetCircuitBreaker
Trip or reset the circuit breaker. Admin only.
Parameters:
| Parameter | Type | Description |
|---|---|---|
tripped | bool | true to halve distributions, false to resume normal |
Accounts:
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | Admin | Yes | No | Must match config admin |
| 1 | DistributorConfig PDA | No | Yes | Config (updated) |
7.5 UpdateDestinations
Update one or more destination accounts. Admin only. Pass None for any account you do not want to change.
Parameters:
| Parameter | Type | Description |
|---|---|---|
reserve_vault | Option<Pubkey> | New reserve vault address |
ve_reward_pool | Option<Pubkey> | New veAXIO reward pool address |
buyback_account | Option<Pubkey> | New buyback address |
treasury_account | Option<Pubkey> | New treasury address |
validator_incentive_account | Option<Pubkey> | New validator incentive address |
Accounts:
| # | Account | Signer | Writable | Description |
|---|---|---|---|---|
| 0 | Admin | Yes | No | Must match config admin |
| 1 | DistributorConfig PDA | No | Yes | Config (updated) |
8. Effective Split Calculation
The effective_split function determines which percentages apply at any given slot:
if bootstrap_active AND no transition:
return bootstrap_split
if NOT bootstrap_active AND no transition:
return steady_state_split
if in transition:
elapsed = current_slot - transition_start_slot
if elapsed >= transition_duration:
return steady_state_split
else:
blend each channel linearlyOnce the transition duration elapses, the next Distribute call automatically clears the bootstrap_active flag and the transition_start_slot, locking in the steady-state split permanently.
9. Accounting Fields
The config tracks cumulative distribution totals for transparency and auditability:
| Field | Type | Description |
|---|---|---|
total_distributed | u64 | Sum of all lamports distributed |
total_to_reserve | u64 | Cumulative to aXNT reserve |
total_to_ve_stakers | u64 | Cumulative to veAXIO pool |
total_to_buyback | u64 | Cumulative to buyback |
total_to_treasury | u64 | Cumulative to treasury |
total_to_validator_incentives | u64 | Cumulative to validator pool |
last_distribution_slot | u64 | Slot of most recent distribution |
All values can be read directly from the on-chain DistributorConfig account for real-time monitoring.