9.5 KiB
9.5 KiB
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>
部署内容:
- LendingFactory - 工厂合约
- Configurator Implementation - 配置管理实现合约
- Configurator Proxy - 配置管理代理合约
- Lending Implementation - 借贷池实现合约
步骤 2: 配置市场参数
运行配置脚本:
npx hardhat run scripts/deploy/08-configureLending.ts --network <network>
配置内容:
- 设置工厂合约地址
- 配置市场参数(利率模型、清算参数等)
- 添加抵押资产配置
- 部署 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
流程:
- 用户授权 USDC 给 Lending 合约
- 调用
supply()存入 USDC - 合约记录用户正余额
- 开始计息
2. 存入抵押品(Supply Collateral)
lending.supplyCollateral(WETH, 10 * 1e18); // 存入 10 ETH
流程:
- 用户授权抵押品(如 WETH)给 Lending 合约
- 调用
supplyCollateral()存入抵押品 - 合约记录用户抵押品余额
3. 借款(Borrow)
lending.borrow(5000 * 1e6); // 借出 5000 USDC
流程:
- 用户已存入足够的抵押品
- 调用
borrow()借出 USDC - 合约检查抵押品是否充足(根据 borrowCollateralFactor)
- 用户余额变为负数(表示借款)
- 开始计息
借款能力计算:
借款能力 = Σ(抵押品价值 × borrowCollateralFactor)
4. 取出资产(Withdraw)
lending.withdraw(500 * 1e6); // 取出 500 USDC
流程:
- 调用
withdraw()取出 USDC - 如果用户有借款,检查抵押品是否充足
- 转账 USDC 给用户
5. 取出抵押品(Withdraw Collateral)
lending.withdrawCollateral(WETH, 2 * 1e18); // 取出 2 ETH
流程:
- 调用
withdrawCollateral()取出抵押品 - 如果用户有借款,检查剩余抵押品是否充足
- 转账抵押品给用户
6. 清算(Absorb)
lending.absorb(borrowerAddress); // 清算借款人
触发条件:
债务 > Σ(抵押品价值 × liquidateCollateralFactor)
流程:
- 清算人调用
absorb()清算不良贷款 - 合约检查借款人是否可被清算
- 将借款人的债务清零
- 将借款人的抵押品转移到清算库存
7. 购买清算抵押品(Buy Collateral)
lending.buyCollateral(WETH, 1 * 1e18, 2000 * 1e6);
// 用 2000 USDC 购买至少 1 ETH
流程:
- 购买者调用
buyCollateral() - 按折扣价(storeFrontPriceFactor)计算可购买的抵押品数量
- 转账 USDC 给合约
- 转账抵押品给购买者
折扣价格计算:
折扣价 = 市场价 × 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(所有者)可以执行以下操作:
- 升级合约:调用
upgradeTo()升级 Lending 或 Configurator - 暂停/恢复:调用
pause()/unpause()暂停或恢复合约 - 配置市场:通过 Configurator 修改市场参数
- 转移所有权:调用
transferOwnership()转移 Owner
推荐配置
建议使用多签钱包(如 Gnosis Safe)作为 Owner:
// 部署后转移所有权到多签
await lending.transferOwnership(GNOSIS_SAFE_ADDRESS);
await configurator.transferOwnership(GNOSIS_SAFE_ADDRESS);
安全注意事项
⚠️ 关键风险
- 价格预言机风险:依赖外部价格源,需确保价格源可靠
- 清算延迟风险:市场剧烈波动时可能来不及清算
- Owner 权限过大:Owner 拥有所有管理权限,需使用多签
🔒 安全建议
- 使用多签钱包:将 Owner 设为 Gnosis Safe 等多签钱包
- 设置合理参数:
borrowCollateralFactor<liquidateCollateralFactor- 合理的清算折扣(storeFrontPriceFactor)
- 适当的 supplyCap 防止单一资产风险过大
- 监控系统:实时监控抵押率,及时清算
- 价格源多样化:考虑使用多个价格源取平均
升级流程
使用 upgrades 插件升级(推荐)
运行升级脚本:
npx hardhat run scripts/deploy/09-upgradeLending.ts --network <network>
脚本特性:
- ✅ 自动验证存储布局兼容性
- ✅ 自动部署新实现合约
- ✅ 自动更新代理指向
- ✅ 保留所有状态数据
修改升级目标:
// 在 09-upgradeLending.ts 中修改
const UPGRADE_LENDING = true; // true = 升级 Lending, false = 升级 Configurator
手动 UUPS 升级步骤(不推荐)
如果需要手动升级:
- 部署新实现合约:
const NewLending = await ethers.getContractFactory("LendingV2");
const newImpl = await NewLending.deploy();
- 升级代理:
await lending.upgradeTo(newImpl.address);
注意事项
- ✅ 只有 Owner 可以升级
- ✅ 必须保持存储布局一致
- ✅ 只能在末尾添加新存储变量
- ⚠️ 升级前在测试网充分测试
- 🔧 推荐使用 upgrades 插件,它会自动验证兼容性
监控指标
关键指标
- 利用率:
totalBorrow / totalSupply - 供应利率:
getSupplyRate() - 借款利率:
getBorrowRate() - 储备金:
reserves - 清算库存:
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 治理)
- 需要可靠的价格预言机