# 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: 部署基础合约 运行部署脚本: ```bash npx hardhat run scripts/deploy/07-deployLending.ts --network ``` 部署内容: 1. **LendingFactory** - 工厂合约 2. **Configurator Implementation** - 配置管理实现合约 3. **Configurator Proxy** - 配置管理代理合约 4. **Lending Implementation** - 借贷池实现合约 ### 步骤 2: 配置市场参数 运行配置脚本: ```bash npx hardhat run scripts/deploy/08-configureLending.ts --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) ```solidity lending.supply(1000 * 1e6); // 存入 1000 USDC ``` **流程**: 1. 用户授权 USDC 给 Lending 合约 2. 调用 `supply()` 存入 USDC 3. 合约记录用户正余额 4. 开始计息 ### 2. 存入抵押品(Supply Collateral) ```solidity lending.supplyCollateral(WETH, 10 * 1e18); // 存入 10 ETH ``` **流程**: 1. 用户授权抵押品(如 WETH)给 Lending 合约 2. 调用 `supplyCollateral()` 存入抵押品 3. 合约记录用户抵押品余额 ### 3. 借款(Borrow) ```solidity lending.borrow(5000 * 1e6); // 借出 5000 USDC ``` **流程**: 1. 用户已存入足够的抵押品 2. 调用 `borrow()` 借出 USDC 3. 合约检查抵押品是否充足(根据 borrowCollateralFactor) 4. 用户余额变为负数(表示借款) 5. 开始计息 **借款能力计算**: ``` 借款能力 = Σ(抵押品价值 × borrowCollateralFactor) ``` ### 4. 取出资产(Withdraw) ```solidity lending.withdraw(500 * 1e6); // 取出 500 USDC ``` **流程**: 1. 调用 `withdraw()` 取出 USDC 2. 如果用户有借款,检查抵押品是否充足 3. 转账 USDC 给用户 ### 5. 取出抵押品(Withdraw Collateral) ```solidity lending.withdrawCollateral(WETH, 2 * 1e18); // 取出 2 ETH ``` **流程**: 1. 调用 `withdrawCollateral()` 取出抵押品 2. 如果用户有借款,检查剩余抵押品是否充足 3. 转账抵押品给用户 ### 6. 清算(Absorb) ```solidity lending.absorb(borrowerAddress); // 清算借款人 ``` **触发条件**: ``` 债务 > Σ(抵押品价值 × liquidateCollateralFactor) ``` **流程**: 1. 清算人调用 `absorb()` 清算不良贷款 2. 合约检查借款人是否可被清算 3. 将借款人的债务清零 4. 将借款人的抵押品转移到清算库存 ### 7. 购买清算抵押品(Buy Collateral) ```solidity 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 方式) **关键优化**:配置时传入年化利率,初始化时自动转换为每秒利率 ```solidity // 初始化时(只计算一次) 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: ```typescript // 部署后转移所有权到多签 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 插件升级(推荐) 运行升级脚本: ```bash npx hardhat run scripts/deploy/09-upgradeLending.ts --network ``` **脚本特性**: - ✅ 自动验证存储布局兼容性 - ✅ 自动部署新实现合约 - ✅ 自动更新代理指向 - ✅ 保留所有状态数据 **修改升级目标**: ```typescript // 在 09-upgradeLending.ts 中修改 const UPGRADE_LENDING = true; // true = 升级 Lending, false = 升级 Configurator ``` ### 手动 UUPS 升级步骤(不推荐) 如果需要手动升级: 1. **部署新实现合约**: ```typescript const NewLending = await ethers.getContractFactory("LendingV2"); const newImpl = await NewLending.deploy(); ``` 2. **升级代理**: ```typescript await lending.upgradeTo(newImpl.address); ``` ### 注意事项 - ✅ 只有 Owner 可以升级 - ✅ 必须保持存储布局一致 - ✅ 只能在末尾添加新存储变量 - ⚠️ 升级前在测试网充分测试 - 🔧 推荐使用 upgrades 插件,它会自动验证兼容性 --- ## 监控指标 ### 关键指标 1. **利用率**:`totalBorrow / totalSupply` 2. **供应利率**:`getSupplyRate()` 3. **借款利率**:`getBorrowRate()` 4. **储备金**:`reserves` 5. **清算库存**:`collateralReserves[asset]` ### 健康检查 ```typescript // 检查利用率 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 治理) - 需要可靠的价格预言机