# FeeManager

**Modular, upgradeable fee management contract for vaults.**

The `FeeManager` is responsible for managing and calculating various fee types in a vault system, including deposit, redemption, performance, and protocol fees. It uses a flexible architecture with deterministic storage slots (via `SlotLibrary`) and supports per-vault configurations.

### Key Responsibilities

* Configures and stores global fee settings (in D6 precision).
* Tracks vault-specific state (base asset, min price, timestamp).
* Computes:
  * **Deposit Fee**: Fee charged on asset deposit.
  * **Redeem Fee**: Fee charged on share redemption.
  * **Performance Fee**: Fee based on drop in price (`assets * price = shares`)
  * **Protocol Fee**: Time-based fee accrued per vault.
* Provides administrative controls to update fee settings and vault metadata.

### Storage

Uses an isolated storage slot per deployment instance, computed deterministically using `SlotLibrary.getSlot("FeeManager", name, version)`, ensuring safety and upgradability.

Each vault is associated with:

* `baseAsset`: Reference token used for performance fee calculation.
* `minPriceD18`: Minimum price recorded (used for performance fee calculation).
* `timestamps`: Last update timestamp for time-based fee accrual.

### Fee Calculation Logic

### `calculateDepositFee(uint256 shares) → uint256`

Computes a linear fee as `shares * depositFeeD6 / 1e6`.

### `calculateRedeemFee(uint256 shares) → uint256`

Computes a linear fee as `shares * redeemFeeD6 / 1e6`.

### `calculateFee(...) → uint256 shares`

Calculates the total fee to be charged based on:

* Performance: If current `priceD18` below `minPriceD18`, applies `performanceFeeD6` as `(minPriceD18 - priceD18) * performanceFeeD6 * totalShares / 1e24`.
* Protocol: Time-weighted fee based on `block.timestamp - timestamps[vault]`, computed as `totalShares * protocolFee * (block.timestamp - timestamps[vault]) / (365 * 24 * 3600 * 1e6)`

All fees are paid in **shares** of the vault (not assets).

### Access Control

* Only the `owner` (defined during initialization) can modify fee parameters or vault configurations.
* Calls to `initialize(...)` must come from the factory and include all required setup parameters.

### Events

* `Initialized(bytes data)`: Emitted after initialization.
* `SetFeeRecipient(address feeRecipient)`: On recipient update.
* `SetFees(...)`: On any fee change.
* `SetBaseAsset(...)`: When base asset is configured per vault.
* `UpdateState(...)`: On state update used for protocol/performance fees.

### Errors

* `ZeroAddress()`: Thrown if an address input is zero.
* `InvalidFees(...)`: When the combined fee rate exceeds 100% (`1e6` D6).
* `BaseAssetAlreadySet(...)`: Prevents base asset override if already set.

### Lifecycle

1. **Constructor**: Sets storage slot based on name/version.
2. **Initialization** (via `initialize(bytes)`): Sets owner, recipient, and fees.
3. **Fee Updates**: Admin can update recipient and fee parameters.
4. **Vault Hooks**:
   * `updateState(asset, price)`: Vaults call this to refresh timestamp and min price.
   * `setBaseAsset`: Called once per vault to register its performance reference token.
