Operate a Multi-Vehicle
This guide helps you interact with a multi-vehicle to operate it as an asset-manager.
Steps:
Requirements
- Connected wallet needs to have the roles
MULTI_VEHICLE_MOVEandMULTI_VEHICLE_DISPATCHset on the external access control of the MultiVehicle. (MULTI_VEHICLE_MOVE_ASSETSandMULTI_VEHICLE_MOVE_SHARESwere collapsed into the singleMULTI_VEHICLE_MOVErole — granting either old name succeeds on-chain but guards nothing.) - Target Vehicle should be authorized on the MultiVehicle (see the manage guide to perform this action).
1. Visualize Multi-Vehicle Holdings & Allocations
Before operating your multi-vehicle, it’s useful to see the current sector balances and allocations.
Get Sector Balances
2. Get Authorized Vehicles
Before moving assets, you need to know which vehicles are authorized on your Multi-Vehicle.
Get Authorized Vehicles
3. Moving Assets from Idle Liquidity to a Vehicle
move transfers the multi-vehicle asset (eg. USDC) from the AVAILABLE sector — the idle liquidity — into a vehicle’s staging sector, where it waits until a query is created for it. Once staged, you call dispatch to actually allocate it into the vehicle.
moveAssets and moveShares were collapsed into a single move taking one struct: {from, to, asset, amount, operationId}. Two things follow from that:
- The asset is explicit. Pass the base asset to move base assets, or a sub-vehicle’s address to move that vehicle’s shares. The engine applies different rules to each.
operationIdis yours to choose. It is echoed back in theMovedandDispatchedevents, so a multi-step operation can be reconstructed off-chain by filtering on it.
Sector ids are bytes32. The static ones are the sector name as right-aligned ASCII, and a vehicle’s staging sector is 0x01, eleven zero bytes, then its address.
Note that move and dispatch are both called on the Sector Accounting Engine of the Multi-vehicle.
4. Dispatch Assets to Vehicle
This will create a deposit query on the selected vehicle from the sector the assets were allocated from the above transaction.
Prerequisite — the sub-vehicle has to allow it.
dispatchis the first step that leaves the Multi-Vehicle: the SubQueryEngine calls the sub-vehicle, and the sub-vehicle checks its own access control. If the grant is missing the transaction revertsMissingRole(VEHICLE_STEAM_DEPOSIT, <sub-vehicle>, <SubQueryEngine>)even though everything on the accounting side — authorization, staged balance, deposit cap — is fine. Grant it once per sub-vehicle, in both directions, with the Manage Roles step:eac.grantScopedRole(VEHICLE_STEAM_DEPOSIT, subVehicle, subQueryEngine); eac.grantScopedRole(VEHICLE_STEAM_REDEEM, subVehicle, subQueryEngine);
5. Rebalancing Between Vehicles
Rebalancing moves an allocation from one vehicle to another. There is no longer a single rebalance entrypoint — it is composed from the move and dispatch primitives above, in three steps:
movethe source vehicle’s shares out ofALLOCATIONinto the source vehicle’s staging sector.dispatchaREDEEMon the source vehicle, withsettledDestinationpointed straight at the destination vehicle’s sector — so the redeemed assets never detour throughAVAILABLE. A rejected redeem falls back toALLOCATION.dispatchaDEPOSITon the destination vehicle fortype(uint256).max, consuming whatever arrived.
Thread the same operationId through all three, so indexers and dashboards can reconstruct the rebalance by filtering Moved and Dispatched events on it.
Whether this is atomic depends on the source vehicle. If its redeem settles synchronously, all three steps fit in a single multicall. If it settles asynchronously, the assets only reach the destination’s sector once the redeem query reaches SETTLED, so step 3 has to be a second transaction sent after that — poll the query state rather than sending blind heartbeat transactions. Until step 3 lands, the value sits in the destination’s staging sector and is not yet allocated.