> ## Documentation Index
> Fetch the complete documentation index at: https://docs.redpotion.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Fund

> Fund is the hub of a fund instance (star architecture). It is the central orchestrator that:

> Source: [`src/Fund.sol`](https://github.com/zentryHQ/red-potion-contract/blob/main/src/Fund.sol) · Modules: [`src/modules/`](https://github.com/zentryHQ/red-potion-contract/tree/main/src/modules)

## Responsibility

`Fund` is the **hub of a fund instance** (star architecture). It is the central orchestrator that:

* Holds the fund's assets (ERC-20s and native ETH) and pushes/pulls them to strategies and external wallets.
* Orchestrates **batch settlement**: accepting an oracle price report, accruing fees, settling deposit and redeem batches in a single transaction.
* Acts as the **access-control registry** for the whole fund: every spoke authorizes admin calls by checking roles against the Fund's `AccessControl` state (see [Access Control & Roles](/developers/access-control-and-roles)).
* Mediates all spoke-to-spoke communication — spokes only know the Fund, never each other.

The Fund contract itself is thin; most behavior comes from the modules it composes:

| Module                        | Contributes                                                                                          |
| ----------------------------- | ---------------------------------------------------------------------------------------------------- |
| `FundACLModule` / `FundRoles` | Role registry + all role-name constants                                                              |
| `QueueModule`                 | Share/queue addresses, settlement math and internals                                                 |
| `OracleModule`                | Oracle address, batch-id passthrough, accept-report internals                                        |
| `FeeManagerModule`            | FeeManager address, fee accrual internals                                                            |
| `RiskManagerModule`           | Queue-facing `checkDeposit`/`checkRedeem` proxies                                                    |
| `StrategyModule`              | Strategy registry + asset push/pull to [Strategy](/developers/contract-reference/strategy) contracts |
| `ExternalWalletModule`        | Whitelist of external wallets + one-way asset push                                                   |

All module state uses ERC-7201 namespaced storage (`neobank.storage.*`).

## Settlement flow (`acceptReport`)

```mermaid theme={"dark"}
sequenceDiagram
    actor Op as ACCEPT_REPORT_ROLE
    participant F as Fund
    participant O as Oracle
    participant FM as FeeManager
    participant S as FundShare
    participant DQ as DepositQueue
    participant RQ as RedeemQueue

    Op->>F: acceptReport(nextCutoffTime)
    F->>F: assets = union(deposit assets, redeem assets) + feeBaseAsset
    F->>O: acceptReport(assets, nextCutoffTime)
    O-->>F: (batchId, prices[]) — batch advances
    loop for each asset
        alt asset == feeBaseAsset
            F->>FM: accrueFees(totalSupply, price)
            FM-->>F: (feeRecipient, feeShares, protocolRecipient, protocolShares)
            F->>S: mint fee shares
        end
        F->>DQ: read batchDepositTotals(asset, batchId)
        F->>S: mint user shares → DepositQueue, entry-fee shares → feeRecipient
        F->>DQ: settleDeposit(asset, batchId, userShares) — assets move DQ → Fund
        F->>RQ: settleRedeem(asset, batchId, assetAmount) — shares move RQ → Fund
        F->>S: burn redeemed shares, mint exit-fee shares → feeRecipient
    end
```

Share math (in `QueueModule`):

* **Deposit**: `totalShares = depositAmount × 1e18 / price`; entry fee = `totalShares × entryFeeBps / 10000`; the user gets the rest.
* **Redeem**: exit fee = `redeemShares × exitFeeBps / 10000`; payout = `netShares × price / 1e18`. The payout is **snapshotted** in the RedeemQueue at settlement, so later fee/price changes cannot desynchronize accounting.

## Redeem funding flow

Settlement only *records* how much each redeem batch is owed. Paying it out is a second, role-gated step, because at settlement the fund's assets are typically deployed elsewhere. Assets come back either:

* **From strategies** — `pullAssetFromStrategy` (`PULL_FROM_STRATEGY_ROLE`): the Fund pulls the assets itself; a [Strategy](/developers/contract-reference/strategy) can never refuse a pull.
* **From external wallets / bridges** — the controller transfers assets back to the Fund address. The Fund cannot pull from an external wallet; this leg is operational trust. The same applies to capital deployed cross-chain via [StandaloneStrategy](/developers/contract-reference/standalone-strategy).

Once the Fund holds enough: `fundRedeem(asset, batchId)` transfers the snapshotted amount to the RedeemQueue and marks the batch claimable, then users call `RedeemQueue.claimRedeem`.

## Function reference

### Initialization

| Function                                                                                                           | Access                                     | Description                                                                            |
| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | -------------------------------------------------------------------------------------- |
| `initialize(share, depositQueue, redeemQueue, oracle, feeManager, riskManager, fundManager, admin, roleHolders[])` | initializer (via `FundManager.createFund`) | Wires all spoke addresses, grants `DEFAULT_ADMIN_ROLE` to `admin` and any extra roles. |
| `receive()`                                                                                                        | anyone                                     | Accepts native ETH.                                                                    |

### Orchestrated entrypoints

| Function                                 | Access                          | Description                                                                                                                                                                                                          |
| ---------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `acceptReport(nextCutoffTime)`           | `ACCEPT_REPORT_ROLE`            | Accepts the pending oracle report for all allowed assets (deposit ∪ redeem ∪ fee base asset), settles every asset's deposit and redeem batch, and accrues fees. Reverts if any pending report is flagged suspicious. |
| `acceptSuspiciousReport(nextCutoffTime)` | `ACCEPT_SUSPICIOUS_REPORT_ROLE` | Same, but bypasses the suspicious-price check — for a more privileged operator after manual review.                                                                                                                  |
| `fundRedeem(asset, batchId)`             | `FUND_REDEEM_ROLE`              | Transfers the snapshotted payout for a settled redeem batch to the RedeemQueue and marks it claimable.                                                                                                               |

### Views

| Function                                                                                       | Description                                                                                                                                                                                                       |
| ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `protocolFeeRecipient()`                                                                       | Live-resolves via `FundManager → FundManagerDeployer`.                                                                                                                                                            |
| `getRiskContext(asset, batchId)`                                                               | Aggregates everything [RiskManager](/developers/contract-reference/risk-manager) needs: base/asset prices, HWM, entry/exit fee bps, share supply, and the batch's deposit/redeem totals valued in the base asset. |
| `share()` / `depositQueue()` / `redeemQueue()` / `oracle()` / `feeManager()` / `fundManager()` | Spoke addresses.                                                                                                                                                                                                  |
| `getCurrentBatchId()`                                                                          | Passthrough to `Oracle.getCurrentBatchId()`.                                                                                                                                                                      |
| `isStrategy(strategy)`                                                                         | Whether an address is a registered strategy.                                                                                                                                                                      |
| `isExternalWallet(wallet)` / `getExternalWallets()`                                            | External-wallet whitelist.                                                                                                                                                                                        |

### Queue-facing validation (called by queues, view)

| Function                                                 | Description                                                                                                                                 |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `checkDeposit(depositor, asset, batchId, amount, proof)` | Proxied to `RiskManager.checkDeposit`; the real depositor is passed so the merkle whitelist applies to them. Reverts on any violated limit. |
| `checkRedeem(batchId, shares)`                           | Proxied to `RiskManager.checkRedeem`.                                                                                                       |

### Strategy management (`StrategyModule`)

| Function                                         | Access                    | Description                                                                                                                          |
| ------------------------------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `createStrategy(admin, roleHolders[])`           | `CREATE_STRATEGY_ROLE`    | Asks the FundManager to deploy a new [Strategy](/developers/contract-reference/strategy) proxy bound to this fund, and registers it. |
| `addStrategy(strategy)`                          | `ADD_STRATEGY_ROLE`       | Registers an existing strategy whose `fund()` is this Fund.                                                                          |
| `removeStrategy(strategy)`                       | `REMOVE_STRATEGY_ROLE`    | De-registers a strategy.                                                                                                             |
| `pushAssetToStrategy(strategy, asset, amount)`   | `PUSH_TO_STRATEGY_ROLE`   | Transfers assets from the Fund to a registered strategy.                                                                             |
| `pullAssetFromStrategy(strategy, asset, amount)` | `PULL_FROM_STRATEGY_ROLE` | Calls `strategy.pullAsset` to bring assets back.                                                                                     |

### External wallets (`ExternalWalletModule`)

For custody destinations that are not smart-contract strategies (CEX deposit addresses, custodian accounts).

| Function                                   | Access                        | Description                                                                                                               |
| ------------------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `addExternalWallet(wallet)`                | `ADD_EXTERNAL_WALLET_ROLE`    | Whitelists a wallet.                                                                                                      |
| `removeExternalWallet(wallet)`             | `REMOVE_EXTERNAL_WALLET_ROLE` | Removes a wallet.                                                                                                         |
| `pushAssetToWallet(wallet, asset, amount)` | `PUSH_TO_WALLET_ROLE`         | Transfers fund assets to a whitelisted wallet. **One-way by design** — only the wallet's controller can send assets back. |

### Role administration (`ACLModule`)

| Function                                                   | Access                               | Description                                                                                                          |
| ---------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `grantRoles(roleHolders[])` / `revokeRoles(roleHolders[])` | `DEFAULT_ADMIN_ROLE`                 | Batch grant/revoke of any fund role. Standard OZ `grantRole`/`revokeRole`/`hasRole`/`getRoleMember*` also available. |
| `multicall(bytes[])`                                       | anyone (per-call auth still applies) | OZ Multicall batching.                                                                                               |

See [Access Control & Roles](/developers/access-control-and-roles) for the full role table.
