AURA

Fees & Economics

Protocol fees, billing templates, and integrator economics for AURA treasuries.

AURA includes a comprehensive fee system that supports protocol-level revenue, integrator economics, and flexible billing models for treasury operators.

Fee Model Overview

AURA's current on-chain fee path accrues execution fees during finalize_execution when a FeeVault is supplied. Fee schedules also carry creation, subscription, AUM, discount, and integrator fields used by templates and off-chain billing surfaces.

SurfaceStored inEnforced on-chain
Execution feeFeeSchedule / legacy ProtocolFeesfinalize_execution when fee_vault is present
Protocol fee floor and integrator boundsProtocolConfigAccountFee schedule validation and fee computation
Creation fee / subscription / AUM fieldsFeeSchedule and templatesStored for billing policy; not charged by propose_transaction

Fees are:

  • Prepaid into a FeeVault attached to the treasury
  • Accrued into the vault's accumulated_fees_lamports bucket during finalization
  • Split according to a FeeSplit table on collection

Fee Vault

Each treasury has an optional FeeVault PDA storing:

import { instructions } from "@aura-protocol/sdk-ts";

await instructions.fees.sendInitFeeVault(client, owner, initFeeVaultInput);
await instructions.fees.sendDepositFees(client, owner, depositFeesInput);

Vault state:

  • fee_balance — prepaid lamports available for future fees
  • accumulated_fees_lamports — accrued fees not yet collected
  • fee_debt_usd — shortfall recorded when low-balance mode is Degrade

Low-balance mode:

  • Block rejects finalization when prepaid balance cannot cover the fee
  • Degrade accrues the covered portion and records the shortfall in fee_debt_usd
  • Warn skips accrual when the vault is short

Fee enforcement

Finalization is rejected with InsufficientFeeBalance when the vault cannot cover the fee and low-balance mode is Block.

Fee Schedules

A FeeSchedule sidecar defines per-treasury fee rates:

await instructions.fees.sendInitFeeSchedule(client, owner, initFeeScheduleInput);

Validation:

  • Rates must fall within ProtocolConfig bounds (integrator limits)
  • Sum of all fees cannot exceed protocol-defined cap

Updates:

await instructions.fees.sendUpdateFeeSchedule(client, owner, updateFeeScheduleInput);

Billing Templates

Pre-defined fee structures that can be applied to multiple treasuries:

await instructions.fees.sendCreateBillingTemplate(client, owner, createTemplateInput);
await instructions.fees.sendApplyBillingTemplate(client, owner, applyTemplateInput);

Built-in profiles:

  • Payroll
  • TradingDesk
  • DaoTreasury
  • GrantProgram
  • VendorPayments
  • ColdStorage
  • Specialty

Forking: Templates can be forked from built-in profiles and customized:

await instructions.fees.sendCreateBillingTemplate(client, owner, forkTemplateInput);

Fee Splits & Recipients

Revenue is split across multiple recipients via a FeeSplit table:

await instructions.fees.sendSetFeeSplits(client, owner, setFeeSplitsInput);

Rules:

  • bps sum must equal 10,000 (100%)
  • Up to 4 recipients
  • Split table applies to all fees accrued after it's set

Collection:

await instructions.fees.sendCollectFees(client, collector, collectFeesInput);

Protocol Configuration

The ProtocolConfig singleton governs global fee economics:

await instructions.lifecycle.sendInitProtocolConfig(
  client,
  protocolAuthority,
  initProtocolConfigInput,
);

Staged updates: All economic changes are timelocked via a two-step process:

// 1. Stage change (48h timelock)
await instructions.lifecycle.sendUpdateProtocolConfig(
  client,
  protocolAuthority,
  updateProtocolConfigInput,
);

// 2. Commit after timelock
await instructions.lifecycle.sendCommitProtocolConfig(
  client,
  protocolAuthority,
  commitProtocolConfigInput,
);

Protocol config changes affect all treasuries. The timelock gives integrators time to update billing templates or opt out.

Org Profiles

Combine policy templates and billing templates into a single "org profile":

await instructions.fees.sendApplyOrgProfile(client, owner, applyOrgProfileInput);

Profiles are validated atomically — both templates must be compatible and within protocol bounds.

Withdrawing Prepaid Surplus

Treasury owners can withdraw unused prepaid balance:

await instructions.fees.sendWithdrawUnusedFees(client, owner, withdrawInput);

Restrictions:

  • Cannot withdraw accrued fees (only prepaid surplus)
  • Must preserve rent and any accrued-fee bucket

Use Cases

Protocol operators:

  • Set global fee floor to fund development
  • Adjust integrator bounds to control ecosystem economics
  • Collect protocol revenue periodically

Integrators (wallets, dashboards, APIs):

  • Define custom billing tiers for their users
  • Earn revenue share on execution fees
  • Apply templates across customer treasuries

Treasury owners:

  • Prepay fees to avoid per-proposal friction
  • Switch between billing tiers as usage scales
  • Monitor accumulated_fees_lamports to budget operational costs

Referral programs:

  • Add referral address to fee split table
  • Referrer earns bps on every execution
  • Tracked on-chain with immutable split history
  • init_fee_vault / close_fee_vault — Vault lifecycle
  • deposit_fees / withdraw_unused_fees — Prepaid balance
  • init_fee_schedule / update_fee_schedule / close_fee_schedule — Per-treasury rates
  • create_billing_template / update_billing_template / close_billing_template — Template authoring
  • apply_billing_template / apply_org_profile — Apply templates
  • set_fee_splits / collect_fees / update_fee_recipient — Revenue collection
  • init_protocol_config / update_protocol_config / commit_protocol_config — Protocol governance

On this page