关于 morpho-builder
morpho-builder 是面向将 Morpho 借贷协议集成到应用中的开发者的参考技能,涵盖协议实体与 SDK 选择。它强调区分 Vault v1 与 v2 的 ABI,并优先使用高层 SDK 处理用户交易流程。
主要功能
- 01Morpho Blue 与 Vault 架构说明
- 02提供 SDK 选型指导
- 03涵盖存取款、借贷与还款流程
- 04说明 v1 与 v2 ABI 差异
- 05介绍读取链上状态与交易构建
适用场景
- 01构建 Morpho 借贷应用
- 02实现 Vault 存款、提款或迁移
- 03开发市场抵押与借贷操作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ morpho-org/ morpho-skills --skill morpho-builder安装后在 Claude Code 中输入/morpho-builder确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/adaptive-curve-irm.mdbad-debt.mdcommon-pitfalls.mddead-deposits.mdslippage.mdtesting-guide.md详细介绍
Morpho Builder 技能
实验性(pre-v1.0) — 随着协议工具日趋成熟,SDK 建议、API 架构和最佳实践可能会有所变化。
用于构建集成 Morpho 借贷协议的应用的参考指南。若要直接通过对话操作该协议,请改用 morpho-cli 技能。
优先使用 Morpho v2。 Morpho Optimizer(Morpho-Aave、Morpho-Compound)已弃用。部署新金库时,优先选择 vault v2,而非 MetaMorpho(vault v1)。注意:两个金库版本的 ABI 不兼容 — v2 金库使用
vaultV2Abi,v1 金库使用metaMorphoAbi。ABI 必须与链上合约匹配。
协议概览
Morpho Blue — 隔离借贷市场。每个市场由五个参数定义:借款代币、抵押品代币、预言机、利率模型(IRM)和清算 LTV(LLTV)。市场由 MarketId 标识(这些参数的哈希值)。
Morpho Vaults v2 — 较新的金库合约,符合 ERC-4626 标准。通过适配器将存款分配到多个市场;适配器可以封装 MetaMorpho(v1)金库和 Morpho Blue 市场。新部署的金库优先采用此版本。SDK 中使用:vaultV2Abi、VaultV2、fetchVaultV2。
MetaMorpho(vault v1) — 原始金库合约。仍可正常使用,并已广泛部署到链上。SDK 中使用:metaMorphoAbi、Vault、fetchVault。两个金库版本的 ABI 不兼容 — 请根据交互的合约使用正确的 ABI。
单例合约:0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb — 通过 CREATE2 在 Ethereum(chain 1)和 Base(chain 8453)上的地址相同。
关键实体
| 实体 | 标识符 | 描述 |
|---|---|---|
| 市场 | MarketId | 具有特定抵押品/借款代币对的隔离借贷池 |
| 金库 | Address | 多市场聚合器,符合 ERC-4626 标准。有两个版本:v2(VaultV2)和 MetaMorpho v1(Vault)— ABI 不同 |
| 仓位 | 用户 + 市场/金库 | 用户在市场中的供应/借款,或在金库中的存款 |
| 代币 | Address + decimals | ERC-20 — 小数位数各不相同(USDC/USDT = 6,WETH/DAI = 18) |
关键数量
| 数量 | 格式 | 说明 |
|---|---|---|
| APY | 十进制数(0.0534 = 5.34%) | 来自 GraphQL state.netApy |
| LLTV | 原始 1e18(860000000000000000 = 86%) | 来自 SDK 或 API |
| 代币数量 | 原始单位 | 除以 10^decimals 转换为人类可读的数值。使用 viem 中的 parseUnits/formatUnits |
| 健康因子 | 比率 | ≥ 1.0 = 安全,< 1.0 = 可清算 |
SDK 选择
面向用户的流程默认使用 @morpho-org/morpho-sdk。 它是一个高层抽象层,封装了 blue-sdk、blue-sdk-viem、bundler-sdk-viem 和 simulation-sdk,并在内部处理打包器与直接调用之间的路由、滑点界限、借款时的 LLTV 缓冲健康检查、ERC-20 授权 / EIP-2612 许可 / Permit2 / Morpho setAuthorization 要求,以及原生代币包装。用较低层级的 SDK 手动实现这些逻辑容易出错,也会重复 morpho-sdk 已经正确处理的逻辑。
使用 morpho-sdk 进行: 金库存入 / 提取 / 赎回(V1 和 V2)、VaultV2 强制提取 / 强制赎回、V1→V2 迁移、Morpho Blue supplyCollateral、borrow(可选使用 PublicAllocator 重新分配)、原子化 supplyCollateralBorrow、repay(按资产或份额)、withdrawCollateral、原子化 repayWithdrawCollateral,以及按实体读取(getData、getMarketData、getPositionData)。
仅在以下情况使用较低层级的 SDK:
- 金库的策展人 / 分配器 / 所有者操作(setCap、重新分配、角色管理、时间锁、guardian/sentinel 流程)
- 创建 Morpho Blue 市场
- 清算、闪电贷、预清算、奖励领取
- 上述操作列表之外的自定义打包器组合
- 跨多个市场 / 金库的全组合聚合(morpho-sdk 仅提供按实体读取——请使用
blue-sdk-viem获取数据的辅助函数或 GraphQL API)
React / wagmi 应用: 没有 @morpho-org/morpho-sdk-wagmi 这个包。读取时请使用 @morpho-org/blue-sdk-wagmi hooks;写入时请针对 wagmi 公共客户端实例化 MorphoClient,并将 buildTx 的输出传递给 wagmi 的 useSendTransaction。
SDK 注册表
所有包均以 @morpho-org 名称发布在 npm 上。
| 包 | 用途 |
|---|---|
@morpho-org/morpho-sdk | 从这里开始。 封装下方四个 SDK 的高层抽象。构建面向用户的交易(存入、借款、还款、提取、迁移),并在内部处理滑点、授权、许可和打包器路由 |
@morpho-org/blue-sdk | 核心类型、实体类(Market、Vault、VaultV2、Position、MarketParams)和常量。由 morpho-sdk 在内部使用;仅在需要导入类型或处理未覆盖的流程时直接使用 |
@morpho-org/blue-sdk-viem | Viem 扩展——ABI、获取数据的辅助函数(fetchMarket、fetchVault、fetchVaultV2、fetchPosition)。由 morpho-sdk 在内部使用;仅在需要 ABI、多实体读取或处理未覆盖的写入流程时直接使用 |
@morpho-org/bundler-sdk-viem | 多步骤交易打包(在一个 tx 中执行授权、转账、Morpho 操作)。由 morpho-sdk 在内部使用;仅在需要 morpho-sdk 操作集之外的自定义组合时直接使用 |
@morpho-org/simulation-sdk | 与框架无关的 Morpho 操作模拟。由 morpho-sdk 在内部使用;仅在需要独立的假设情景模拟时直接使用 |
@morpho-org/blue-sdk-ethers | Ethers 扩展——提供与 viem 相同的获取数据辅助函数,适用于基于 Ethers 的项目 |
@morpho-org/blue-sdk-wagmi | React hooks(useMarket、useVault、usePosition 等),封装核心 SDK。需要 wagmi v2。写入操作请与 morpho-sdk 搭配使用 |
@morpho-org/blue-api-sdk | GraphQL SDK,提供适用于 Morpho API 的类型化查询 |
@morpho-org/simulation-sdk-wagmi | 用于客户端模拟的 React hooks(useSimulationState) |
@morpho-org/liquidity-sdk-viem | 流动性监控和机器人基础设施 |
@morpho-org/liquidation-sdk-viem | 清算机器人基础设施 |
@morpho-org/migration-sdk-viem | 从 Aave/Compound 迁移到 Morpho |
@morpho-org/morpho-ts | 时间和格式工具 |
@morpho-org/test | 用于 Morpho 的 Vitest/Anvil 测试固件 |
@morpho-org/test-wagmi | @morpho-org/test 的 Wagmi 测试配置扩展 |
@morpho-org/morpho-test | 与框架无关的测试固件 |
SDK 详情
@morpho-org/morpho-sdk
高层抽象。面向用户流程的默认入口。
构造——有两种等效形式:new MorphoClient(publicClient) 会返回直接客户端;publicClient.extend(morphoViemExtension()) 则会将 API 挂载到 viem 公共客户端的 .morpho 下。
实体工厂——都需要 chainId(Ethereum 为 1,Base 为 8453):
| 工厂 | 返回值 | 用途 |
|---|---|---|
morpho.vaultV2(address, chainId) | MorphoVaultV2 | Vault V2(新部署首选) |
morpho.vaultV1(address, chainId) | MorphoVaultV1 | MetaMorpho(vault v1) |
morpho.marketV1(marketParams, chainId) | MorphoMarketV1 | Morpho Blue 市场 |
读取——每个实体都提供 getData(),并在适用时提供 getMarketData() / getPositionData(user)。返回构建操作所需的实时链上状态。
操作——每个操作都会返回 { buildTx, getRequirements }:
| 实体 | 操作 |
|---|---|
MorphoVaultV2 | deposit、withdraw、redeem、forceWithdraw、forceRedeem |
MorphoVaultV1 | deposit、withdraw、redeem、migrateToV2 |
MorphoMarketV1 | supplyCollateral、borrow、repay、withdrawCollateral、supplyCollateralBorrow、repayWithdrawCollateral,以及供 PublicAllocator 使用的 getReallocationData / getReallocations |
规范写入流程:
- 构造
MorphoClient和实体(vault 或市场)。 - 获取实时状态:
await entity.getData()(vault)或await market.getMarketData()+await market.getPositionData(user)(市场)。 - 调用操作:
const { buildTx, getRequirements } = await entity.deposit({ amount, userAddress, accrualVault })。 - 解析所需项:
const reqs = await getRequirements()——返回所需的 ERC-20 授权、EIP-2612 许可、Permit2 数据和/或morpho.setAuthorization(GA1, true)步骤。 - 根据所需项的要求签署许可/发送授权交易。
- 构建并发送:
const tx = buildTx(requirementSignatures)→{ to, value, data, action }→ 签名并广播。
说明:
- 滑点——morpho-sdk 会根据链上状态自动计算
maxSharePrice/minSharePrice边界。默认容差为 3 bps,上限为 10%。需要更严格或更宽松的边界时,可通过操作的滑点选项进行覆盖。 - 借款健康度——
borrow和supplyCollateralBorrow会根据你传入的仓位快照自动应用 LLTV 缓冲。调用借款操作前,务必立即获取最新的positionData。 - 原生 ETH——为存款/借款操作传入
nativeAmount,即可在单笔交易中原子化地包装并供应。 - 分析——每个操作都可选填
metadata字段,用于为交易添加归因标签。 - 无 wagmi 封装——morpho-sdk 仅支持 viem。在 React 中,针对 wagmi 公共客户端(
usePublicClient())构造MorphoClient,并将buildTx的输出传给useSendTransaction。
@morpho-org/blue-sdk
类型、实体类和常量。
Market——包含操作方法(.supply()、.borrow()、.repay()、.withdraw())和转换方法(.toSupplyAssets()、.toBorrowAssets())的类MarketParams——new MarketParams({ loanToken, collateralToken, oracle, irm, lltv })MarketId——标识市场的品牌类型Position——new Position({ supplyShares, borrowShares, collateral })VaultV2——vault v2 实体类(新集成首选)Vault——MetaMorpho(vault v1)实体类VaultConfig——MetaMorpho vault 的配置类
@morpho-org/blue-sdk-viem
ABI、获取辅助函数和 viem 扩展。
ABI 目录 — 请导入这些 ABI,而不是手动编写 ABI JSON:
| 导出项 | 合约 |
|---|---|
blueAbi | Morpho Blue 单例 |
vaultV2Abi | Vault v2(新部署首选) |
vaultV2FactoryAbi | Vault v2 工厂 |
metaMorphoAbi | MetaMorpho / vault v1(用于现有的 v1 vault) |
metaMorphoFactoryAbi | MetaMorpho 工厂 / vault v1 |
erc2612Abi | ERC-2612 permit |
permit2Abi | Uniswap Permit2 |
wstEthAbi | Wrapped stETH |
adaptiveCurveIrmAbi | Morpho 的自适应曲线 IRM |
blueOracleAbi | Morpho 预言机 |
获取辅助函数 — fetchMarket、fetchVaultV2(v2)/ fetchVault(v1)、fetchPosition 会将链上状态读取为 SDK 实体对象。请根据链上 vault 版本使用对应的获取辅助函数。实体方法包括 market.toSupplyAssets()、vault.toShares() 等。
@morpho-org/blue-sdk-wagmi
封装核心 SDK 的 React hooks。需要 wagmi v2。
Hooks:useMarket、useVault、usePosition、useToken、useHolding、useMarkets、useVaults、usePositions、useTokens、useHoldings、useVaultMarketConfig、useVaultMarketConfigs、useVaultUser、useVaultUsers、useMarketParams,以及对应的复数形式。
@morpho-org/simulation-sdk + @morpho-org/simulation-sdk-wagmi
在客户端模拟 Morpho 操作。useSimulationState hook 会提供模拟的操作后状态,用于在 UI 中预览,而无需提交交易。
GraphQL API
端点:https://api.morpho.org/graphql
主要查询:vaults(字段:address、name、symbol、asset、state.netApy、state.totalAssets)和 markets(字段:uniqueKey、loanAsset、collateralAsset、state.supplyApy、state.borrowApy、state.utilization、lltv)。
筛选与分页
| 筛选条件 | 示例 | 说明 |
|---|---|---|
chainId_in | [1]、[8453]、[1, 8453] | 必填 — 始终指定链 |
assetSymbol_in | ["USDC"] | 按资产符号筛选 |
address_in | ["0x..."] | 按 vault 地址筛选 |
uniqueKey_in | ["0x..."] | 按市场 ID 筛选 |
userAddress_in | ["0x..."] | 筛选用户的头寸 |
使用 first 和 skip 进行分页。循环获取,直到 items.length < first。
数值解读
| 字段 | 格式 | 转换方式 |
|---|---|---|
netApy / supplyApy / borrowApy | 十进制数 | 0.0534 = 5.34% |
totalAssets | 原始字符串 | 除以 10^asset.decimals |
lltv | 原始 1e18 字符串 | 除以 1e18 得到百分比 |
集成方式
- 后端 / 脚本 / 机器人(viem) — 默认使用
@morpho-org/morpho-sdk中的MorphoClient(publicClient)。仅在需要读取大量实体,或执行 morpho-sdk 未提供的操作时,才直接使用@morpho-org/blue-sdk-viem的获取辅助函数和 ABI。 - 前端(React + wagmi) — 使用
@morpho-org/blue-sdk-wagmihooks(useVault、usePosition等)进行响应式读取。写入时,基于usePublicClient()构造MorphoClient,使用 morpho-sdk 构建交易,再通过 wagmi 的useSendTransaction提交。不存在@morpho-org/morpho-sdk-wagmi。 - 进阶操作(curator 运维、创建市场、清算、闪电贷、奖励) — morpho-sdk 不支持这些操作。请将
@morpho-org/blue-sdk-viemABI 与对应的子 SDK 配合使用:@morpho-org/liquidation-sdk-viem、@morpho-org/liquidity-sdk-viem或@morpho-org/migration-sdk-viem。
协议机制
死亡存款(通胀攻击防护)
ERC-4626 金库容易在首次存款时遭受份额价格通胀攻击。死亡存款——将份额铸造到销毁地址 0x000000000000000000000000000000000000dEaD——必须是任何新金库或市场的第一笔交易。任何用户存款若早于此操作,都会导致攻击成为可能。
Vault V2 — 目标份额取决于资产的小数位数:
公式:targetShares = max(1e9, 10^(6 + max(0, 18 - decimals))) — 18 位小数资产:1e9,8 位:1e16,6 位:1e18。调用 vault.mint(TARGET_SHARES, 0xdead)。
Market V1 — 固定为 1e9 份额,与小数位数无关。调用 morpho.supply(marketParams, 0, 1e9, 0xdead, "")。
Vault V1 — 标准值为 1e9 份额;对于小数位数少于 9 位的代币,使用 1e12。
活跃上限要求:当 Vault V2 引用底层市场/金库时,0xdead 还必须持有:
- 每个非零金库上限的 Market V1 中
1e9supplyShares - 每个具有非零上限或出现在提款队列中的 Vault V1 中
1e9份额
AdaptiveCurveIRM
Morpho 批准的 IRM 使用双重机制:
- 曲线 — 在利用率变化时即时调整利率(例如,利用率从 90% ↔ 0% 时,利率乘以 4 或除以 4)
- 自适应 — 根据持续的利用率,随时间不断调整目标利率
| 利用率 | 利率变化 |
|---|---|
| 0% | 每约 5 天减半 |
| 90%(目标) | 稳定 |
| 100% | 每约 5 天翻倍 |
操作警告:避免 100% 利用率——利率会快速复利增长。创建市场后立即为其注入初始供应;空市场处于 0% 利用率时会触发自动利率衰减。
滑点与份额/资产转换
资产与份额之间的兑换率可能会在交易准备与链上执行之间发生变化。正确进行死亡存款后,这属于用户体验问题,而非安全漏洞,但集成仍应保护用户。
**防御模式:**使用 @morpho-org/morpho-sdk 时,滑点界限(maxSharePrice / minSharePrice,默认为 3 bps,上限为 10%)会自动计算并应用——无需手动编写预览和容差逻辑。只有直接使用 blue-sdk-viem / bundler-sdk-viem 时,才需要自行实现该模式:调用 previewDeposit() 估算份额,应用容差下限(例如 1%),并验证实际结果达到最低要求。
全额提款:使用 redeem(),而不是 withdraw()——避免留下零头。
Vault V2 的特殊情况:maxDeposit、maxMint、maxWithdraw 和 maxRedeem 始终返回零。不要依赖它们进行容量检查。
坏账跟踪
- V1.0:立即实现——受影响市场中所有供应者的份额价格会原子性地下跌。坏账实现容易受到闪电贷放大攻击。
- V1.1+:通过
lostAssets字段跟踪——在显式实现之前,份额价格不受影响。可防止闪电贷操纵。
常见陷阱
| 陷阱 | 后果 | 预防措施 |
|---|---|---|
| 缺少销毁地址存款 | 通胀攻击/份额价格操纵 | 在任何用户存款之前,先向 0xdead 注入种子份额 |
完全退出时使用 withdraw() | 仓位中残留尘埃金额 | 完全退出时使用 redeem() |
| 忽视预言机风险 | 使用过时或遭操纵的价格进行清算 | 集成市场之前,检查预言机类型、数据时效性和已知风险 |
| 将 ERC4626 金库用作抵押品 | 份额价格操纵(类似 Cream-hack) | 避免将 V1.0 金库用作抵押品;不实现坏账确认的 V1.1+ 更安全 |
| 将 ERC4626 金库用作贷款资产 | 清算激励不可预测 | 不要将任何 ERC4626 金库列为贷款资产 |
| 忽视金库治理 | 所有者/策展人可以将资金重新分配到高风险市场 | 审查角色持有者;向用户说明信任假设 |
安全注意事项
地址:通过 GraphQL API 或 SDK 获取辅助函数发现地址。使用前,向用户展示候选地址以供确认。切勿对金库、市场或代币地址进行硬编码。
链:始终将链设为参数——将链作为函数参数传入。切勿假定为 Ethereum 或 Base。Morpho 在这两条链上都部署于相同的单例地址。
写入流程:所有写入操作都遵循:查询 → 准备 → 模拟 → 确认 → 执行。执行前模拟交易,以便尽早发现回滚。服务会返回未签名交易——由你的应用负责签名。
代币小数位数:USDC/USDT = 6,WETH/DAI = 18。从 API 或合约读取 decimals——切勿假定为 18。使用 parseUnits(amount, decimals) 进行转换。
USDT 授权注意事项:设置新额度前必须先将额度重置为 0。针对 USDT 实现条件检查,或采用通用的先重置再设置模式。
DAI permit:采用非标准实现——使用 ERC-20 approve(),而不是 EIP-2612 permit。
健康因子:对于借款操作,在计划借款后验证健康因子。如果仓位会变得不安全(健康因子 < 1.0),则阻止继续操作。健康因子约为 1.1 时发出警告。
销毁地址存款:创建任何金库或市场时,都必须将销毁地址存款作为第一笔交易。参见上文的 协议机制 > 销毁地址存款。
测试
@morpho-org/test— 用于 Morpho 专项测试设置的 Vitest/Anvil 固定配置。- 完整测试用例目录请参见测试指南,涵盖金库、市场、输入验证、健康因子、代币授权、签名安全和坏账。实现应在测试套件中包含这些检查。
最佳实践
面向用户的流程优先使用 @morpho-org/morpho-sdk:MorphoClient 集中处理滑点界限、授权/permit/Permit2/GA1 授权、借款时的 LLTV 缓冲健康检查,以及打包器路由。只有在 morpho-sdk 未提供相应操作(策展人操作、市场创建、清算、闪电贷、奖励、自定义打包器组合)时,才通过 @morpho-org/blue-sdk-viem + @morpho-org/bundler-sdk-viem 手动实现。完整支持列表请参见上文的 SDK 选择。
新部署优先使用 vault v2:创建新金库时,优先选择 vault v2,而不是 MetaMorpho(v1)。与现有金库交互时,应使 ABI 与链上合约相匹配——v2 使用 vaultV2Abi,v1 使用 metaMorphoAbi。二者不可互换。
优先使用 Morpho Blue,而不是 Morpho Optimizer:原始的 Morpho Optimizer(Morpho-Aave、Morpho-Compound)已弃用。新集成应优先使用 Morpho Blue 合约和 SDK。
不使用 Bundler3:已弃用。新代码中不要引用。
ABI:始终从 @morpho-org/blue-sdk-viem 导入。切勿手动编写 ABI JSON。
实现后审查
完成代码或计划后,在呈现结果前,按以下 Morpho 专项检查项进行审查。每项标记为 CRITICAL(资金损失)、WARNING(用户体验受损)或 N/A。
- SDK 选择 — 面向用户的标准流程(存款、借款、还款、取款、迁移、提供/取回抵押品)应使用
@morpho-org/morpho-sdk(MorphoClient),而不是手动组合blue-sdk-viem、bundler-sdk-viem和simulation-sdk。如果手动实现跳过了 morpho-sdk 原本会应用的安全措施(滑点上限、借款时的 LLTV 缓冲、USDT 授权重置、GA1 授权),则标记为 CRITICAL;如果只是重复实现已覆盖的流程,则标记为 WARNING。 - 死地址存款保护 — 金库/市场创建时,第一笔交易应向
0xdead存入死地址存款;使用与版本对应的正确公式(参考) - 滑点保护 — morpho-sdk 会自动处理容差;直接使用底层 SDK 时,存款/取款应使用预览函数并进行容差检查;全部退出时使用
redeem(),而不是withdraw();不得依赖 Vault V2 的max*函数(参考) - IRM 注意事项 — 新市场应及时注入流动性;不得持续维持 100% 的利用率;APY 公式应正确(参考)
- 坏账安全 — 不得将 V1.0 金库用作抵押品;不得将 ERC4626 金库用作贷款资产;仪表板应展示
lostAssets(参考) - 代币授权 — USDT 应先将授权额度重置为 0;DAI 使用
approve(),而不是permit()(morpho-sdk 会通过其需求流程自动处理两者;手动实现的集成必须自行实现这些操作)(参考) - 金库治理 — UI 应展示角色持有者;应记录信任假设(参考)
- 通用安全 — 不得硬编码地址;链 ID 应参数化;应读取小数位数,不得依赖假设值;执行写入操作前应先模拟;应验证健康因子;ABI 应来自
@morpho-org/blue-sdk-viem - 测试覆盖 — 实现应包含测试指南中相关用例的测试;应覆盖边界情况(死地址存款、USDT 授权、健康因子边界、通过
redeem()全额取款)