| name | morpho-builder |
| description | Use when building applications, bots, SDKs, or integrations against the Morpho lending protocol — deposits, borrows, repays, withdrawals, vault v1/v2 integrations, V1→V2 migration flows, risk monitors, portfolio dashboards. Steers toward `@morpho-org/morpho-sdk` (`MorphoClient`) for user-facing transactions and flags uncovered flows (curator ops, market creation, liquidations, flashloans, rewards) that need lower-level SDKs. Invoke whenever a user mentions Morpho, MetaMorpho, Morpho Blue, or any on-chain integration touching these contracts — even if they don't name morpho-sdk explicitly. |
Morpho Builder Skill
Experimental (pre-v1.0) — SDK recommendations, API schemas, and best practices may evolve as the protocol tooling matures.
Reference guide for building applications that integrate with the Morpho lending protocol. For operating on the protocol directly in a conversation, use the morpho-cli skill instead.
Prefer Morpho v2. The Morpho Optimizer (Morpho-Aave, Morpho-Compound) is deprecated. For new vault deployments, prefer vault v2 over MetaMorpho (vault v1). Note: the two vault versions have incompatible ABIs — use vaultV2Abi for v2 vaults and metaMorphoAbi for v1 vaults. Match the ABI to the on-chain contract.
Protocol Overview
Morpho Blue — isolated lending markets. Each market is defined by five parameters: loan token, collateral token, oracle, interest rate model (IRM), and liquidation LTV (LLTV). Markets are identified by a MarketId (hash of these parameters).
Morpho Vaults v2 — the newer vault contract. ERC-4626 compliant. Allocates deposits across multiple markets via adapters, which can wrap MetaMorpho (v1) vaults and Morpho Blue markets. Preferred for new vault deployments. In the SDK: vaultV2Abi, VaultV2, fetchVaultV2.
MetaMorpho (vault v1) — the original vault contract. Still functional and widely deployed on-chain. In the SDK: metaMorphoAbi, Vault, fetchVault. The two vault versions have incompatible ABIs — use the correct one for the contract you're interacting with.
Singleton contract: 0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb — same address on Ethereum (chain 1) and Base (chain 8453) via CREATE2.
Key Entities
| Entity | Identifier | Description |
|---|
| Market | MarketId | Isolated lending pool with specific collateral/loan pair |
| Vault | Address | Multi-market aggregator, ERC-4626. Two versions: v2 (VaultV2) and MetaMorpho v1 (Vault) — ABIs differ |
| Position | User + Market/Vault | User's supply/borrow in a market or deposit in a vault |
| Token | Address + decimals | ERC-20 — decimals vary (USDC/USDT = 6, WETH/DAI = 18) |
Key Quantities
| Quantity | Format | Notes |
|---|
| APY | Decimal (0.0534 = 5.34%) | From GraphQL state.netApy |
| LLTV | Raw 1e18 (860000000000000000 = 86%) | From SDK or API |
| Token amounts | Raw units | Divide by 10^decimals for human-readable. Use parseUnits/formatUnits from viem |
| Health factor | Ratio | ≥ 1.0 = safe, < 1.0 = liquidatable |
SDK Selection
Default to @morpho-org/morpho-sdk for user-facing flows. It is the high-level abstraction layer that wraps blue-sdk, blue-sdk-viem, bundler-sdk-viem, and simulation-sdk, and handles bundler-vs-direct routing, slippage bounds, LLTV-buffer health checks on borrows, ERC-20 approvals / EIP-2612 permits / Permit2 / Morpho setAuthorization requirements, and native-token wrapping — all internally. Hand-rolling these from the lower-level SDKs is error-prone and duplicates logic morpho-sdk already gets right.
Use morpho-sdk for: vault deposits / withdrawals / redeems (V1 and V2), VaultV2 force-withdraw / force-redeem, V1→V2 migration, Morpho Blue supplyCollateral, borrow (with optional PublicAllocator reallocations), atomic supplyCollateralBorrow, repay (by assets or shares), withdrawCollateral, atomic repayWithdrawCollateral, and per-entity reads (getData, getMarketData, getPositionData).
Drop to lower-level SDKs only for:
- Curator / allocator / owner ops on vaults (setCap, reallocate, role management, timelocks, guardian/sentinel flows)
- Morpho Blue market creation
- Liquidations, flashloans, pre-liquidation, rewards claiming
- Custom bundler compositions beyond the actions listed above
- Portfolio-wide aggregation across many markets / vaults (morpho-sdk exposes per-entity reads only — use
blue-sdk-viem fetch helpers or the GraphQL API)
React / wagmi apps: there is no @morpho-org/morpho-sdk-wagmi package. Use @morpho-org/blue-sdk-wagmi hooks for reads, instantiate MorphoClient against the wagmi public client for writes, and pass the buildTx output to wagmi's useSendTransaction.
SDK Registry
All packages are published under @morpho-org on npm.
| Package | Purpose |
|---|
@morpho-org/morpho-sdk | Start here. High-level abstraction wrapping the four SDKs below. Builds user-facing transactions (deposit, borrow, repay, withdraw, migrate) with slippage, approvals, permits, and bundler routing handled internally |
@morpho-org/blue-sdk | Core types, entity classes (Market, Vault, VaultV2, Position, MarketParams), and constants. Used internally by morpho-sdk; use directly only for type imports or uncovered flows |
@morpho-org/blue-sdk-viem | Viem augmentation — ABIs, fetch helpers (fetchMarket, fetchVault, fetchVaultV2, fetchPosition). Used internally by morpho-sdk; use directly for ABIs, multi-entity reads, or uncovered write flows |
@morpho-org/bundler-sdk-viem | Multi-step transaction bundling (approvals, transfers, Morpho ops in one tx). Used internally by morpho-sdk; use directly only for custom compositions beyond morpho-sdk's action set |
@morpho-org/simulation-sdk | Framework-agnostic simulation of Morpho operations. Used internally by morpho-sdk; use directly only for standalone what-if simulations |
@morpho-org/blue-sdk-ethers | Ethers augmentation — same fetch helpers as viem, for Ethers-based projects |
@morpho-org/blue-sdk-wagmi | React hooks (useMarket, useVault, usePosition, etc.) wrapping core SDK. Requires wagmi v2. Pair with morpho-sdk for writes |
@morpho-org/blue-api-sdk | GraphQL SDK with typed queries for the Morpho API |
@morpho-org/simulation-sdk-wagmi | React hooks for client-side simulation (useSimulationState) |
@morpho-org/liquidity-sdk-viem | Liquidity monitoring and bot infrastructure |
@morpho-org/liquidation-sdk-viem | Liquidation bot infrastructure |
@morpho-org/migration-sdk-viem | Migration from Aave/Compound to Morpho |
@morpho-org/morpho-ts | Time and format utilities |
@morpho-org/test | Vitest/Anvil test fixtures for Morpho |
@morpho-org/test-wagmi | Wagmi test config extension of @morpho-org/test |
@morpho-org/morpho-test | Framework-agnostic test fixtures |
SDK Details
@morpho-org/morpho-sdk
High-level abstraction. Default entry point for user-facing flows.
Construction — two equivalent forms: new MorphoClient(publicClient) returns a direct client, or publicClient.extend(morphoViemExtension()) attaches the API to a viem public client under .morpho.
Entity factories — all require a chainId (1 for Ethereum, 8453 for Base):
| Factory | Returns | Use for |
|---|
morpho.vaultV2(address, chainId) | MorphoVaultV2 | Vault V2 (preferred for new deployments) |
morpho.vaultV1(address, chainId) | MorphoVaultV1 | MetaMorpho (vault v1) |
morpho.marketV1(marketParams, chainId) | MorphoMarketV1 | Morpho Blue market |
Reads — each entity exposes getData(), plus getMarketData() / getPositionData(user) where applicable. Returns live on-chain state needed to build actions.
Actions — each action returns { buildTx, getRequirements }:
| Entity | Actions |
|---|
MorphoVaultV2 | deposit, withdraw, redeem, forceWithdraw, forceRedeem |
MorphoVaultV1 | deposit, withdraw, redeem, migrateToV2 |
MorphoMarketV1 | supplyCollateral, borrow, repay, withdrawCollateral, supplyCollateralBorrow, repayWithdrawCollateral, plus getReallocationData / getReallocations for PublicAllocator |
Canonical write pattern:
- Construct
MorphoClient and the entity (vault or market).
- Fetch live state:
await entity.getData() (vaults) or await market.getMarketData() + await market.getPositionData(user) (markets).
- Call the action:
const { buildTx, getRequirements } = await entity.deposit({ amount, userAddress, accrualVault }).
- Resolve requirements:
const reqs = await getRequirements() — returns ERC-20 approvals, EIP-2612 permits, Permit2 data, and/or morpho.setAuthorization(GA1, true) steps as needed.
- Sign permits / send approval txs as dictated by the requirements.
- Build and send:
const tx = buildTx(requirementSignatures) → { to, value, data, action } → sign and broadcast.
Notes:
- Slippage — morpho-sdk computes
maxSharePrice / minSharePrice bounds from on-chain state automatically. Default tolerance is 3 bps, capped at 10%. Override via the action's slippage option when tighter/looser bounds are needed.
- Borrow health —
borrow and supplyCollateralBorrow apply an LLTV buffer automatically using the position snapshot you pass in. Always fetch a fresh positionData immediately before calling borrow actions.
- Native ETH — pass a
nativeAmount to deposit/borrow actions for atomic wrap-and-supply in a single transaction.
- Analytics — an optional
metadata field on every action tags the transaction for attribution.
- No wagmi wrapper — morpho-sdk is viem-only. In React, construct
MorphoClient against the wagmi public client (usePublicClient()) and feed buildTx output into useSendTransaction.
@morpho-org/blue-sdk
Types, entity classes, and constants.
Market — class with operation methods (.supply(), .borrow(), .repay(), .withdraw()) and conversion methods (.toSupplyAssets(), .toBorrowAssets())
MarketParams — new MarketParams({ loanToken, collateralToken, oracle, irm, lltv })
MarketId — branded type identifying a market
Position — new Position({ supplyShares, borrowShares, collateral })
VaultV2 — vault v2 entity class (preferred for new integrations)
Vault — MetaMorpho (vault v1) entity class
VaultConfig — configuration class for MetaMorpho vaults
@morpho-org/blue-sdk-viem
ABIs, fetch helpers, and viem augmentation.
ABI catalog — import these instead of hand-rolling ABI JSON:
| Export | Contract |
|---|
blueAbi | Morpho Blue singleton |
vaultV2Abi | Vault v2 (preferred for new deployments) |
vaultV2FactoryAbi | Vault v2 factory |
metaMorphoAbi | MetaMorpho / vault v1 (use for existing v1 vaults) |
metaMorphoFactoryAbi | MetaMorpho factory / vault v1 |
erc2612Abi | ERC-2612 permit |
permit2Abi | Uniswap Permit2 |
wstEthAbi | Wrapped stETH |
adaptiveCurveIrmAbi | Morpho's adaptive curve IRM |
blueOracleAbi | Morpho oracle |
Fetch helpers — fetchMarket, fetchVaultV2 (v2) / fetchVault (v1), fetchPosition read on-chain state into SDK entity objects. Use the fetch helper matching the on-chain vault version. Entity methods include market.toSupplyAssets(), vault.toShares(), etc.
@morpho-org/blue-sdk-wagmi
React hooks wrapping the core SDK. Requires wagmi v2.
Hooks: useMarket, useVault, usePosition, useToken, useHolding, useMarkets, useVaults, usePositions, useTokens, useHoldings, useVaultMarketConfig, useVaultMarketConfigs, useVaultUser, useVaultUsers, useMarketParams, plus plural variants.
@morpho-org/simulation-sdk + @morpho-org/simulation-sdk-wagmi
Client-side simulation of Morpho operations. useSimulationState hook provides simulated post-state for UI previews without submitting transactions.
GraphQL API
Endpoint: https://api.morpho.org/graphql
Key queries: vaults (fields: address, name, symbol, asset, state.netApy, state.totalAssets) and markets (fields: uniqueKey, loanAsset, collateralAsset, state.supplyApy, state.borrowApy, state.utilization, lltv).
Filters and Pagination
| Filter | Example | Notes |
|---|
chainId_in | [1], [8453], [1, 8453] | Required — always specify chain |
assetSymbol_in | ["USDC"] | Filter by asset symbol |
address_in | ["0x..."] | Filter by vault address |
uniqueKey_in | ["0x..."] | Filter by market ID |
userAddress_in | ["0x..."] | Filter positions for a user |
Paginate with first and skip. Iterate until items.length < first.
Value Interpretation
| Field | Format | Conversion |
|---|
netApy / supplyApy / borrowApy | Decimal | 0.0534 = 5.34% |
totalAssets | Raw string | Divide by 10^asset.decimals |
lltv | Raw 1e18 string | Divide by 1e18 for percentage |
Integration Approaches
- Backend / scripts / bots (viem) — default to
MorphoClient(publicClient) from @morpho-org/morpho-sdk. Use @morpho-org/blue-sdk-viem fetch helpers + ABIs directly only for reads across many entities or for actions morpho-sdk doesn't expose.
- Frontend (React + wagmi) — use
@morpho-org/blue-sdk-wagmi hooks (useVault, usePosition, etc.) for reactive reads. For writes, construct MorphoClient against usePublicClient(), build the transaction with morpho-sdk, and submit via wagmi's useSendTransaction. There is no @morpho-org/morpho-sdk-wagmi.
- Advanced (curator ops, market creation, liquidations, flashloans, rewards) — morpho-sdk does not cover these. Use
@morpho-org/blue-sdk-viem ABIs together with the targeted sub-SDKs: @morpho-org/liquidation-sdk-viem, @morpho-org/liquidity-sdk-viem, or @morpho-org/migration-sdk-viem.
Protocol Mechanics
Dead Deposits (Inflation Attack Protection)
Detailed reference
ERC-4626 vaults are vulnerable to share-price inflation attacks on their first deposit. A dead deposit — minting shares to the burn address 0x000000000000000000000000000000000000dEaD — must be the very first transaction on any new vault or market. Any user deposit before this enables the attack.
Vault V2 — target shares depend on the asset's decimals:
Formula: targetShares = max(1e9, 10^(6 + max(0, 18 - decimals))) — 18-dec assets: 1e9, 8-dec: 1e16, 6-dec: 1e18. Call vault.mint(TARGET_SHARES, 0xdead).
Market V1 — fixed 1e9 shares regardless of decimals. Call morpho.supply(marketParams, 0, 1e9, 0xdead, "").
Vault V1 — 1e9 shares standard; use 1e12 for tokens with fewer than 9 decimals.
Active-cap requirement: When a Vault V2 references underlying markets/vaults, 0xdead must also hold:
1e9 supplyShares in each Market V1 with non-zero vault caps
1e9 shares in each Vault V1 with non-zero caps or present in withdraw queues
AdaptiveCurveIRM
Detailed reference
Morpho's approved IRM uses a two-pronged mechanism:
- Curve — instantly adjusts rates when utilization changes (e.g., 90% ↔ 0% scales rate ×4 or ÷4)
- Adaptive — continuously shifts the target rate over time based on sustained utilization
| Utilization | Rate behavior |
|---|
| 0% | Halves every ~5 days |
| 90% (target) | Stable |
| 100% | Doubles every ~5 days |
Operational warnings: Avoid 100% utilization — rates compound aggressively. Seed markets with initial supply immediately after creation; an empty market at 0% utilization triggers automatic rate decay.
Slippage and Share/Asset Conversion
Detailed reference
The exchange rate between assets and shares can shift between transaction preparation and on-chain execution. With a proper dead deposit this is a UX concern, not a security vulnerability, but integrations should still protect users.
Defensive pattern: When using @morpho-org/morpho-sdk, slippage bounds (maxSharePrice / minSharePrice, default 3 bps, capped at 10%) are computed and applied automatically — no manual preview+tolerance wiring is needed. Only when dropping to blue-sdk-viem / bundler-sdk-viem directly should you hand-roll the pattern: call previewDeposit() to estimate shares, apply a tolerance floor (e.g., 1%), and verify the actual result meets the minimum.
Full withdrawals: Use redeem(), not withdraw() — avoids leaving dust behind.
Vault V2 quirk: maxDeposit, maxMint, maxWithdraw, and maxRedeem always return zero. Do not rely on these for capacity checks.
Bad Debt Tracking
Detailed reference
- V1.0: Realized immediately — share price drops atomically for all suppliers in the affected market. Vulnerable to flash-loan amplification of bad debt realization.
- V1.1+: Tracked via
lostAssets field — share price is unaffected until explicit realization. Prevents flash-loan manipulation.
Common Pitfalls
Detailed reference
| Pitfall | Consequence | Prevention |
|---|
| Missing dead deposit | Inflation attack / share-price manipulation | Seed shares to 0xdead before any user deposit |
withdraw() for full exit | Dust remains in position | Use redeem() for full exits |
| Oracle risk blindness | Liquidations with stale or manipulated prices | Check oracle type, freshness, and known risks before integrating a market |
| ERC4626 vault as collateral | Share-price manipulation (Cream-hack style) | Avoid V1.0 vaults as collateral; V1.1+ without bad debt realization are safer |
| ERC4626 vault as loan asset | Unpredictable liquidation incentives | Do not list any ERC4626 vault as a loan asset |
| Ignoring vault governance | Owner/curator can reallocate to risky markets | Audit role holders; document trust assumptions to users |
Safety Notes
Addresses: Discover via GraphQL API or SDK fetch helpers. Present candidates to the user for confirmation before use. Never hardcode vault, market, or token addresses.
Chain: Always parameterize — accept chain as a function parameter. Never assume Ethereum or Base. Morpho is deployed on both chains at the same singleton address.
Write flow: All write operations follow: query → prepare → simulate → confirm → execute. Simulate transactions before execution to catch reverts early. The server returns unsigned transactions — your app handles signing.
Token decimals: USDC/USDT = 6, WETH/DAI = 18. Read decimals from the API or contract — never assume 18. Use parseUnits(amount, decimals) for conversion.
USDT approval quirk: Must reset allowance to 0 before setting a new value. Implement as a conditional check for USDT or as a general reset-before-set pattern.
DAI permit: Non-standard — use ERC-20 approve() instead of EIP-2612 permit.
Health factor: For borrow operations, validate the health factor after the intended borrow. Prevent proceeding if the position would become unsafe (health factor < 1.0). Warn at ~1.1.
Dead deposits: Any vault or market creation must include the dead deposit as the first transaction. See Protocol Mechanics > Dead Deposits above.
Testing
Detailed reference
@morpho-org/test — Vitest/Anvil fixtures for Morpho-specific test setup.
- See the testing guide for a full catalog of test cases covering vaults, markets, input validation, health factors, token approvals, signature security, and bad debt. Implementations should include these checks in their test suites.
Best Practices
Prefer @morpho-org/morpho-sdk for user-facing flows: MorphoClient centralizes slippage bounds, approvals / permits / Permit2 / GA1 authorization, LLTV-buffer health checks on borrow, and bundler routing. Only hand-roll these via @morpho-org/blue-sdk-viem + @morpho-org/bundler-sdk-viem when morpho-sdk does not expose the action (curator ops, market creation, liquidations, flashloans, rewards, custom bundler compositions). See SDK Selection above for the full coverage list.
Prefer vault v2 for new deployments: When creating new vaults, prefer vault v2 over MetaMorpho (v1). When interacting with existing vaults, match the ABI to the on-chain contract — vaultV2Abi for v2, metaMorphoAbi for v1. They are not interchangeable.
Prefer Morpho Blue over Morpho Optimizer: The original Morpho Optimizer (Morpho-Aave, Morpho-Compound) is deprecated. Prefer Morpho Blue contracts and SDKs for new integrations.
No Bundler3: Deprecated. Do not reference in new code.
ABIs: Always import from @morpho-org/blue-sdk-viem. Never hand-roll ABI JSON.
Post-Implementation Review
After finishing code or a plan, review it against these Morpho-specific checks before presenting the result. For each, mark CRITICAL (fund loss), WARNING (broken UX), or N/A.
- SDK Choice — standard user-facing flows (deposit, borrow, repay, withdraw, migrate, supply/withdraw collateral) use
@morpho-org/morpho-sdk (MorphoClient) rather than hand-rolled blue-sdk-viem + bundler-sdk-viem + simulation-sdk compositions. CRITICAL if the hand-rolled version skips a safeguard morpho-sdk would have applied (slippage bound, LLTV buffer on borrow, USDT allowance reset, GA1 authorization); WARNING if it is merely redundant re-implementation of covered flows.
- Dead Deposit Protection — vault/market creation includes dead deposit to
0xdead as the first tx; correct formula per version (reference)
- Slippage Protection — morpho-sdk handles tolerance automatically; when using lower-level SDKs directly, deposits/withdrawals use preview functions + tolerance check; full exits use
redeem() not withdraw(); no reliance on Vault V2 max* functions (reference)
- IRM Awareness — new markets seeded promptly; no sustained 100% utilization; APY formulas correct (reference)
- Bad Debt Safety — no V1.0 vault as collateral; no ERC4626 vault as loan asset; dashboards surface
lostAssets (reference)
- Token Approvals — USDT resets allowance to 0 first; DAI uses
approve() not permit() (morpho-sdk handles both automatically via its requirements flow; hand-rolled integrations must implement these) (reference)
- Vault Governance — UI surfaces role holders; trust assumptions documented (reference)
- General Safety — no hardcoded addresses; chain ID parameterized; decimals read not assumed; write ops simulate before execute; health factor validated; ABIs from
@morpho-org/blue-sdk-viem
- Test Coverage — implementation includes tests for relevant cases from the testing guide; edge cases (dead deposits, USDT approvals, health factor boundaries, full withdrawals via
redeem()) are covered