Aave V3 与 Compound V2 利率模型详解

从资金利用率出发,逐步理解 DeFi 借贷协议的动态利率与拐点模型

15 分钟阅读
Aave V3 与 Compound V2 利率模型详解

目录

  1. 为什么 DeFi 借贷协议需要动态利率
  2. 先理解借贷池中的三类资金
  3. 资金利用率的计算方法
  4. 利用率为什么能调节市场供需
  5. 借款利率与存款利率的关系
  6. 为什么存款利率必须乘以利用率
  7. 储备因子与协议收入
  8. Aave V3 的分段线性拐点模型
  9. 使用 DAI 参数完整计算借款利率
  10. 完整计算存款利率与协议收入
  11. 利用率变化时各参与者会发生什么
  12. Aave V3 与 Compound V2 的共同点和差异
  13. Solidity 实现时的定点数与精度问题
  14. 常见误区
  15. 总结

1. 为什么 DeFi 借贷协议需要动态利率

在传统金融中,中央银行、商业银行和市场共同影响利率。银行可以人工调整贷款利率,也可以通过内部风控决定不同客户的利率。

DeFi 借贷协议没有银行柜员,也不会为每一笔贷款单独开会定价。智能合约需要根据链上的资金状态,自动计算当前利率。

Aave V3 和 Compound V2 的核心思路可以概括为:

池子里的钱越紧张,借款利率越高;池子里的闲钱越多,借款利率越低。

协议通过提高或降低利率,引导用户改变行为:

  • 资金紧张时,提高借款成本,促使借款人还款,同时吸引更多存款人提供资金。
  • 闲置资金过多时,降低借款成本,鼓励更多用户借款,同时减少协议需要支付的存款利息。

这个自动调节过程的核心指标就是资金利用率。

2. 先理解借贷池中的三类资金

为了简化理解,假设某个 USDC 借贷池中共有以下资金:

  • 存款人一共存入 1,000,000 USDC。
  • 借款人已经借走 700,000 USDC。
  • 合约中还剩 300,000 USDC 可以被借出或取走。

这里可以区分三个概念:

概念数量含义
总流动性1,000,000 USDC存款人提供的全部可借资金
已借资金700,000 USDC当前正在被借款人使用的资金
可用流动性300,000 USDC暂时没有被借走的资金

需要特别注意:

存款人看到的账户余额仍然可能是 1,000,000 USDC 加上累计利息,但这些资金并不是全部以现金形式躺在合约里。其中 700,000 USDC 已经借给了借款人。

如果所有存款人同时要求取款,协议只能立即拿出当前可用的 300,000 USDC。剩余资金需要等待借款人还款,或者等待新的存款进入。

3. 资金利用率的计算方法

最直观的利用率公式是:

资金利用率 U = 已借资金 ÷ 总资金

因为:

总资金 = 已借资金 + 可用流动性

所以也可以写成:

U = 已借资金 ÷(已借资金 + 可用流动性)

继续使用前面的例子:

已借资金 = 700,000 USDC
可用流动性 = 300,000 USDC

U = 700,000 ÷ (700,000 + 300,000)
  = 700,000 ÷ 1,000,000
  = 70%

3.1 借款不变,新增存款会怎样

假设又有用户存入 400,000 USDC,但借款仍然是 700,000 USDC:

已借资金 = 700,000 USDC
可用流动性 = 700,000 USDC

U = 700,000 ÷ 1,400,000
  = 50%

借款数量没有减少,但由于可用资金增加,池子不再那么紧张,利用率从 70% 降到了 50%。

3.2 存款不变,借款增加会怎样

假设总资金仍然是 1,000,000 USDC,但借款从 700,000 增加到 900,000 USDC:

U = 900,000 ÷ 1,000,000
  = 90%

此时池子中只剩 100,000 USDC。协议需要提高利率,避免资金被全部借光。

4. 利用率为什么能调节市场供需

利用率不是一个单纯用于展示的数据,它会直接影响借款利率。

4.1 利用率上升

利用率上升说明借款需求旺盛,池子中的可用资金正在减少。

协议通常会提高借款利率,产生以下效果:

  1. 新借款人发现借款成本变高,可能放弃借款。
  2. 已有借款人需要支付更多利息,因此更愿意提前还款。
  3. 存款利率通常也会提高,吸引更多存款人提供资金。
  4. 还款和新增存款都会增加可用流动性。
  5. 可用流动性增加后,利用率下降。

4.2 利用率下降

利用率下降说明池子里有大量资金没有被使用。

协议通常会降低借款利率,产生以下效果:

  1. 借款成本降低,吸引更多用户借款。
  2. 存款利率也会降低,减少资金继续涌入的动力。
  3. 借款增加或存款减少后,闲置资金下降。
  4. 利用率重新上升。

因此,利率模型实际上是一个自动反馈系统。

5. 借款利率与存款利率的关系

借款人支付的利息,是存款人收益和协议收入的来源。

暂时忽略协议收费时,存款利率可以近似表示为:

存款利率 = 借款利率 × 资金利用率

假设:

借款利率 = 10%
资金利用率 = 50%

那么:

存款利率 = 10% × 50%
          = 5%

存款人获得的年化利率是 5%,而不是 10%。

6. 为什么存款利率必须乘以利用率

假设:

  • Alice 向协议存入 100 USDC。
  • Bob 从协议借走 50 USDC。
  • 借款年利率是 10%。
  • 暂时忽略复利和协议收费。

一年后 Bob 需要支付的利息为:

50 × 10% = 5 USDC

协议只从借款人那里赚到了 5 USDC,因此最多只能把这 5 USDC 分给存款人。

Alice 最初存入了 100 USDC,她获得 5 USDC 利息,对应的收益率为:

5 ÷ 100 = 5%

这也等于:

借款利率 × 利用率
= 10% × (50 ÷ 100)
= 10% × 50%
= 5%

如果协议不乘以利用率,直接承诺给 Alice 10%:

协议应付 Alice 的利息 = 100 × 10% = 10 USDC
协议从 Bob 收到的利息 = 50 × 10% = 5 USDC
资金缺口 = 10 - 5 = 5 USDC

协议凭空多欠了 5 USDC,这种模式无法长期运行。

7. 储备因子与协议收入

实际协议不会把全部借款利息都分给存款人。协议通常会保留一部分收入,用于国库、风险储备或其他治理用途。

这一比例叫作储备因子:

Reserve Factor

加入储备因子后,存款利率公式变为:

存款利率
= 借款利率 × 资金利用率 ×(1 - 储备因子)

假设:

借款利率 = 10%
资金利用率 = 50%
储备因子 = 20%

分三步计算:

第一步:所有借款利息能够支撑的毛存款利率
10% × 50% = 5%

第二步:存款人可以获得的比例
1 - 20% = 80%

第三步:存款人最终获得的利率
5% × 80% = 4%

最终:

  • 存款人年化利率为 4%。
  • 对应 1% 的总存款本金收益率进入协议。
  • 这里的 1% 等于 5% 毛收益的 20%,不是借款本金的 20%。

8. Aave V3 的分段线性拐点模型

如果借款利率从 0% 利用率到 100% 利用率始终以相同速度增长,就无法在资金即将耗尽时产生足够强的制动力。

因此,Aave V3 使用带拐点的分段线性模型。

协议首先设置一个最优利用率:

U_optimal

利率曲线被分成两段:

  • 第一段:利用率不超过最优利用率,利率缓慢上升。
  • 第二段:利用率超过最优利用率,利率快速上升。

8.1 第一段:正常区间

当:

U ≤ U_optimal

借款利率为:

R_borrow
= R_base + (U ÷ U_optimal) × R_slope1

参数含义:

参数含义
U当前资金利用率
U_optimal协议希望维持的最优利用率
R_base利用率为 0 时的基础借款利率
R_slope1从 0 到最优利用率区间内增加的利率

这里必须先计算 U ÷ U_optimal,因为协议需要知道当前利用率已经走完正常区间的百分之多少。

8.2 第二段:高风险区间

当:

U > U_optimal

借款利率为:

R_borrow
= R_base
  + R_slope1
  + ((U - U_optimal) ÷ (1 - U_optimal)) × R_slope2

超过拐点后:

  • R_base + R_slope1 是到达拐点时已经产生的利率。
  • U - U_optimal 是超过拐点的利用率。
  • 1 - U_optimal 是拐点之后剩余的完整区间。
  • 两者相除,可以得到当前已经走完高风险区间的百分之多少。
  • 再乘以 R_slope2,得到高风险区间新增的利率。

R_slope2 通常明显大于 R_slope1,所以曲线在拐点后会陡峭上升。

9. 使用 DAI 参数完整计算借款利率

原文使用的一组 Aave DAI 利率参数如下:

U_optimal = 80%
R_base    = 0%
R_slope1  = 4%
R_slope2  = 75%

这些参数表达的含义是:

  • 利用率从 0% 增长到 80% 时,借款利率从 0% 缓慢增长到 4%。
  • 利用率从 80% 增长到 100% 时,借款利率会在已有 4% 的基础上继续增加最多 75%。
  • 当利用率达到 100% 时,借款利率为 79%。

9.1 利用率为 40%

40% 没有超过 80%,使用第一段公式:

R_borrow
= 0% + (40% ÷ 80%) × 4%
= 0% + 50% × 4%
= 2%

此时借款年利率为 2%。

直观理解:

40% 正好走完了正常区间的一半,所以也只使用了 R_slope1 的一半。

9.2 利用率为 80%

80% 正好位于拐点:

R_borrow
= 0% + (80% ÷ 80%) × 4%
= 4%

此时借款年利率为 4%。

9.3 利用率为 90%

90% 超过了 80%,使用第二段公式。

第一步,计算超过拐点的部分:

90% - 80% = 10%

第二步,计算拐点之后的完整区间:

100% - 80% = 20%

第三步,计算已经走完高风险区间的比例:

10% ÷ 20% = 50%

第四步,计算第二段新增利率:

50% × 75% = 37.5%

第五步,加上拐点处已有的利率:

R_borrow
= 0% + 4% + 37.5%
= 41.5%

利用率只是从 80% 增加到了 90%,借款利率却从 4% 增加到了 41.5%。

这不是计算错误,而是协议故意制造的强烈经济激励:

  • 借款人会发现继续占用资金非常昂贵。
  • 部分借款人会尽快还款。
  • 高利率也会推高存款收益,吸引新资金进入。

9.4 利用率为 95%

超过拐点的利用率 = 95% - 80% = 15%
高风险区间总长度 = 100% - 80% = 20%
已走完高风险区间 = 15% ÷ 20% = 75%
第二段新增利率 = 75% × 75% = 56.25%

R_borrow = 0% + 4% + 56.25%
         = 60.25%

此时借款年利率为 60.25%。

9.5 利用率为 100%

超过拐点的利用率 = 100% - 80% = 20%
已走完高风险区间 = 20% ÷ 20% = 100%
第二段新增利率 = 100% × 75% = 75%

R_borrow = 0% + 4% + 75%
         = 79%

此时借款年利率为 79%。

把几个关键点放在一起:

利用率借款年利率
0%0%
40%2%
80%4%
90%41.5%
95%60.25%
100%79%

可以清楚看到,80% 是整个曲线的关键拐点。

10. 完整计算存款利率与协议收入

继续使用下面的状态:

总存款 = 1,000,000 DAI
已借资金 = 900,000 DAI
资金利用率 = 90%
借款利率 = 41.5%
储备因子 = 10%

10.1 计算存款利率

存款利率
= 41.5% × 90% × (1 - 10%)
= 41.5% × 90% × 90%
= 33.615%

存款人的理论年化利率约为 33.615%。

10.2 使用实际金额验证

借款人一年产生的总利息:

900,000 × 41.5% = 373,500 DAI

协议按 10% 的储备因子保留:

373,500 × 10% = 37,350 DAI

分给存款人的利息:

373,500 - 37,350 = 336,150 DAI

相对于 1,000,000 DAI 总存款:

336,150 ÷ 1,000,000 = 33.615%

结果与公式完全一致。

10.3 不要把高年化理解为固定收益

41.5% 和 33.615% 是当前资金状态对应的年化速率,不代表该利率会持续一年。

如果高利率促使借款人大量还款,利用率可能在几个区块后下降,借款利率和存款利率也会随之下降。

因此,界面显示的 APY 或 APR 通常是基于当前状态推算的结果,不是协议对未来一年的收益承诺。

11. 利用率变化时各参与者会发生什么

11.1 利用率从 50% 上升到 80%

  • 借款需求增加。
  • 可供取款的流动性减少。
  • 借款利率逐渐上升。
  • 存款利率也逐渐上升。
  • 市场仍处于协议认为相对正常的区间。

11.2 利用率从 80% 上升到 90%

  • 可用资金快速减少。
  • 借款利率进入陡峭区间。
  • 新借款变得非常昂贵。
  • 已有借款人受到更强的还款激励。
  • 存款人受到更强的存款激励。

11.3 利用率接近 100%

  • 几乎没有可用资金。
  • 存款人可能暂时无法足额取款。
  • 借款利率接近模型设定的最高值。
  • 协议通过极高利率试图恢复流动性。

高利用率不等于协议已经资不抵债。

它首先表示流动性紧张:资产可能仍然存在于借款人的抵押贷款头寸中,但没有足够的空闲现金满足所有即时取款。

12. Aave V3 与 Compound V2 的共同点和差异

12.1 共同点

Aave V3 和 Compound V2 在本文讨论的核心经济逻辑上非常接近:

  • 使用资金利用率衡量资金紧张程度。
  • 利用率决定借款利率。
  • 借款利率结合利用率,决定存款人能够获得的收益。
  • 协议可以通过储备因子保留部分利息收入。
  • 使用带拐点的曲线,使高利用率区间的利率更快上升。

12.2 差异

两者在具体合约结构、变量命名、每区块或每秒的计息方式、参数管理和指数累计方式上存在实现差异。

学习时应该分成两个层次:

第一层是经济模型:

利用率 → 借款利率 → 存款利率

第二层是合约实现:

如何保存参数
如何计算每秒或每区块利率
如何累计借款指数
如何累计存款指数
如何处理定点数精度

不要因为实现代码不同,就误以为两者的核心经济逻辑完全不同。

另外,Compound V3 的存款利率模型与 Compound V2 不完全相同。Compound V3 可以直接根据利用率计算存款利率,而不是简单地使用“借款利率乘以利用率”这一形式。

13. Solidity 实现时的定点数与精度问题

Solidity 没有原生浮点数,不能直接保存 0.80.040.75

Aave 会使用高精度定点数表示比例。原文提到相关参数使用 27 位小数精度的 Ray:

1     = 10^27
0.8   = 8 × 10^26
0.04  = 4 × 10^25
0.75  = 75 × 10^25

可以把它理解为:

合约先把所有小数统一放大 10^27 倍,使用整数完成计算,最后再按 10^27 的比例解释结果。

13.1 一个简化的定点数例子

为了方便展示,假设只使用 10^4 精度:

1.0000 = 10,000
0.8000 = 8,000
0.0400 = 400

计算:

0.4 ÷ 0.8 × 0.04

放大后分别是:

0.4  → 4,000
0.8  → 8,000
0.04 → 400

定点数乘法和除法需要主动恢复缩放比例,否则结果会多放大或少放大若干倍。

例如,两个都放大了 10,000 倍的数相乘:

(4,000 × 400) ÷ 10,000 = 160

160 按照 10,000 精度解释就是:

160 ÷ 10,000 = 0.016 = 1.6%

实际生产合约通常会使用经过审计的数学库处理 Ray 乘法、除法和舍入,避免重复编写容易出错的缩放逻辑。

13.2 审计时应重点检查

  • 分段条件在 U == U_optimal 时选择哪一段。
  • 计算顺序是否导致整数除法提前截断。
  • 乘法是否可能溢出。
  • 缩放因子是否被遗漏或重复使用。
  • U_optimal 是否可能被设置为 0 或 100%,从而造成除零。
  • 治理设置的 R_slope2 是否过高或过低。
  • 储备因子是否被正确限制在合法范围内。
  • 利率是年化值、每秒值还是每区块值。
  • 展示层的 APR 与 APY 转换是否正确。

14. 常见误区

14.1 利用率 90% 表示 90% 的用户正在借款

错误。

利用率衡量的是被借走的资金占总资金的比例,与用户数量没有直接关系。一个大户也可能借走池子中 90% 的资金。

14.2 借款利率 10%,存款利率也应该是 10%

错误。

只有被借走的资金才会产生借款利息,而且协议还可能保留一部分收入。存款利率通常低于借款利率。

14.3 储备因子 20% 表示协议拿走全部存款的 20%

错误。

协议拿走的是借款利息中的 20%,不是存款本金的 20%。

14.4 利用率越高越好

不完全正确。

高利用率说明资金使用效率高,但过高会导致存款人难以及时取款。协议需要在资金效率和可用流动性之间取得平衡。

14.5 100% 利用率等于协议破产

错误。

100% 利用率首先意味着可用流动性几乎为零,不一定意味着抵押资产不足。协议是否资不抵债,还要看借款人的抵押品价值、清算机制和坏账情况。

14.6 当前显示 30% APY,就一定能获得一年 30% 收益

错误。

利率会随着利用率不断变化。当前显示值只是按照当前状态进行的年化换算。

15. 总结

Aave V3 和 Compound V2 利率模型可以浓缩为以下链路:

借款需求变化

资金利用率变化

借款利率变化

借款人和存款人的行为变化

资金利用率重新趋向合理区间

最重要的四个公式是:

1. 资金利用率

U = 已借资金 ÷(已借资金 + 可用流动性)
2. 拐点之前的借款利率

R_borrow
= R_base + (U ÷ U_optimal) × R_slope1
3. 拐点之后的借款利率

R_borrow
= R_base
  + R_slope1
  + ((U - U_optimal) ÷ (1 - U_optimal)) × R_slope2
4. 考虑储备因子后的存款利率

R_supply
= R_borrow × U × (1 - Reserve Factor)

理解这个模型时,不要只背公式。真正关键的是理解它背后的目标:

  • 正常区间内,让资金保持较高使用效率。
  • 资金紧张时,快速提高借款成本。
  • 用高利率促使借款人还款并吸引新存款。
  • 保留足够流动性,让存款人能够取回资金。
  • 在存款人、借款人和协议三方之间合理分配借款利息。

💬 评论