> ## 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.

# Conduits

> The distribution layer that connects yield strategies to platforms and their users

Conduits are how platforms distribute yield strategies to their users. A platform deploys a Conduit on top of any Vehicle or Multi-Vehicle to create a branded entry point with custom shares, fees, and compliance — without building custom infrastructure for each DeFi protocol.

Think of it this way:

* **Vehicle / Multi-Vehicle** — The strategy (executes protocol-specific logic, manages allocations)
* **Conduit** — The distribution channel (each platform deploys its own Conduit with custom fees, shares, and compliance on top of the same strategy)

Users interact with Conduits. Conduits interact with Vehicles or Multi-Vehicles on their behalf.

## Why Conduits exist

<AccordionGroup>
  <Accordion title="Scaling without fragmentation">
    Asset managers build one strategy (a Multi-Vehicle) — they don't need to deploy a separate strategy for each distribution partner. Each platform deploys its own Conduit on top of the same Multi-Vehicle, with its own fee structure and access control. One strategy, N platforms.
  </Accordion>

  <Accordion title="Liquidity attribution">
    Conduits identify exactly where liquidity comes from. Because each platform has its own Conduit, the protocol knows which platform originated each deposit. This enables custom revenue-sharing deals and precise attribution for business development.
  </Accordion>

  <Accordion title="Unified user experience">
    Regardless of underlying protocol complexity — whether the strategy uses Aave (sync) or Ethena (async with cooldowns) — the deposit and redeem interface through a Conduit is identical. Platforms don't need to build different UX flows for different protocols.
  </Accordion>

  <Accordion title="Automated operations">
    Keepers automatically process async operations on behalf of Conduit users. In standard DeFi, users must come back after a cooldown period to manually claim their assets. With Conduits, keepers call `process()` automatically — users deposit and receive their shares (or assets) without a second transaction. This is a fundamental UX improvement over standard DeFi vault patterns.
  </Accordion>
</AccordionGroup>

## The share token model

A Conduit issues its own ERC20 shares (conduit shares) to represent ownership. Internally, the Conduit holds shares issued by the underlying Vehicle.

```
Conduit Shares <-> Vehicle Shares <-> Underlying Assets
```

As the underlying Vehicle earns yield, the Vehicle share value increases. This growth is reflected in the Conduit's `totalAssets()`, increasing the value of each conduit share. Users never touch Vehicle shares directly.

## The create/process lifecycle

Conduits simplify the STEAM lifecycle into two user-facing operations.

### Create

When a user calls `create(query, receiver)`:

<Steps>
  <Step title="Validation">
    The Conduit checks the receiver, ensures the Conduit is enabled, and verifies the sender is allowed (via AccountList if configured).
  </Step>

  <Step title="Asset pull">
    Pulls assets from `msg.sender` -- underlying tokens for deposits, conduit shares for redeems.
  </Step>

  <Step title="Vehicle interaction">
    Approves the Vehicle and calls `vehicle.create()` to start the STEAM operation.
  </Step>

  <Step title="Fee capture">
    Captures the current fee configuration from the FeeManager to ensure consistent fee application at settlement.
  </Step>

  <Step title="Auto-processing">
    If `receiver == msg.sender`, the Conduit automatically attempts to process the query immediately.
  </Step>
</Steps>

### Process

The `process(query)` function advances the query through the STEAM state machine:

1. **Fee accrual** -- Accrues management and performance fees by minting shares to the FeeManager
2. **State check** -- Checks the current state of the query in the Vehicle
3. **PAUSED** -- Calls `vehicle.resume()` to continue
4. **UNLOCKING** -- Calls `vehicle.unlock()`, mints conduit shares (deposits) or transfers assets (redeems), and applies transactional fees
5. **RECOVERING** -- Calls `vehicle.recover()` to refund assets or restore shares

### Keeper automation

For async Vehicles (Ethena, Syrup), the `process()` call doesn't happen immediately — the underlying protocol needs time to complete the operation. **Keepers** monitor active queries and call `process()` automatically when the operation is ready to settle.

This means users never need to return to manually claim their assets. They deposit, and their shares appear once the operation settles — no second transaction required.

<Card title="Keeper setup" icon="robot" href="/developers/contracts/keeper">
  How to configure keeper automation for your Vehicle.
</Card>

## Deposit flow

<CodeGroup>
  ```solidity Solidity theme={null}
  // User deposits 1,000 USDC into Conduit
  //
  // 1. Conduit pulls 1,000 USDC from user
  // 2. Conduit approves Vehicle, calls vehicle.create(DEPOSIT)
  //
  // Synchronous Vehicle (e.g., Aave):
  //   -> Query reaches UNLOCKING immediately
  //   -> Conduit calls vehicle.unlock()
  //   -> Conduit mints shares to user (minus deposit fee if any)
  //   -> Done in one transaction
  //
  // Asynchronous Vehicle (e.g., Ethena):
  //   -> Query enters PROCESSING
  //   -> Keeper calls process() when ready (user doesn't need to act)
  //   -> When ready: UNLOCKING -> unlock -> mint shares
  ```

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

## Withdrawal flow

<CodeGroup>
  ```solidity Solidity theme={null}
  // User redeems 1,000 conduit shares
  //
  // 1. Conduit pulls 1,000 shares from user
  // 2. Conduit calls vehicle.create(REDEEM)
  // 3. Vehicle redeems underlying assets
  // 4. Conduit applies redeem fee (if any)
  // 5. Conduit transfers base assets to user
  //    Conduit shares are burned
  ```

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

## Optional modules

Conduits are extensible through optional modules set at deployment.

<AccordionGroup>
  <Accordion title="AccountList">
    Controls who can create queries and receive shares.

    * Implements allowlist or blocklist logic
    * Checked on every `create()` call and share transfer
    * Can integrate with external sanctions oracles (e.g., Chainalysis) via `ISanctionsList`
  </Accordion>

  <Accordion title="OwnerRegistry">
    Delegates query ownership to an external registry.

    * Enables wrapping queries into transferable ERC721 NFTs
    * Advanced use case for tokenized positions
  </Accordion>

  <Accordion title="FeeManager">
    Handles all fee types:

    * **Management fee** -- Annualized, prorated by time elapsed
    * **Performance fee** -- Charged on gains above high water mark
    * **Deposit fee** -- Deducted from shares received
    * **Redeem fee** -- Deducted from assets received

    Fees are captured at query creation time and applied at settlement, ensuring consistency.
  </Accordion>
</AccordionGroup>

## Transfer policies

Each Conduit is configured with a TransferMode that governs ERC20 share transfers:

| Mode             | Behavior                                                      |
| ---------------- | ------------------------------------------------------------- |
| `ACCOUNT_LIST`   | Enforces AccountList rules on all transfers (default)         |
| `ALLOW_TRANSFER` | Permissionless transfers -- anyone can send or receive shares |
| `BLOCK_TRANSFER` | Only mint and burn allowed -- no user-to-user transfers       |

This is a configuration on the Conduit itself, not an external module.

## Conduit vs direct Vehicle vs Multi-Vehicle

| Aspect              | Direct Vehicle            | Conduit                                      | Multi-Vehicle              |
| ------------------- | ------------------------- | -------------------------------------------- | -------------------------- |
| **Share token**     | Vehicle shares (internal) | Conduit ERC20 shares                         | Multi-Vehicle ERC20 shares |
| **Fee management**  | None                      | Full suite (mgmt, perf, deposit, redeem)     | Full suite via FeeManager  |
| **Access control**  | None                      | AccountList (allowlist/blocklist)            | EAC role-based             |
| **Wraps**           | Single protocol           | Any Vehicle or Multi-Vehicle                 | Multiple sub-vehicles      |
| **User experience** | Manual query management   | Simple create/process with keeper automation | Automated queue-based      |
| **Best for**        | Protocol integrations     | Platform distribution                        | Institutional strategies   |

## Key interface summary

| Method                       | Description                                                   |
| ---------------------------- | ------------------------------------------------------------- |
| `create(query, receiver)`    | Create a deposit or redeem query. Auto-processes if possible. |
| `process(query)`             | Advance a query through the STEAM lifecycle.                  |
| `holdings()`                 | Total Vehicle shares held by the Conduit.                     |
| `totalAssets()`              | Total underlying assets managed.                              |
| `estimate(query)`            | Preview output including fees.                                |
| `convert(assets, direction)` | Pure conversion without fees.                                 |
| `isEnabled()`                | Whether the Conduit is open for deposits.                     |
| `getVehicle()`               | The underlying Vehicle contract address.                      |
| `asset()`                    | The underlying ERC20 asset address.                           |

## Deployment

Conduits are deployed via `ConduitFactory.spawn()`:

<Steps>
  <Step title="Deploy proxy">
    Deploy the Conduit proxy via the Beacon pattern.
  </Step>

  <Step title="Initialize">
    Configure the Vehicle, FeeManager, AccountList, and TransferMode.
  </Step>

  <Step title="Initial deposit">
    Make an initial deposit for anti-inflation protection.
  </Step>

  <Step title="Enable">
    For sync Vehicles, the initial deposit settles immediately and the Conduit is enabled. For async Vehicles, call `finalizeConduitDeposit()` after the initial deposit settles.
  </Step>
</Steps>
