Skip to main content
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

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

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):
1

Validation

The Conduit checks the receiver, ensures the Conduit is enabled, and verifies the sender is allowed (via AccountList if configured).
2

Asset pull

Pulls assets from msg.sender — underlying tokens for deposits, conduit shares for redeems.
3

Vehicle interaction

Approves the Vehicle and calls vehicle.create() to start the STEAM operation.
4

Fee capture

Captures the current fee configuration from the FeeManager to ensure consistent fee application at settlement.
5

Auto-processing

If receiver == msg.sender, the Conduit automatically attempts to process the query immediately.

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. WAITING — 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.

Keeper setup

How to configure keeper automation for your Vehicle.

Deposit flow

// 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

Withdrawal flow

// 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

Optional modules

Conduits are extensible through optional modules set at deployment.
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
Delegates query ownership to an external registry.
  • Enables wrapping queries into transferable ERC721 NFTs
  • Advanced use case for tokenized positions
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.

Transfer policies

Each Conduit is configured with a TransferMode that governs ERC20 share transfers:
ModeBehavior
ACCOUNT_LISTEnforces AccountList rules on all transfers (default)
ALLOW_TRANSFERPermissionless transfers — anyone can send or receive shares
BLOCK_TRANSFEROnly 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

AspectDirect VehicleConduitMulti-Vehicle
Share tokenVehicle shares (internal)Conduit ERC20 sharesMulti-Vehicle ERC20 shares
Fee managementNoneFull suite (mgmt, perf, deposit, redeem)Full suite via FeeManager
Access controlNoneAccountList (allowlist/blocklist)EAC role-based
WrapsSingle protocolAny Vehicle or Multi-VehicleMultiple sub-vehicles
User experienceManual query managementSimple create/process with keeper automationAutomated queue-based
Best forProtocol integrationsPlatform distributionInstitutional strategies

Key interface summary

MethodDescription
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():
1

Deploy proxy

Deploy the Conduit proxy via the Beacon pattern.
2

Initialize

Configure the Vehicle, FeeManager, AccountList, and TransferMode.
3

Initial deposit

Make an initial deposit for anti-inflation protection.
4

Enable

For sync Vehicles, the initial deposit settles immediately and the Conduit is enabled. For async Vehicles, call finalizeConduitDeposit() after the initial deposit settles.