> For the complete documentation index, see [llms.txt](https://docs.keystonefi.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keystonefi.xyz/reference/fees.md).

# Fee Structure

One fee schedule, applied at the vault level:

* Fees paid in **USDC**, not by minting shares
* Depositor token balances never debited
* Post-fee share price reflects the actual outflow

***

## Rates

| Fee                     | Rate                               | Mechanism                                                       |
| ----------------------- | ---------------------------------- | --------------------------------------------------------------- |
| Management              | **0%**                             | Not charged. Capital does not pay rent.                         |
| Performance             | **20% above HWM**                  | Charged only on net-new gains above the prior peak share price. |
| Reserve skim            | **5% of accrued performance fees** | Routed to the reserve fund instead of the admin.                |
| Rebalance / mode switch | **0%**                             | No fee charged on internal position rotation.                   |
| Withdrawal              | **0%**                             | Neither instant nor queued path charges a fee.                  |

***

## High-water mark (HWM)

* `vault.hwm_share_price_1e9` — highest share price ever reached *after* fee collection
* Performance fees apply **only** when the current share price exceeds this mark

```
gain_per_share_1e9 = max(0, current_share_price_1e9 − hwm_share_price_1e9)
total_gain_usdc    = gain_per_share_1e9 × total_shares / 1e9
gross_perf_fee     = total_gain_usdc × perf_fee_bps / 10_000
reserve_skim       = gross_perf_fee × reserve_skim_bps / 10_000
admin_share        = gross_perf_fee − reserve_skim
```

`collect_fees`:

1. Asserts `position_mode == Idle` (Parked) and `!paused` — gains must be crystallized.
2. Transfers `admin_share` USDC out of the vault main USDC ATA → admin's USDC account.
3. Transfers `reserve_skim` USDC out of the vault main USDC ATA → reserve ATA; bumps `reserve_fund_usdc`.
4. Reduces `cached_nav_usdc` by the full `gross_perf_fee`.
5. Bumps HWM to the post-fee share price; updates the peak if it just set a new high.

> `pending_perf_fees_usdc` is reserved for a future per-settle accrual model. Always 0 in v1.0.

***

## Reserve fund

The reserve fund is a hard-coded insurance buffer that absorbs first-loss events:

* **Funded by** the 5% skim on performance fees.
* **Held as** USDC in `reserve_ata` (a vault-PDA-owned ATA, separate from the main USDC ATA); productively lent on Kamino via `lend_reserve` / `unlend_reserve`.
* **Spendable only via** `pay_from_reserve(amount)` — admin-signed, on-chain logged. If part of the reserve is currently lent, the admin must `unlend_reserve` first.
* **Tracked on the vault** as `reserve_fund_usdc` (USDC base units; includes the lent portion).
* **Excluded from `effective_nav_usdc`** for share-price math — reserve growth doesn't dilute or flatter the share price.

Use of the reserve is **not automatic** — the admin must explicitly invoke `pay_from_reserve`. This avoids reflexive draws during routine volatility.

***

## Who can call `collect_fees`

* Only the admin can call `collect_fees`
* The math is fully on-chain and reproducible from `cached_nav_usdc`, `total_shares`, and `hwm_share_price_1e9`
* Anyone can verify the fee delta before/after — not permissionless to call, but permissionless to audit

***

## Worked example

**Start:**

* Vault holds $1,000,000 NAV, 1,000,000 ksUSD outstanding
* Share price = $1.0000 · HWM = $1.0000

**Carry accrues** over a quarter:

* NAV grows to $1,030,000
* Total shares unchanged → share price = $1.0300

Admin runs `close_position` to crystallize gains (mode → `Idle` / Parked), then `collect_fees`:

* Gain per share: $0.0300
* Gross perf fee: 0.0300 × 1,000,000 × 0.20 = **$6,000**
* Reserve skim: $6,000 × 0.05 = **$300** → routed to `reserve_ata` (then `lend_reserve` redeploys it on Kamino)
* Admin share: **$5,700** → admin USDC ATA
* NAV after: $1,030,000 − $6,000 = **$1,024,000**
* New share price: $1.024
* HWM bumps to **$1.024** (post-fee)

Next fee event triggers only above $1.024 — drawdown recovery is free.

***

## Related

* [NAV & share pricing](/reference/nav-calculation.md) — share-price math, `effective_nav_usdc`
* [Admin operations](/for-operators/admin-ops.md) — `collect_fees`, `pay_from_reserve`
* [Security model](/reference/security.md) — admin role and HWM monotonicity guarantee
* [Whitepaper — Yield sources & fees](/reference/whitepaper.md#yield-sources--fees)
