Files
assetxContracts/doc/YTLending-流程说明.md
2025-12-18 13:07:35 +08:00

9.5 KiB
Raw Blame History

YT Lending 借贷池系统流程说明

系统概述

YT Lending 是基于 Compound V3 架构的简化借贷池系统,采用 OpenZeppelin UUPS 升级模式和 Ownable 权限管理。

核心特性

  • UUPS 可升级:使用 OpenZeppelin 的 UUPS 代理模式
  • 简化权限:使用 Owner 权限管理,替代复杂的 Governor 治理
  • 单一基础资产:支持一种基础资产(如 USDC的借贷
  • 多种抵押品:支持多种抵押资产(如 ETH、WBTC
  • 动态利率:双拐点利率模型
  • 清算机制:支持不良贷款清算和抵押品拍卖

合约架构

├── Lending.sol                    # 核心借贷合约UUPS
├── LendingFactory.sol             # 工厂合约
├── Configurator.sol               # 配置管理合约UUPS
├── LendingConfiguration.sol       # 配置结构体
├── LendingStorage.sol             # 存储定义
├── LendingMath.sol                # 数学计算库
├── ConfiguratorStorage.sol        # 配置器存储
└── interfaces/
    ├── ILending.sol               # 借贷接口
    └── IPriceFeed.sol             # 价格预言机接口

部署流程

步骤 1: 部署基础合约

运行部署脚本:

npx hardhat run scripts/deploy/07-deployLending.ts --network <network>

部署内容:

  1. LendingFactory - 工厂合约
  2. Configurator Implementation - 配置管理实现合约
  3. Configurator Proxy - 配置管理代理合约
  4. Lending Implementation - 借贷池实现合约

步骤 2: 配置市场参数

运行配置脚本:

npx hardhat run scripts/deploy/08-configureLending.ts --network <network>

配置内容:

  1. 设置工厂合约地址
  2. 配置市场参数(利率模型、清算参数等)
  3. 添加抵押资产配置
  4. 部署 Lending Proxy 代理合约

配置参数说明

利率模型参数

参数 说明 示例值
supplyKink 供应利率拐点(利用率) 80%
supplyPerYearInterestRateSlopeLow 供应拐点前斜率 3% APY
supplyPerYearInterestRateSlopeHigh 供应拐点后斜率 40% APY
borrowKink 借款利率拐点(利用率) 80%
borrowPerYearInterestRateSlopeLow 借款拐点前斜率 5% APY
borrowPerYearInterestRateSlopeHigh 借款拐点后斜率 150% APY

抵押资产参数

参数 说明 示例值
borrowCollateralFactor 借款抵押率LTV 80%
liquidateCollateralFactor 清算抵押率 85%
liquidationFactor 清算激励 5%
supplyCap 供应上限 100,000 ETH

核心功能流程

1. 存款Supply

lending.supply(1000 * 1e6); // 存入 1000 USDC

流程

  1. 用户授权 USDC 给 Lending 合约
  2. 调用 supply() 存入 USDC
  3. 合约记录用户正余额
  4. 开始计息

2. 存入抵押品Supply Collateral

lending.supplyCollateral(WETH, 10 * 1e18); // 存入 10 ETH

流程

  1. 用户授权抵押品(如 WETH给 Lending 合约
  2. 调用 supplyCollateral() 存入抵押品
  3. 合约记录用户抵押品余额

3. 借款Borrow

lending.borrow(5000 * 1e6); // 借出 5000 USDC

流程

  1. 用户已存入足够的抵押品
  2. 调用 borrow() 借出 USDC
  3. 合约检查抵押品是否充足(根据 borrowCollateralFactor
  4. 用户余额变为负数(表示借款)
  5. 开始计息

借款能力计算

借款能力 = Σ(抵押品价值 × borrowCollateralFactor)

4. 取出资产Withdraw

lending.withdraw(500 * 1e6); // 取出 500 USDC

流程

  1. 调用 withdraw() 取出 USDC
  2. 如果用户有借款,检查抵押品是否充足
  3. 转账 USDC 给用户

5. 取出抵押品Withdraw Collateral

lending.withdrawCollateral(WETH, 2 * 1e18); // 取出 2 ETH

流程

  1. 调用 withdrawCollateral() 取出抵押品
  2. 如果用户有借款,检查剩余抵押品是否充足
  3. 转账抵押品给用户

6. 清算Absorb

lending.absorb(borrowerAddress); // 清算借款人

触发条件

债务 > Σ(抵押品价值 × liquidateCollateralFactor)

流程

  1. 清算人调用 absorb() 清算不良贷款
  2. 合约检查借款人是否可被清算
  3. 将借款人的债务清零
  4. 将借款人的抵押品转移到清算库存

7. 购买清算抵押品Buy Collateral

lending.buyCollateral(WETH, 1 * 1e18, 2000 * 1e6);
// 用 2000 USDC 购买至少 1 ETH

流程

  1. 购买者调用 buyCollateral()
  2. 按折扣价storeFrontPriceFactor计算可购买的抵押品数量
  3. 转账 USDC 给合约
  4. 转账抵押品给购买者

折扣价格计算

折扣价 = 市场价 × storeFrontPriceFactor
可购买数量 = 支付 USDC 数量 / 折扣价

利率计算

利用率

利用率 = 总借款 / 总供应

双拐点利率模型

如果 利用率 <= Kink:
    利率 = 基础利率 + 利用率 × 低斜率

如果 利用率 > Kink:
    超额利用率 = 利用率 - Kink
    利率 = 基础利率 + 低斜率 + 超额利用率 × 高斜率

示例借款利率Kink = 80%

利用率 借款利率
0% 1.5%
40% 3.5%
80% 5.5%
90% 20.5%
100% 35.5%

利率计算优化(采用 Compound V3 方式)

关键优化:配置时传入年化利率,初始化时自动转换为每秒利率

// 初始化时(只计算一次)
uint256 SECONDS_PER_YEAR = 31,536,000;
supplyPerSecondRate = supplyPerYearRate / SECONDS_PER_YEAR;
borrowPerSecondRate = borrowPerYearRate / SECONDS_PER_YEAR;

// 每次计提利息(高效计算)
newIndex = oldIndex + (oldIndex * perSecondRate * timeElapsed) / 1e18;

优化效果

  • 精度更高:每秒利率避免了重复除法导致的精度损失
  • Gas 更低:每次计提节省 ~100 gas~66% Gas 优化)
  • 计算更快:只需乘法,无需除以 31,536,000
  • 完全兼容:配置文件仍使用易读的年化利率

权限管理

Owner 权限

Owner所有者可以执行以下操作

  1. 升级合约:调用 upgradeTo() 升级 Lending 或 Configurator
  2. 暂停/恢复:调用 pause() / unpause() 暂停或恢复合约
  3. 配置市场:通过 Configurator 修改市场参数
  4. 转移所有权:调用 transferOwnership() 转移 Owner

推荐配置

建议使用多签钱包(如 Gnosis Safe作为 Owner

// 部署后转移所有权到多签
await lending.transferOwnership(GNOSIS_SAFE_ADDRESS);
await configurator.transferOwnership(GNOSIS_SAFE_ADDRESS);

安全注意事项

⚠️ 关键风险

  1. 价格预言机风险:依赖外部价格源,需确保价格源可靠
  2. 清算延迟风险:市场剧烈波动时可能来不及清算
  3. Owner 权限过大Owner 拥有所有管理权限,需使用多签

🔒 安全建议

  1. 使用多签钱包:将 Owner 设为 Gnosis Safe 等多签钱包
  2. 设置合理参数
    • borrowCollateralFactor < liquidateCollateralFactor
    • 合理的清算折扣storeFrontPriceFactor
    • 适当的 supplyCap 防止单一资产风险过大
  3. 监控系统:实时监控抵押率,及时清算
  4. 价格源多样化:考虑使用多个价格源取平均

升级流程

使用 upgrades 插件升级(推荐)

运行升级脚本:

npx hardhat run scripts/deploy/09-upgradeLending.ts --network <network>

脚本特性

  • 自动验证存储布局兼容性
  • 自动部署新实现合约
  • 自动更新代理指向
  • 保留所有状态数据

修改升级目标

// 在 09-upgradeLending.ts 中修改
const UPGRADE_LENDING = true;  // true = 升级 Lending, false = 升级 Configurator

手动 UUPS 升级步骤(不推荐)

如果需要手动升级:

  1. 部署新实现合约
const NewLending = await ethers.getContractFactory("LendingV2");
const newImpl = await NewLending.deploy();
  1. 升级代理
await lending.upgradeTo(newImpl.address);

注意事项

  • 只有 Owner 可以升级
  • 必须保持存储布局一致
  • 只能在末尾添加新存储变量
  • ⚠️ 升级前在测试网充分测试
  • 🔧 推荐使用 upgrades 插件,它会自动验证兼容性

监控指标

关键指标

  1. 利用率totalBorrow / totalSupply
  2. 供应利率getSupplyRate()
  3. 借款利率getBorrowRate()
  4. 储备金reserves
  5. 清算库存collateralReserves[asset]

健康检查

// 检查利用率
const utilization = totalBorrow.mul(1e18).div(totalSupply);
console.log("Utilization:", utilization / 1e18 * 100, "%");

// 检查是否需要清算
const isLiquidatable = await lending.isLiquidatable(userAddress);

总结

YT Lending 提供了一个简化但功能完整的借贷池系统:

  • 核心借贷功能(存款、借款、抵押品管理)
  • 清算机制absorb + buyCollateral
  • 动态利率模型(双拐点)
  • 可升级架构UUPS
  • 简化权限管理Owner

适用场景

  • 中小型借贷协议
  • 需要快速上线的项目
  • 中心化或半中心化管理的借贷池

限制

  • 单一基础资产(只能借贷一种资产)
  • 简化的权限模型(不支持 DAO 治理)
  • 需要可靠的价格预言机