The Composable Virtual Machine: Technical Overview and Example Case

By Dzmitry Lahoda, 0xbrainjar


User transactions and intents need a language for execution across different environments/ecosystems. The Composable Virtual Machine (CVM) is the building block that energizes the Inter-Blockchain Communication (IBC) Protocol to be able to meet this need.

For example, the CVM enables the ability to move Polkadot’s DOT to Osmosis, swap to DOT to ETH, move ETH to Ethereum, swap ETH to USDC, and move funds to Composable’s Cosmos chain. This all occurs in one user-signed transaction, which is expressed in plain English.

In this post, we describe the technical architecture of the CVM, and provide an example use case that applies the CVM for a cross-chain exchange.

The Solution

Technical Overview

The CVM is made of opaque contracts for execution of non-atomic, asynchronous, trust-minimized, non-custodial, bridge-agnostic and non-Turing complete cross-chain programs. This involves code propagated along with data, accessing de facto native liquidity markets on each chain and abstracting away several underlying transports, encodings, assets systems, and messaging protocols.

Here is what should happen semantically:

This sounds simple, but you need to know several encodings, transports protocols, and SDKs to do this. Also, without the CVM, one may not easily start on Polkadot and proceed to the end of this sequence of depicted steps using a single transaction.

CVM solves it this way (displayed in a simplified manner):

Exchange, as depicted above, is just one of the many possible operations in the CVM.

Architecture and Flow

Here is the logical state of the CVM:

The user (wallet) has an executor (CVM account) on each chain (instantiated on demand). The CVM account delegates a CVM contract to bridge assets and execute cross-chain on the user’s behalf.

The CVM is bridge-agnostic, with full capabilities when the target chain allows permissionless contracts and general message passing, as well as limited shortcuts when no custom code is allowed and only a subset of target cross-chain operations are possible.

Let us look into a hop from one chain to another chain in detail (additional hops will just repeat part of the picture):

The above diagram starts with a fully CVM-enabled flow.

In the end, it shortcuts VM execution to a standard protocol without doing SubProgram execution. This happens if there is an incentive to do a shortcut (for example, gas costs or limited CVM support on the target) and the subprogram is simple, like a transfer.

All the CVM receives is CVM programs. It then uses routing configuration (of assets, bridges, and their features) to dispatch programs over underlying protocols.

CVM Execution Semantics

Each chain within the CVM contains a singleton entity consisting of the Router and the Gateway. Implementers MAY choose to create a monolithic smart contract or a set of modular contracts.


Each chain contains a singleton bridge aggregator, the Gateway, which abstracts over transports.


Each program arriving through the Gateway is passed to the Router, which becomes the initial beneficiary of the provided Assets before finding or instantiating an Executor instance. The router then transfers funds to the Executor instance.

Subsequent calls by the same Origin will not result in an instantiation, but instead in re-use of the Executor instance. This allows foreign Origins to maintain state across different protocols, such as managing LP positions.

If no executor instance has been created for a given caller, the call to the Router must either come from the IBC, XCM, OTP, or a local origin. After the instance has been created, it can be configured to accept other origins by the caller.

Ownership & Security

Executor instances maintain a set of owners:

/// One or more ordered set of unique cross chain accounts.

/// Owners have full control over funds in CVM Executor

type Owners = Identity[]

/// Network prefixed cross chain native chain Account

type Identity = [Network, Account]

Programs are only executed by the executor if the caller is in the set of owners.

Ensuring that the caller is an owner is an incredibly important check, as the owner can delegate calls through the executor, directly owning all state, funds, and possible (financial) positions associated with the executor account. Since each executor has their own Identity, they might own other accounts as well. Thus the owners control more accounts than just the contract storing the owners.

The Call instruction has the same security risks as calling any arbitrary smart contract, such as setting unlimited allowances.

Adding an owner to the set of owners grants them the ability to evict other owners.

Failure to execute an instruction will lead to a transaction being reverted. However, the funds will still be in the executor account’s control. If you implement the CVM, ensure that changing ownership is always done atomically (add and remove in the same transaction) to ensure funds are not lost forever.

Using bridges is equivalent to adding them as owners on your executor instance.


Execution fees are opt-in and paid by the user by using the Tip registry value.

Asset Registries

Assets can be identified using a global asset identifier.

Example: Cross-Chain Exchange (swap)

Traditionally, users and applications were trading tokens that were only available on their native chain. If you were operating on a chain X, you would only be able to swap tokens that were registered on X (be it native, ERC20 virtualized, or even virtualized and wrapped tokens like WETH).

Manipulating tokens is very complex already. Users willing to move assets between chains are facing incredible difficulties. Not only is bridging hard, but it is also insecure. In most cases, bridges are centralized and hackable by design. We, at Composable, try to push the blockchain vision forward, trustless from the start to the end.

In this example, we will execute a cross-chain swap through CVM and understand how programs are relayed, instructions are executed, and funds are transferred. Be aware that this use case can be generalized to any DeFi protocol and it is the reason why the CVM makes protocols cross-chain native.

Under CVM, tokens are free to fly between any chain connected to its network. They can not only be traded regardless of their origin, but also are completely abstracted thanks to a globally unique CVM asset identifier.

Alice could submit the following CVM program, along with 250 PICA to execute a cross-chain swap:

spawn network=Osmosis amount=250PICA { // Move to Osmosis with 250 PICA

transfer to=Tip amount=25PICA // optional tip to the relayer for the journey

// Execute a swap, effectively trading 200 PICA for OSMO with 1% slippage tolerance.

// This might be replaced by an arbitrary call 0x042502 representing the swap,

// but for some well-known protocols, we decided to include a custom, strongly typed instruction.

exchange give=200PICA want=99%OSMO

// At this point, we don't know how many OSMO/PICA we have.

// But we can ask CVM to move 100% of both!

spawn network=Picasso amount=100%OSMO,100%PICA {

// optional tip for the relayer for the cosy home with the remaining PICA.

transfer to=Tip amount=100%PICA

// 1.3.2. Funds are safu.

transfer to=Alice amount=100%OSMO



  1. Alice submits the CVM program and the instruction 1. is executed, resulting in:

    i. The child CVM program, consisting of the instructions [1.1., 1.2., 1.3.] is being submitted within an IBC packet to Osmosis.

    ii. The funds attached to the child program, 250 PICA, are being transferred to Osmosis using an ICS20 transfer.

  2. An IBC relayer, listening to on-chain events, determines that relaying the IBC packet containing the CVM program is profitable. It proceeds and relays both the funds and the packet to Osmosis.

  3. The packet is submitted by the relayer and subsequently processed on Osmosis, resulting in the child CVM program being executed:

    i. The instruction 1.1. is executed: 25 PICA are transferred to the relayer.

    ii. The instruction 1.2. is executed: 200 PICA are traded against an unknown amount X of OSMO.

    iii. The instruction 1.3. is executed, resulting in:

     a. The second child CVM program, consisting of the instructions [1.3.1., 1.3.2.] is being submitted within an IBC packet to Picasso.
     b. The funds attached to the second child program, 100% of the OSMO, and 100% of the remaining PICA are transferred to Picasso using an ICS20 transfer.
  4. Finally, an IBC relayer determines that relaying the program is again profitable and the packet and the funds are relayed to Picasso.

  5. The packet is submitted by the relayer and subsequently processed on Picasso, resulting in the second child CVM program being executed:

    i. The instruction 1.3.1. is executed: 100% of the remaining PICA (25 + dust from the swap) is transferred to the relayer.

    ii. The instruction 1.3.2. is executed: 100% of the OSMO is transferred back to Alice.


The CVM has been engineered to execute complex cross-chain operations in a single, user-signed transaction.

For users, CVM streamlines your experience by abstracting away complicated terms and protocols. With our trust-minimized, non-custodial approach, you own your assets at every step. It’s cross-chain asset management, simplified.

For developers, CVM offers native support for various liquidity markets, asset systems, and even bridges. This makes the CVM the most versatile cross-chain solution available. All you need is to write your program once and watch it execute anywhere, seamlessly.

For more details about the CVM and how it serves developers, users, and other DeFi participants, please refer to its documentation here. This is also where you can find a model of the CVM design in addition to definitions and additional resources that will help you better understand the CVM at a technical level. The CVM github repo is available here. CVM contracts deployed on mainnet are available as centauri1c676xpc64x9lxjfsvpn7ajw2agutthe75553ws45k3ld46vy8pts0w203g for Composable’s Cosmos chain and here for Osmosis.

1 Like