# Fee Model

MetaVaults charge a **performance fee** on positive yield generated during each [epoch](/glossary.md#epoch). There is no management fee or deposit/withdrawal fee.

## Performance fee

The performance fee is calculated as a percentage of the profit (positive yield) between the previous epoch's saved underlying value and the new underlying value reported at settlement.

```
profit = newSavedBalance - lastSavedBalance
fees   = profit * feesInBps / 10000
```

* `feesInBps` is set at vault initialization and can be changed by the owner.
* The maximum allowed fee is **30%** (3000 bps), enforced by the `MAX_FEES` constant.
* If `newSavedBalance <= lastSavedBalance` (no profit or a loss), **no fees are charged**.

### Example

| Value                  | Amount         |
| ---------------------- | -------------- |
| `lastSavedBalance`     | 1,000,000 USDC |
| `newSavedBalance`      | 1,050,000 USDC |
| `feesInBps`            | 1000 (10%)     |
| Profit                 | 50,000 USDC    |
| Fee                    | 5,000 USDC     |
| Net balance after fees | 1,045,000 USDC |

## Fee collection during settle()

Fees are collected atomically during the `settle()` call:

1. The accountant reports `newSavedBalance` — the total vault underlying value after the epoch's strategies.
2. The contract computes the fee and subtracts it from the balance used for share pricing.
3. The fee amount is transferred from the accountant to the **treasury** address via `safeTransferFrom`.
4. Pending deposit and redeem requests are then processed using the post-fee balance.

{% hint style="info" %}
The fee is taken **before** processing pending deposits and redeems. This means depositors who requested during the epoch do not dilute the fee, and redeemers receive their share based on the post-fee net asset value.
{% endhint %}

## Treasury

The treasury is the address that receives all collected fees. It is set at vault initialization and can be updated by the vault owner via:

```solidity
function setTreasury(address _treasury) public onlyOwner
```

The treasury cannot be set to `address(0)`.

## Max drawdown protection

To protect depositors from catastrophic losses (whether from strategy failure or a compromised accountant key), the vault enforces a **max drawdown** check during settlement.

```solidity
if (newSavedBalance < lastSavedBalance * (BPS_DIVIDER - _maxDrawdown) / BPS_DIVIDER) {
    revert MaxDrawdownReached();
}
```

* The default max drawdown is **30%** (3000 bps).
* If the accountant attempts to report an underlying value that exceeds the max drawdown, the `settle()` transaction reverts.
* The max drawdown can be adjusted by the owner via `setMaxDrawdown(uint16)`.

### Example

With a max drawdown of 3000 bps (30%) and a `lastSavedBalance` of 1,000,000 USDC, the minimum acceptable `newSavedBalance` is 700,000 USDC. Reporting anything below this reverts the transaction.

## Fee parameter changes

```solidity
function setFee(uint16 newFee) external onlyOwner
```

* Cannot exceed `MAX_FEES` (3000 bps / 30%).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.spectra.finance/metavaults/fee-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
