Skip to main content
Composer deploys a small set of contracts on every supported EVM chain. Your wallet sends the compiled transaction to your per-user proxy (or, on the proxy’s first use, to the ProxyFactory, which deploys the proxy and runs the flow atomically). The proxy delegatecalls the VM — the shared logic contract — so the flow executes in your proxy’s own balance and storage context. The remaining contracts support arithmetic and invariant checks during execution.
ContractRole
VirtualMachineShared logic that executes a compiled Flow. Each proxy delegatecalls the VM — it is not the transactionRequest.to.
ProxyFactoryDeterministically derives each signer’s per-signer execution proxy, and is the transactionRequest.to on the proxy’s first use (deployAndExecute). See Account model.
ArithmeticProcessorEvaluates core.* arithmetic instructions during execution.
InvariantCheckerEnforces guard assertions baked into the calldata.
FlashloanRegistryResolves flashloan providers for the flashloan materialiser.
LiFiFlashloanAdapterInitiates flashloans and routes the provider callback so lifi.flashloanRepay can settle each leg.
Verify before you hardcode. The most reliable source is the POST /compose response itself: userProxy is your per-user proxy, and transactionRequest.to is that same proxy once it’s deployed (or the ProxyFactory on first use). These always match the deployment that produced your calldata. Treat the tables below as a convenience snapshot.

Canonical (production)

Served from https://composer.li.quest. These addresses are the same on every supported chain.
ContractAddress
VirtualMachine0xb57Ce43Be47DF611C98EB0943e5D36EBDb36cc6D
ProxyFactory0xe174D02351656a883f6626497C86684e849efB35
InvariantChecker0xe17006F4DfE8Aa2bf80589E497ad98D470f66fef
ArithmeticProcessor0x46C2c852E6FEfaF173dFe49457f0Fe61Dc3F587a

Addresses from the compile response

You rarely need to hardcode anything: every POST /compose response carries the two addresses an integration actually touches, and they always match the deployment that produced the calldata.
const result = await builder.compile({ signer, inputs, sweepTo });

result.transactionRequest.to; // your execution proxy (the ProxyFactory on first use)
result.userProxy;             // your per-signer execution proxy address
The remaining contracts (arithmetic processor, invariant checker, flashloan registry, adapter) are wired in by the compiler during lowering and don’t need to be referenced from integration code.