Skip to main content
Fees are the protocol’s second pluggable layer. The core hard-codes where fees may be charged; the calculator defines how much. Any program satisfying three conditions is a drop-in fee strategy — no change to the core or dispatcher, no redeploy.

The two-hop call path

The three conditions

1

Match the discriminator

Expose an instruction whose 8-byte discriminator equals CALCULATE_FEES_DISCRIMINATOR = [140,235,78,9,249,8,129,101]. In Anchor, just name it calculate_fees — the generated discriminator matches by construction.
2

Read the input, treat account[0] as the vault

Take a FeeCalculationInput argument; account[0] is the read-only vault, any further accounts are your own config PDAs.
3

Return output via return-data

Write a FeeCalculationOutput with set_return_data.

The wire types

A minimal calculator

The four buckets and the HWM

Every fee splits into four buckets — LP, manager, protocol, performance — each with its own verified recipient. The performance bucket is high-water-mark-gated: charge only on equity above the prior mark and return new_high_water_mark = Some(balance), which the dispatcher persists. The same gain is never taxed twice.

Prebuilt calculators to reference

Attaching it

Point VaultFees.fee_calc_program at your program id via set_fee_calc_program.
A vault’s economics are just two on-chain pubkeys (policy_program, fee_calc_program) plus their config accounts. An LP can read exactly which strategy and rates a vault is bound to before depositing.