# IPOR Fusion > IPOR Fusion is an open-source on-chain asset management framework by IPOR Labs. Depositor capital sits in ERC-4626 Plasma Vaults. A vault curator (Atomist) configures which DeFi protocols the vault may use through Fuses, and an off-chain strategist (Alpha) executes allocations by calling the vault. Fusion runs on Ethereum, Arbitrum, Base and other EVM chains. This file covers Fusion only, not IPOR Derivatives, IPOR Labs' interest-rate-swap protocol. Documentation: https://docs.ipor.io. Application: https://app.ipor.io/fusion. Facts below are as of 2026-10-06; when sources differ, contract code and ipor-abi win over docs pages. Every page on https://docs.ipor.io is available as plain Markdown by appending .md to its URL. Arriving from docs.ipor.io, read Fusion for agents (https://docs.ipor.io/build-on-fusion/fusion-for-agents.md) first. Core vocabulary: - Plasma Vault: the ERC-4626 vault contract that holds depositor funds. Every interaction with an external protocol goes through the vault. Vault shares use the underlying asset's decimals plus 2 (DECIMALS_OFFSET = 2 in PlasmaVaultLib.sol); do not assume a 1:1 share-to-asset scale. - Fuse: a stateless adapter contract encoding one action on an external protocol (supply, withdraw, borrow, swap, claim). The Plasma Vault executes fuses via delegatecall, so the vault itself holds the resulting positions. Fuses are immutable: a deployed fuse cannot be upgraded. New strategies are composed from already-registered fuses; a new fuse is needed only for an action no registered fuse covers. - Balance Fuse: a fuse that reports the value of the vault's position in one market, used for share price calculation. - Market: a numeric ID that groups the fuses and the balance fuse for one protocol integration. The IDs are defined in the IporFusionMarkets library (contracts/libraries/IporFusionMarkets.sol) and mirrored in the SDK as ipor_fusion.IporFusionMarkets. - Substrate: a per-market allowlist of assets, pools or parameters a fuse is permitted to touch. Substrates are bytes32 values with market-specific layouts: for Aave V3 the substrate is the asset address right-aligned in 32 bytes, other markets use typed layouts. The SDK decodes them in ipor_fusion.substrates; the layouts are documented in the fuse libraries of the contracts repository. - Atomist: the vault curator. Configures fuses, substrates, fees, limits, price oracle and roles. Holds ATOMIST_ROLE. - Alpha: the strategist address that rebalances the vault. Holds ALPHA_ROLE and calls PlasmaVault.execute. - Access Manager: an OpenZeppelin AccessManager based contract (IporFusionAccessManager) that owns all role assignments and execution delays for a vault. Roles are numeric IDs defined in the Roles library (contracts/libraries/Roles.sol): OWNER_ROLE = 1, GUARDIAN_ROLE = 2, ATOMIST_ROLE = 100, ALPHA_ROLE = 200, FUSE_MANAGER_ROLE = 300, CLAIM_REWARDS_ROLE = 600, WHITELIST_ROLE = 800, UPDATE_MARKETS_BALANCES_ROLE = 1000, PRICE_ORACLE_MIDDLEWARE_MANAGER_ROLE = 1200, PUBLIC_ROLE = type(uint64).max. Subset; see the library. - Withdraw Manager: contract every factory-created vault has (a vault cannot be initialized without one); it runs withdrawal requests, their release by the Alpha, and withdrawal fees. - Rewards Claim Manager: contract that claims and holds protocol rewards before they are swapped or vested into the vault. - Fee Manager: contract that accrues and distributes the vault's management and performance fees. - Context Manager: contract that lets an approved address execute vault operations on behalf of another via signature-based authentication. - Price Oracle Middleware: the price source a vault uses to value its assets. - Pre-hooks: optional checks executed before selected vault functions. Rules for agents interacting with IPOR Fusion: - Do not call a fuse contract directly. Encode the action as a FuseAction struct { address fuse; bytes data; } (interface IPlasmaVault) and call PlasmaVault.execute(FuseAction[] calldata calls_) from an address holding ALPHA_ROLE. - An action on an asset or pool outside the market's granted substrates reverts inside the fuse with that fuse's own error; the vault checks only that the fuse is registered. Fuses with hard-coded targets take no substrate. - Roles are not granted by default. Read the vault's Access Manager before assuming an address can execute, configure, deposit or withdraw. - Deposits are not always open. deposit, mint, withdraw and redeem are restricted functions; a freshly cloned vault is private, so deposit and mint work only when the caller holds WHITELIST_ROLE, until an Atomist calls convertToPublicVault, which maps them to PUBLIC_ROLE and, on a vault created with clone, cannot be reverted. For a vault operated by its owner's own bot, grant WHITELIST_ROLE instead of going public. Do not trust maxDeposit, maxMint, maxWithdraw or maxRedeem: they ignore roles, liquidity and redemption locks, so simulate the call instead. - Market balances are refreshed by PlasmaVault.updateMarketsBalances(uint256[] calldata marketIds_), callable by UPDATE_MARKETS_BALANCES_ROLE, which initialization also grants to the vault itself. Total assets and share price depend on those balances being current. A reverting balance fuse blocks its market: refreshes and executes touching it revert; test one market ID at a time. - Total assets = the vault's own balance of the underlying asset + the cached balance of every market + the Rewards Claim Manager's balanceOf when one is set. The ERC20 balance fuse (market 7, ERC20_VAULT_BALANCE) skips the underlying asset and prices every other substrate token, held or not. - Value each holding through exactly one balance fuse: a holding counted by two markets inflates total assets and share price while every on-chain check passes. Known double counts: a receipt token (Aave aToken, ERC-4626 share, Midas mToken) listed as an ERC20 balance substrate next to its own market; the same Morpho Blue market id granted to both the Morpho market (14) and the Morpho liquidity-only market (41); the same ERC-4626 vault or token granted to two markets. - Match substrates to the balance fuse: Erc4626BalanceFuse reverts on a plain token such as USDC; CurveChildLiquidityGaugeBalanceFuse reverts AssetNotFoundInCurvePool when the pool lacks the vault's asset. Some reads skip zero positions, so an empty market's clean refresh proves little. - Every token a balance fuse prices needs an oracle price, or its market blocks. That includes ERC20 substrates, the asset of granted ERC-4626, Euler and Silo vaults, and both tokens of every Morpho market granted to market 14, where supply and supplyCollateral accept any onBehalf. - Withdrawals: withdraw and redeem pay from the vault's idle balance not reserved for released requests, plus what its instant-withdrawal fuses unwind (set by configureInstantWithdrawalFuses, which needs CONFIG_INSTANT_WITHDRAWAL_FUSES_ROLE = 900, held by no address after clone); without them a shortfall reverts in the underlying token's transfer. Beyond that, request with WithdrawManager.requestShares; after the Alpha releases funds, redeem with PlasmaVault.redeemFromRequest within the withdraw window. Separately, the Access Manager locks the calling account for the vault's redemption delay after each deposit or mint. - Take contract addresses only from the ipor-abi repository or from the app. Always state the chain name and chain ID next to an address. mainnet/addresses.json lists vaults, fuses, prehooks and price_oracles per chain but no factory; the per-chain files mainnet/mainnet--fusion/addresses.json are flat name-to-address maps that add the infrastructure contracts, including the vault factory. ABIs are under mainnet/mainnet--fusion/abis. - To deploy a vault, use the address under the IporFusionFactoryProxy key, never IporFusionFactoryImpl: calling clone on the implementation reverts DaoFeePackagesArrayEmpty. - Fuse registry names differ per chain for the same role (Base publishes the Aave V3 balance fuse as BalanceFuseAaveV3 and AaveV3WithPriceOracleMiddlewareBalanceFuse, Arbitrum only as the latter), and SDK class names differ from registry names (the SDK's AaveV3SupplyFuse is the registry's SupplyFuseAaveV3). Resolve names and addresses per chain from ipor-abi; do not port a configuration to another chain by substituting addresses. - Supported chains and chain IDs: Ethereum (1), Arbitrum (42161), Base (8453), Unichain (130), TAC (239), Ink (57073), Plasma (9745), Avalanche (43114), Katana (747474), Botanix (3637), HyperEVM (999), Robinhood (4663), Monad (143) and Flare. ipor-abi holds the current list; "supported" means a Fusion deployment, factory included, exists there. No IPOR source states Flare's chain ID yet. Live vaults run on a subset: enumerate them with GET /v2/fusion/vaults (chainId per vault). - Python: pip install ipor-fusion gives the SDK (Web3Context, PlasmaVault and fuse classes such as AaveV3SupplyFuse). pipx install 'ipor-fusion[cli]' adds the fusion CLI (for example fusion vault info
--chain-id ethereum). The SDK README lists Ethereum, Arbitrum and Base as supported networks. Notes for generating code with the Python SDK (ipor-fusion): - Amounts are raw on-chain integers with no decimal scaling: 1 USDC (6 decimals) is 1_000_000. Use the types in ipor_fusion.types (Amount, Shares and others) instead of bare ints. - Fuse methods are stateless encoders: each returns a FuseAction (fuse address plus calldata) and touches no chain. Nothing happens until PlasmaVault.execute([actions]) runs the batch atomically. - Every wrapper method returns a Call: .call() runs a read-only eth_call on a view and returns a typed value (it raises on a write-only call); .send() signs locally and needs a private key in the Web3Context; .build_transaction() returns the unsigned transaction dict (needs the signer address and an RPC, no key, no value field); .calldata gives the raw bytes for an external signer. - VaultSimulator runs an execute batch plus reads through eth_simulateV1 with no broadcast and no local node. - FusionFactory deploys new vaults with clone; use the IporFusionFactoryProxy address of the chain. After sending clone, read the created addresses from the receipt with decode_clone_receipt(receipt): a .call() preview only predicts the next CREATE addresses, which another transaction can take first, so use a preview only inside one atomic simulation. Do not use clone_supervised (contract function cloneSupervised): only the factory's MAINTENANCE_MANAGER_ROLE may call it, and it gives the caller ADMIN_ROLE, full control of the new vault's Access Manager. - A fresh clone grants its owner only OWNER_ROLE. Before configuring or executing, grant the operating roles through the vault's Access Manager with grant_role(role, account, 0): ATOMIST_ROLE first (it administers the others), then FUSE_MANAGER_ROLE for configuration and ALPHA_ROLE for execute. - On each market, add_fuses, grant_market_substrates and add_balance_fuse must all happen before the first execute, in any order among themselves, and the vault's price oracle must price the underlying asset, or execute reverts. - Common reverts on this path: 0x8745fbfd DaoFeePackagesArrayEmpty means clone was sent to the factory implementation, use the proxy; 0x9996b315 AddressEmptyCode means execute or updateMarketsBalances reached a missing or code-less balance fuse; 0x24a01144 UnsupportedAsset and 0xb73dbe63 UnexpectedPriceResult mean the price oracle cannot price an asset; 0x068ca9d8 AccessManagedUnauthorized means the caller lacks the role the function requires, including deposit or mint on a private vault without WHITELIST_ROLE. MCP (Model Context Protocol) servers. Two options, both named ipor-fusion, with different tool sets (vault listing is vaults_list hosted, vault_list local): - Hosted, no install: https://mcp.ipor.io/mcp is public, unauthenticated and read-only (HTTP transport). Claude Code: claude mcp add --transport http ipor-fusion https://mcp.ipor.io/mcp. Generic client config: {"mcpServers": {"ipor-fusion": {"type": "http", "url": "https://mcp.ipor.io/mcp"}}}. Tools: vaults_list, vault_info, vault_oracle_mapping, fusion_addresses_list, fusion_address_names, fusion_address_lookup, market_morpho_blue, market_meta_morpho. Start with vaults_list and vault_info. Read the fusion://invariants resource before writing code that deploys or configures a vault. Caveats: unfiltered vaults_list returns every vault in one payload, large enough to exhaust a context window; narrow it (parameters: chain_id, sort_by, descending, limit, fields); APYs are percent strings ("4.30%"), never multiply by 100; vault_info supports Ethereum (1), Arbitrum (42161) and Base (8453) only; the address-registry tools do not yet cover Monad, HyperEVM, Robinhood or Flare (fusion_address_lookup returns no match there instead of an error), so read ipor-abi directly for those. - Local, from the SDK: pipx install 'ipor-fusion[mcp]' installs the fusion-mcp server (stdio transport) that exposes the CLI against your own RPC providers and local config. Client config: {"mcpServers": {"ipor-fusion": {"command": "fusion-mcp", "type": "stdio"}}}. Tools: server_info, config_show, config_set_provider, config_set_etherscan_key, vault_info, vault_role_accounts, vault_oracle_mapping, vault_list, vault_add, vault_remove, market_morpho_blue, market_meta_morpho. Configure providers and vaults first (fusion config or the config tools). - Both servers serve the SDK guide as MCP resources fusion://glossary, fusion://architecture, fusion://invariants and fusion://quickstart, and the prompts quickstart, deploy_vault, analyze_vault, trace_oracle_pricing and explain_fuse. - Agent skill: skills/ipor-deploy-vault/SKILL.md in the ipor-fusion.py repository teaches a coding agent the full clone, roles, market, access posture, deposit and execute walk, with the invariants and revert selectors. IPOR Fusion API at https://api.ipor.io (read-only vault and market statistics): - No API key, no authentication, no query parameters: every input is encoded in the URL path. Responses are pre-rendered JSON files served from a CDN and regenerated on a schedule; short history buckets (7d) are refreshed most often, the all bucket least often. - Responses are gzip-encoded; send Accept-Encoding: gzip (curl --compressed). - Most numbers are decimal strings, some fields are JSON floats or null; parse per field with a decimal library. Token amounts and TVL are decimal-scaled human units, not raw base units. Timestamps are ISO-8601 UTC. - Enumerate vaults with GET /v2/fusion/vaults: per vault chainId, address, name, asset, netApy, grossApy, rewardsApy, totalAssets, tvl, publicDepositOpened (access posture), managedByIporAlpha (IPOR Labs runs the Alpha; off-chain) and lastReadBlockTimestamp (freshness). Markets: GET /v2/fusion/markets (chainId, protocol, marketId, supply/borrow APYs). - Time series: GET /v2/fusion/vault-history/{chainId}/{vaultAddress}-{period} and GET /v2/fusion/market-history/{chainId}/{protocol}/{substrate}-{period}. Addresses in these paths must be lowercase; a checksummed address returns 404. Creating a vault with an AI agent (Fusion Vault Launchpad, https://github.com/IPOR-Labs/fusion-vault-launchpad): - Clone the repository and follow its AGENTS.md instead of assembling a deployment by hand. One JSON strategy file describes the vault (chain, underlying, fuses, substrates, price feeds, fees, roles and more); the pipeline turns it into a configured vault in idempotent steps and verifies the result from the vault's own contracts. - A dry-run needs no key. A fork rehearsal on a local anvil fork uses anvil's public test key and then exercises the vault: deposit, every fuse, accounting, withdrawal. A live deployment needs the human's own funded key in a local .env file. - Never ask a human for a private key in a conversation. Never broadcast to a live chain without a clean fork rehearsal, a clean plan/run diff, the three sign-offs in the strategy file (roles reviewed, hardening and front-end listing acknowledged) and an explicit human "yes" for that exact file in that session. - Supported chains: Ethereum (1) and Base (8453). Two worked examples ship: a USDC vault on Aave V3 and a leveraged wstETH/USDC loop on Morpho Blue, both on Base. ## Concepts - [Fusion introduction](https://docs.ipor.io/build-on-fusion/introduction.md): what Fusion is, the on-chain/off-chain split and who the participants are - [Architecture overview](https://docs.ipor.io/build-on-fusion/architecture-overview/general.md): vaults, fuses, Atomists, Alphas and the list of supported chains - [What is a Fusion vault](https://docs.ipor.io/build-on-fusion/architecture-overview/what-is-a-fusion-vault.md): Plasma Vault standards, redemption delay, rewards, fees, configurable versus immutable settings - [What is a Fuse](https://docs.ipor.io/build-on-fusion/architecture-overview/what-is-a-fuse.md): fuse adapter model - [What is an Atomist](https://docs.ipor.io/build-on-fusion/architecture-overview/what-is-an-atomist.md): curator responsibilities - [What is an Alpha](https://docs.ipor.io/build-on-fusion/architecture-overview/what-is-an-alpha.md): strategist responsibilities ## Developer guide - [Fusion for agents](https://docs.ipor.io/build-on-fusion/fusion-for-agents.md): start-here router for AI agents, choosing between the MCP server, the Python SDK, the API and the deployment registry, with the vault-creation call and the rules for agents - [Quick start guide](https://docs.ipor.io/build-on-fusion/developer-guide/quick-start-guide.md): first steps for integrators - [Smart contracts](https://docs.ipor.io/build-on-fusion/developer-guide/smart-contracts.md): contract overview - [Open-source repository](https://docs.ipor.io/build-on-fusion/developer-guide/open-source-repository.md): how the ipor-fusion repository is organised - [Developing a fuse](https://docs.ipor.io/build-on-fusion/developer-guide/developing-a-fuse.md): how to write and register a new fuse - [Balance fuses](https://docs.ipor.io/build-on-fusion/developer-guide/balance-fuses.md): position valuation per market - [Share price calculation rules](https://docs.ipor.io/build-on-fusion/developer-guide/general-share-price-calculation-rules.md): how total assets and share price are computed - [Accounting and PPS protection](https://docs.ipor.io/build-on-fusion/developer-guide/accounting-and-pps-protection.md): cached balances, explicit reporting, manipulation resistance - [Price Oracle Middleware](https://docs.ipor.io/build-on-fusion/developer-guide/price-oracle-middleware.md): price feeds used by vaults - [Configuring pre-hooks](https://docs.ipor.io/build-on-fusion/developer-guide/configuring-pre-hooks.md): pre-execution checks - [API](https://docs.ipor.io/build-on-fusion/developer-guide/api.md): the read-only JSON API for vault and market history, endpoints, conventions and the bucket merge rule - [Security and audits](https://docs.ipor.io/build-on-fusion/developer-guide/security-and-audits.md): audit reports and security process ## Creating a vault with an AI agent - [Fusion Vault Launchpad on GitHub](https://github.com/IPOR-Labs/fusion-vault-launchpad): toolkit that deploys, verifies and rehearses a Plasma Vault from one JSON strategy file, driven by an AI agent with a human in the loop - [AGENTS.md](https://raw.githubusercontent.com/IPOR-Labs/fusion-vault-launchpad/main/AGENTS.md): operating guide for agents, rules, autonomy boundary, private-key handling and the lifecycle commands; read first - [Using the repository with your agent](https://raw.githubusercontent.com/IPOR-Labs/fusion-vault-launchpad/main/docs/09-using-with-your-agent.md): how each agent tool finds the instructions, and a starter prompt - [The strategy file](https://raw.githubusercontent.com/IPOR-Labs/fusion-vault-launchpad/main/docs/03-strategy-json.md): field reference for the JSON strategy and the chain contexts - [Deploying](https://raw.githubusercontent.com/IPOR-Labs/fusion-vault-launchpad/main/docs/04-deploy.md): dry-run, fork rehearsal with the rehearsal stage, live broadcast, verification and recovery - [Hardening](https://raw.githubusercontent.com/IPOR-Labs/fusion-vault-launchpad/main/docs/10-hardening.md): what comes after a verified vault before it takes outside money, and why listing on the app needs the IPOR Labs team ## Operating a vault - [Vault configuration step by step](https://docs.ipor.io/build-on-fusion/atomists/vault-configuration-step-by-step.md): full Atomist setup checklist - [Access management](https://docs.ipor.io/build-on-fusion/atomists/vault-configuration-step-by-step/access-management.md): role hierarchy, role IDs, technical roles that must stay at zero delay - [Timelocks and execution delays](https://docs.ipor.io/build-on-fusion/atomists/vault-configuration-step-by-step/timelocks-and-execution-delays.md): execution delays, grant delays, floors, Guardian veto scope - [Substrates](https://docs.ipor.io/build-on-fusion/atomists/vault-configuration-step-by-step/substrates.md): per-market allowlists - [Curating a Fusion vault](https://docs.ipor.io/build-on-fusion/atomists/curating-a-fusion-vault.md): ongoing vault management topics - [Managing redemption delays](https://docs.ipor.io/build-on-fusion/atomists/curating-a-fusion-vault/managing-redemption-delays.md): Withdraw Manager configuration - [Deposit caps](https://docs.ipor.io/build-on-fusion/atomists/curating-a-fusion-vault/deposit-caps.md): limiting vault size - [Public vault listing](https://docs.ipor.io/build-on-fusion/atomists/curating-a-fusion-vault/public-vault-listing.md): requirements for listing a vault in the app - [Running an Alpha](https://docs.ipor.io/build-on-fusion/alpha/running-an-alpha.md): how strategists execute rebalances - [Best practices for Alphas](https://docs.ipor.io/build-on-fusion/alpha/running-an-alpha/best-practices-for-alphas.md): operating guide for strategy executors - [Vault fees](https://docs.ipor.io/fusion-for-depositors/user-guide/vault-fees.md): management and performance fees ## Code, SDKs and addresses - [ipor-fusion on GitHub](https://github.com/IPOR-Labs/ipor-fusion): Solidity source of Plasma Vault, fuses, managers and libraries - [Roles.sol](https://github.com/IPOR-Labs/ipor-fusion/blob/main/contracts/libraries/Roles.sol): the complete list of role IDs - [IporFusionMarkets.sol](https://github.com/IPOR-Labs/ipor-fusion/blob/main/contracts/libraries/IporFusionMarkets.sol): the complete list of market IDs - [IPlasmaVault.sol](https://github.com/IPOR-Labs/ipor-fusion/blob/main/contracts/interfaces/IPlasmaVault.sol): Plasma Vault interface including the FuseAction struct - [ipor-abi on GitHub](https://github.com/IPOR-Labs/ipor-abi): ABIs and deployed addresses for every chain, including the full fuse list - [addresses.json](https://github.com/IPOR-Labs/ipor-abi/blob/main/mainnet/addresses.json): mainnet vaults, fuses, prehooks and price oracles in one file, keyed by chain - [Base deployment addresses](https://github.com/IPOR-Labs/ipor-abi/blob/main/mainnet/mainnet-base-fusion/addresses.json): per-chain flat address map including the FusionFactory; the same file exists as mainnet--fusion/addresses.json for every supported chain - [ipor-fusion.py on GitHub](https://github.com/IPOR-Labs/ipor-fusion.py): official Python SDK, CLI and MCP server for Plasma Vaults - [ipor-fusion on PyPI](https://pypi.org/project/ipor-fusion/): the SDK package, with cli and mcp extras - [ipor-deploy-vault agent skill](https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/skills/ipor-deploy-vault/SKILL.md): step-by-step vault deployment guide for coding agents, with invariants and revert selectors - [SDK documentation](https://docs.ipor.io/build-on-fusion/alpha/sdk.md): SDK usage for Alphas - [typescript-examples on GitHub](https://github.com/IPOR-Labs/typescript-examples): TypeScript examples of reading and using Plasma Vaults, with ABIs and helper libraries - [IPOR Fusion app](https://app.ipor.io/fusion): live vault list, addresses, positions and performance ## Optional - [Glossary of terms](https://docs.ipor.io/resources/resources/glossary-of-terms.md): definitions used across the docs - [Cross-chain vault integration, technical overview](https://docs.ipor.io/build-on-fusion/developer-guide/cross-chain-vault-integration-technical-overview.md): how vaults hold positions on other chains - [Fusion for depositors](https://docs.ipor.io/fusion-for-depositors/introduction.md): end-user explanations of depositing, withdrawing, fees and risks - [Risks for depositors](https://docs.ipor.io/fusion-for-depositors/user-guide/risks.md): risk disclosures - [Fusion for institutions](https://docs.ipor.io/fusion-for-institutions/executive-summary-the-prime-brokerage-protocol-of-defi.md): institutional overview - [DeepWiki for ipor-fusion](https://deepwiki.com/IPOR-Labs/ipor-fusion): auto-generated code walkthrough, secondary and not authoritative - [DeepWiki for ipor-fusion.py](https://deepwiki.com/IPOR-Labs/ipor-fusion.py): auto-generated overview of the Python SDK components, secondary and not authoritative - [Full documentation index](https://docs.ipor.io/llms.txt): every docs page with its Markdown URL, grouped by section, including IPOR derivatives