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

# Multi-Vehicle architecture

> How Multi-Vehicles aggregate yield across multiple strategies

<Info>In user-facing documentation, a MultiVehicle is referred to as a **Strategy**. See [Glossary](/developers/glossary).</Info>

A Multi-Vehicle is a sophisticated vault system built on the STEAM protocol. It manages multiple sub-vehicles (yield strategies) with advanced allocation and redemption capabilities, providing a single entry point for diversified DeFi strategies.

## Architecture overview

A Multi-Vehicle is composed of 6 interconnected components:

```mermaid theme={null}
graph TD
    MV[MultiVehicle] --> SAE[SectorAccountingEngine]
    MV --> QSE[QueueStrategyEngine]
    MV --> SQE[SubQueryEngine]
    MV --> QRQ[QueryRedeemQueue]
    MV --> VR[VehicleRegistry]

    SAE ---|Double-entry accounting| SAE
    QSE ---|Priority queue allocation| QSE
    SQE ---|STEAM query management| SQE
    QRQ ---|Async redemption FIFO| QRQ
    VR ---|Authorization & caps| VR
```

## The 6 components

### 1. MultiVehicle (main contract)

The STEAM-compliant entry point that users interact with directly.

**User operations:**

* **Deposit assets** -- receive Multi-Vehicle shares
* **Redeem shares** -- receive base assets back

**Key responsibilities:**

* User-facing STEAM operations (`create`, `resume`, `unlock`, `recover`)
* Share minting and burning using ERC-4626-style exchange rates
* Integration with QueryRedeemQueue for asynchronous redemptions

### 2. SectorAccountingEngine

The central accounting system implementing double-entry bookkeeping principles. Every asset movement is recorded as a transfer between sectors, ensuring the total supply of accounted assets remains constant.

| Sector          | Type      | Description                                  |
| --------------- | --------- | -------------------------------------------- |
| **ENTRY**       | Virtual   | Assets entering the system (accounting only) |
| **DEPOSIT**     | Physical  | Idle base assets awaiting allocation         |
| **ALLOCATION**  | Physical  | Sub-vehicle shares (deployed capital)        |
| **REDEEM**      | Physical  | Base assets ready for withdrawal             |
| **EXIT**        | Virtual   | Assets leaving the system (accounting only)  |
| Vehicle sectors | Staging   | Per-vehicle staging areas                    |
| Pending sectors | Ephemeral | Assets in active queries (in-flight)         |

<Tip>
  For a deep dive into how sectors work and how funds flow between them, see [Accounting and flow of funds](/developers/contracts/accounting).
</Tip>

### 3. QueueStrategyEngine

Defines the allocation strategy through configurable priority queues. The asset manager sets up deposit and redeem queues that control how capital is distributed.

#### Deposit queue

A prioritized list of `{vehicle, target}` pairs:

1. Processes in order (index 0 = highest priority)
2. `target` = maximum shares to allocate to a vehicle before moving to the next entry
3. Stops when the vehicle reaches its target, hits `maxDepositable`, or assets are exhausted

<CodeGroup>
  ```solidity Solidity theme={null}
  // Initial state
  depositQueue = [{aave, 60k}, {morpho, 30k}]
  currentHoldings = {aave: 50k, morpho: 20k}
  newDeposit = 20k shares

  // Algorithm execution:
  // 1. Check aave: 50k < 60k target
  //    -> allocate min(20k available, 10k to reach target) = 10k to aave
  //    -> aave now has 60k

  // 2. Remaining: 10k shares

  // 3. Check morpho: 20k < 30k target
  //    -> allocate min(10k available, 10k to reach target) = 10k to morpho
  //    -> morpho now has 30k

  // 4. Done: aave=60k, morpho=30k
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

<Note>
  The deposit queue does **not** enforce ongoing ratios. If a vehicle grows past its target from yield alone, new deposits skip it and go to the next queue entry.
</Note>

#### Redeem queue

A prioritized list of `{vehicle, target}` pairs where `target` represents a **floor** (minimum shares to maintain):

1. Processes in order (index 0 = highest priority)
2. Redeems from a vehicle down to its floor
3. Moves to the next entry if more assets are needed

<CodeGroup>
  ```solidity Solidity theme={null}
  // Initial state
  redeemQueue = [{aave, 20k}, {morpho, 10k}]
  currentHoldings = {aave: 60k, morpho: 30k}
  redeemRequest = 50k shares

  // Algorithm execution:
  // 1. Check aave: 60k holdings, 20k floor
  //    -> redeem min(50k requested, 60k - 20k available) = 40k from aave
  //    -> aave now has 20k (at floor)

  // 2. Remaining: 10k shares

  // 3. Check morpho: 30k holdings, 10k floor
  //    -> redeem min(10k requested, 30k - 10k available) = 10k from morpho
  //    -> morpho now has 20k

  // 4. Done: redeemed 50k total
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

### 4. SubQueryEngine

Manages the STEAM query lifecycle for operations dispatched to sub-vehicles. It tracks ephemeral accounting to prevent share price distortion during asynchronous operations.

**Ephemeral accounting** ensures that `totalAssets()` remains accurate even when assets are in-flight:

* When a sub-query enters PROCESSING, the system uses the vehicle's `estimate()` function to record expected outputs
* As actual shares are received on settlement, the ephemeral estimate is replaced with real values
* This prevents spikes or drops in the Multi-Vehicle's share price during async settlements

### 5. QueryRedeemQueue

Handles asynchronous redemptions when immediate liquidity is insufficient:

* **Demands** — user redemption requests, created during redeem commit. Each demand records the shares owed and is assigned a sequential index.
* **Fulfillments** — liquidity provisions created by a keeper or operator calling `feedQueryRedeemQueue`. Each fulfillment covers one or more demands using FIFO matching.
* **Partial fills** — a single demand can be fulfilled across multiple rounds. The queue tracks cumulative fulfillment progress using binary search for efficient matching.
* **Claiming** — once fulfilled (partially or fully), users call `claimRedeemQueue` to receive their base assets. No manual monitoring is needed — the queue tracks what's owed.

### 6. VehicleRegistry

Manages authorization and configuration for sub-vehicles. Every vehicle must be registered here before it can receive capital from the Multi-Vehicle.

**Key responsibilities:**

* Validate vehicle compatibility (STEAM standard, SingleAsset, matching base asset)
* Store per-vehicle configuration (mode and cap)
* Enforce role-based access for authorization changes

## The role of the asset manager

The asset manager configures and operates the Multi-Vehicle. Beyond setting initial parameters, they have four active levers.

### Rebalance capital

Move assets directly between sub-vehicles using `rebalance`:

<CodeGroup>
  ```solidity Solidity theme={null}
  // Redeem from source, deposit into destination
  accountingEngine.rebalance(fromVehicle, toVehicle, shareAmount);
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

If the source vehicle is asynchronous, the redemption settles first and the deposit is staged in the destination vehicle's sector until settlement completes.

### Manage sub-vehicles

Add or remove yield sources at any time:

<CodeGroup>
  ```solidity Solidity theme={null}
  // Authorize a new sub-vehicle
  vehicleRegistry.authorize(newVehicle);

  // Or authorize with initial mode and cap
  vehicleRegistry.authorizeAndConfigure(newVehicle, config);

  // Remove a sub-vehicle (redeem all positions first)
  vehicleRegistry.unauthorize(vehicleToRemove);
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

Removing a sub-vehicle prevents new allocations but does not automatically redeem existing positions — unallocate first.

### Reconfigure queues

Update allocation priorities without moving capital:

<CodeGroup>
  ```solidity Solidity theme={null}
  // Set new deposit and redeem queues
  strategyEngine.setQueues(newDepositQueue, newRedeemQueue);
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

New deposits and redemptions follow the updated order immediately. Existing positions are unaffected.

### Feed redemption liquidity

When async redemptions are pending in the QueryRedeemQueue, feed liquidity to fulfill demands:

<CodeGroup>
  ```solidity Solidity theme={null}
  multiVehicle.feedQueryRedeemQueue();
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

Keepers typically automate this, but operators can trigger it manually if redemptions stall.

## Authorization and guardrails

Every sub-vehicle must be explicitly authorized in the **VehicleRegistry** before it can receive capital. Authorization validates that the vehicle implements the STEAM standard, is a `SingleAsset` vehicle, and uses the same base asset as the Multi-Vehicle.

### Vehicle configuration

Each authorized vehicle has a configuration with two parameters:

| Parameter | Values                            | Description                                                                                                                  |
| --------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Mode**  | `Automatic` (default), `Manual`   | Automatic vehicles participate in queue-based allocation. Manual vehicles only receive capital through explicit rebalancing. |
| **Cap**   | Share target (default: unlimited) | Maximum allocation target for this vehicle. Limits exposure to a single yield source.                                        |

<CodeGroup>
  ```solidity Solidity theme={null}
  // Authorize with Automatic mode and a 100k share cap
  vehicleRegistry.authorizeAndConfigure(vehicle, VehicleConfig({
      mode: VehicleMode.Automatic,
      cap: Target(100_000e18)
  }));
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

### On-chain guardrails

Authorization and caps create enforceable boundaries:

* **Queue configuration** cannot route capital to unauthorized vehicles
* **Allocation caps** limit exposure regardless of queue targets or active rebalancing
* **Role-based access** (via EAC) controls who can authorize vehicles, set caps, and reconfigure queues — allowing platforms commissioning a strategy to set guardrails that asset managers cannot override

This means strategies can run hands-off through queue automation while enforcing risk boundaries that neither automation nor operators can exceed.

## Sync and async sub-vehicles

Multi-Vehicle orchestrates both synchronous and asynchronous sub-vehicles.

**Synchronous** sub-vehicles (Aave, Compound, ERC-4626) complete in a single transaction:

<CodeGroup>
  ```solidity Solidity theme={null}
  // Sync flow: single transaction
  // EMPTY -> UNLOCKING -> SETTLED
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

**Asynchronous** sub-vehicles (Ethena, Syrup) require multiple transactions:

<CodeGroup>
  ```solidity Solidity theme={null}
  // Async flow: multiple transactions
  // EMPTY -> PROCESSING -> (PAUSED ->) UNLOCKING -> SETTLED
  ```

  ```typescript TypeScript theme={null}
  // Coming soon
  ```
</CodeGroup>

When interacting with async sub-vehicles:

* Sub-queries remain in PROCESSING until the underlying protocol is ready
* Ephemeral accounting tracks expected outputs to prevent share price distortion
* The Keeper system automates monitoring and advancing nested operations
* Operators should monitor pending sectors for high balances indicating slow settlement

## Design principles

1. **Separation of concerns** -- Each component has a single, well-defined responsibility
2. **Double-entry accounting** -- All asset movements are tracked through sector transfers
3. **Asynchronous by design** -- STEAM handles both sync and async operations gracefully
4. **Queue-based strategy** -- Flexible, operator-controlled allocation and redemption logic
5. **Accurate pricing** -- Ephemeral accounting ensures share price accuracy during in-flight operations

<Warning>
  **Trade-offs to consider:**

  * **Gas costs** -- More automation means higher gas costs. Queue-based strategies execute more transactions.
  * **Complexity** -- More vehicles mean more monitoring and management overhead. Start simple and scale up.
  * **Async operations** -- Sub-vehicle operations may not settle immediately. Design your flows with async handling in mind.
</Warning>
