# Allocation and Capacity

#### Proportional Allocation

When a user deposits into an OPAL vault, `OpalManager` distributes the incoming capital across every adapter in proportion to what each adapter already holds. Withdrawals reclaim from each adapter in the same proportions.

The allocation algorithm is deterministic: given the same portfolio state, it produces the same result every time. The sum of all per-adapter allocations equals the aggregate input exactly, with no rounding residue.

Every deposit reinforces the existing portfolio composition. Every withdrawal preserves it.

#### The Token Index

OPAL vaults can hold multiple asset tokens and multiple liability tokens across multiple adapters, each with its own internal token ordering. `OpalManager` maintains a global token index (`assetTokens[]` and `liabilityTokens[]`, bounded at MAX\_TOKENS = 10 each) that reconciles adapter-local views into a single coherent aggregate.

A `tokensHash` value (bytes32) represents the current token layout of the vault. Integrations and managed rebalance bundles can assert the expected `tokensHash` at runtime. If the token layout has changed since the bundle was composed, the transaction reverts.

#### Group-Aware Capacity

DeFi lending markets impose supply caps and borrow ceilings. Adapters that share the same underlying market declare the same `groupId`. When computing vault-level capacity (`maxJoin` / `maxExit`), `OpalManager` scales each adapter's raw capacity by the group's share of the combined total, then takes the minimum across all adapters.

This prevents a large deposit from hitting a protocol supply cap at the transaction boundary. The vault returns the correct deposit ceiling before the transaction is attempted.

#### Bounded Complexity

All allocation operations are bounded by **MAX\_ADAPTERS = 10** and **MAX\_TOKENS = 10**, enforced at the contract level. Every vault operation has a known worst-case gas cost regardless of operational history or portfolio complexity.

***

### Atomic Rebalances

#### The Bundler3 Execution Model

Managed rebalances in OPAL are executed through Origami's fork of Morpho Bundler3, an independently audited multi-step transaction engine. `OpalManager` functions as a permissioned Bundler that accepts a list of declarative call steps and executes them sequentially on target plugin contracts.

Every adapter enforces the `withApprovedBundler` modifier on all state-changing functions. Only `OpalManager` can move capital in or out of any adapter. External contracts, compromised wallets, and governance proposals cannot directly touch adapter positions.

#### Access Tiers

| Operation                        | Access Required                 |
| -------------------------------- | ------------------------------- |
| User deposit (`join`)            | None                            |
| User withdrawal (`exit`)         | None                            |
| Managed rebalance (`multicall`)  | Elevated Access only            |
| Add / deprecate / remove adapter | Elevated Access only            |
| Whitelist adapter implementation | OpalAdapterFactory owner only   |
| Approve new external plugin      | Manager owner / Elevated Access |

#### Atomicity via Flash Loans

Multi-step operations (leverage construction, PT rollovers, inter-adapter migrations) are collapsed into a single transaction using the AaveV3Flash plugin. The flash loan provides capital within the same transaction block. A post-execution balance sheet assertion (via the TbsV2 plugin) checks the result against expected ranges.

If every step succeeds and the assertion passes, the position is live. If any step fails or the assertion is off, the entire transaction reverts and the vault returns to its exact pre-operation state.

#### Reentry Safety

Flash loan callbacks are constrained by a predeclared hash mechanism. Before initiating a flash loan, the bundle specifies a hash of the exact nested callback steps. An unexpected callback reverts immediately.

#### Plugin Whitelist

All external integrations (flash loan providers, DEX routers, inter-vault operations) must be registered in `OpalManager`'s plugin whitelist. A bundle step targeting an unregistered address reverts the entire bundle.


---

# 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://docs.origami.finance/the-third-fold-opal/allocation-and-capacity.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.
