FortiBlox LogoFortiBlox Docs
AXIO Block Engine

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:

  1. Reads the current balance of a forti-tips vault (above rent-exempt minimum)
  2. Computes the effective split percentages for the current slot
  3. Distributes lamports to 5 destination accounts in a single atomic transaction
  4. 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.

ChannelDestinationPurpose
Reserve InjectionaXNT stake pool reserveRaises the aXNT exchange rate for all holders
veAXIO StakersveAXIO reward poolDistributed to veAXIO holders proportional to effective balance
BuybackAXIO buyback moduleMarket purchases of AXIO to support token price
TreasuryProtocol treasuryDevelopment, operations, grants
Validator IncentivesValidator incentive poolPerformance-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:

PhaseActive SplitTypical Focus
Bootstrapbootstrap_splitHigher validator incentives and reserve injection to attract early participants
TransitionBlended (linear)Gradual shift over ~30 days
Steady-Statesteady_state_splitBalanced 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,000

This 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%:

DayWeight (Steady)Validator Incentive %
00%30.0%
723%26.5%
1550%22.5%
2273%19.1%
30100%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.

ParameterDefaultDescription
min_lock_rate_bps3,000 (30%)Minimum veAXIO lock rate before breaker triggers
circuit_breaker_trippedfalseCurrent breaker state

When tripped:

effective_amount = available_lamports / 2

The 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:

GuardrailValueMeaning
validator_floor_bps6,000 (60%)Validators always keep at least 60% of total MEV
protocol_ceiling_bps4,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

AccountSeedsDescription
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:

ParameterTypeDescription
bootstrap_splitSplitConfigBootstrap phase percentages (must sum to 10,000 bps)
steady_state_splitSplitConfigSteady-state percentages (must sum to 10,000 bps)
bootstrap_activeboolStart in bootstrap mode

Accounts:

#AccountSignerWritableDescription
0AdminYesNoProgram admin
1DistributorConfig PDANoYesConfig account (created)
2Reserve VaultNoNoaXNT reserve destination
3veAXIO Reward PoolNoNoveAXIO staker destination
4Buyback AccountNoNoBuyback destination
5Treasury AccountNoNoTreasury destination
6Validator Incentive AccountNoNoValidator incentive destination
7System ProgramNoNoSystem 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:

#AccountSignerWritableDescription
0CrankerYesNoPays transaction fee
1DistributorConfig PDANoYesConfig (updated with accounting)
2Source (forti-tips PDA)NoYesOne of 8 rotating tip vaults
3Reserve VaultNoYesaXNT reserve destination
4veAXIO Reward PoolNoYesveAXIO staker destination
5Buyback AccountNoYesBuyback destination
6Treasury AccountNoYesTreasury destination
7Validator Incentive AccountNoYesValidator incentive destination
8System ProgramNoNoSystem program
9Clock SysvarNoNoFor 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:

ParameterTypeDescription
duration_slotsu64Transition duration in slots (~6,480,000 for 30 days)

Accounts:

#AccountSignerWritableDescription
0AdminYesNoMust match config admin
1DistributorConfig PDANoYesConfig (updated with transition state)
2Clock SysvarNoNoFor transition start slot

7.4 SetCircuitBreaker

Trip or reset the circuit breaker. Admin only.

Parameters:

ParameterTypeDescription
trippedbooltrue to halve distributions, false to resume normal

Accounts:

#AccountSignerWritableDescription
0AdminYesNoMust match config admin
1DistributorConfig PDANoYesConfig (updated)

7.5 UpdateDestinations

Update one or more destination accounts. Admin only. Pass None for any account you do not want to change.

Parameters:

ParameterTypeDescription
reserve_vaultOption<Pubkey>New reserve vault address
ve_reward_poolOption<Pubkey>New veAXIO reward pool address
buyback_accountOption<Pubkey>New buyback address
treasury_accountOption<Pubkey>New treasury address
validator_incentive_accountOption<Pubkey>New validator incentive address

Accounts:

#AccountSignerWritableDescription
0AdminYesNoMust match config admin
1DistributorConfig PDANoYesConfig (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 linearly

Once 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:

FieldTypeDescription
total_distributedu64Sum of all lamports distributed
total_to_reserveu64Cumulative to aXNT reserve
total_to_ve_stakersu64Cumulative to veAXIO pool
total_to_buybacku64Cumulative to buyback
total_to_treasuryu64Cumulative to treasury
total_to_validator_incentivesu64Cumulative to validator pool
last_distribution_slotu64Slot of most recent distribution

All values can be read directly from the on-chain DistributorConfig account for real-time monitoring.

Next Steps