Skip to main content
A Conduit wraps an existing strategy (Multi-Vehicle or Vehicle) with your own ERC20 share token, fee structure, and access control. This guide walks you through deploying one using the ConduitFactory already deployed on each supported chain.

Before you begin

You need a strategy to wrap and an External Access Control (EAC) contract. Fee Manager and AccountList are optional.
PrerequisiteRequiredHow to get it
Strategy (Multi-Vehicle or Vehicle)YesUse a Strategy or Wrap a yield source
External Access Control (EAC)YesDeploy an EAC — your central permission contract
Fee ManagerNoDeploy a Fee Manager — or pass address(0) for no fees
AccountListNoSet up compliance — or pass address(0) for permissionless access
Already completed Use a Strategy? You already have an EAC and a Strategy-level Fee Manager deployed. You can optionally deploy a separate Fee Manager for your Conduit — see Configure fees. Skip to Choose your configuration.
Starting fresh? At minimum, deploy an EAC before proceeding — it’s a single transaction. See Compliance — Deploy and configure access control.

Choose your configuration

Before deploying, decide on three key parameters:
Deploy a FeeManager to collect fees on your Conduit. You can configure:
  • Management fee — annualized, prorated by time elapsed
  • Performance fee — charged on gains above a high water mark
  • Deposit fee — deducted from shares received
  • Redeem fee — deducted from assets received
Set to address(0) if you don’t need fees. To deploy a Fee Manager, see Configure fees.
Deploy an AccountList to control who can deposit, withdraw, and hold shares:
  • Allowlist mode — only approved addresses can interact
  • Blocklist mode — all addresses except blocked ones can interact
  • Sanctions integration — connect to Chainalysis or similar oracles via ISanctionsList
Set to address(0) for permissionless access. To deploy an AccountList, see Compliance.
Choose how your Conduit’s ERC20 shares can be transferred:
ModeBehavior
ACCOUNT_LISTEnforces AccountList rules on transfers (recommended for compliance)
ALLOW_TRANSFERPermissionless — anyone can send or receive shares
BLOCK_TRANSFEROnly mint and burn — no user-to-user transfers

Deploy the Conduit

1

Get the ConduitFactory address

Railnet deploys a ConduitFactory on each supported chain. Look up factory addresses in Supported protocols.
ConduitFactory factory = ConduitFactory(CONDUIT_FACTORY_ADDRESS);
2

Configure spawn parameters

Define your Conduit’s configuration. The vehicle parameter accepts any STEAM-compliant contract — a Multi-Vehicle or a Vehicle.
ConduitFactory.SpawnParams memory params = ConduitFactory.SpawnParams({
    name: "Platform USDC Yield",           // Your branded share token name
    symbol: "pUSDCy",                       // Your branded share token symbol
    vehicle: IVehicle(MULTI_VEHICLE_ADDRESS), // The strategy to distribute
    feeManager: IFeeManager(feeManagerAddress), // address(0) for no fees
    accountList: IAccountList(accountListAddress), // address(0) for permissionless
    ownerRegistry: IOwnerRegistry(address(0)),
    accessControl: accessControl,           // Your EAC contract
    transferMode: ConduitStructs.TransferMode.ACCOUNT_LIST,
    initialDepositSize: 1e6,                // Initial deposit (e.g., 1 USDC)
    initialExpectedSupply: 1e6,
    depositAsset: IERC20(USDC_ADDRESS),
    querySalt: bytes32(0),
    deploymentSalt: keccak256("platform-conduit-v1")
});
3

Approve and spawn

Approve the factory to spend the initial deposit, then spawn the Conduit.
// Approve the factory to spend the initial deposit
IERC20(USDC_ADDRESS).approve(address(factory), 1e6);

// Spawn the Conduit
Conduit conduit = Conduit(
    address(factory.spawn(params, keccak256("deployment-salt")))
);
The initial deposit protects against inflation attacks by bootstrapping the share supply. The initial shares are burned automatically.
4

Finalize (async strategies only)

For sync yield sources, the Conduit is enabled immediately after spawning. For async yield sources (or strategies wrapping async sources), wait for the initial deposit to settle, then finalize:
// Call after the initial deposit has settled
factory.finalizeConduitDeposit(address(conduit));

Verify deployment

After deployment, confirm the Conduit is operational:
// Check the Conduit is enabled
require(conduit.isEnabled(), "Conduit not enabled");

// Verify the underlying strategy
address vehicle = address(conduit.getVehicle());
require(vehicle == MULTI_VEHICLE_ADDRESS, "Wrong vehicle");

// Check the asset
address asset = conduit.asset();
require(asset == USDC_ADDRESS, "Wrong asset");

Next steps

Deposits & withdrawals

Process deposits and withdrawals through your Conduit.

Compliance & access control

Configure roles and permissions for your Conduit.

Configure fees & revenue

Set up fee structures and revenue distribution.

Supported protocols

Look up deployed factory and infrastructure addresses per chain.