概述
读者可以前往我的博客获得更好的阅读体验。
我们在上一篇文章AAVE交互指南中主要介绍了aave
前端、利率计算等内容,本篇文章
将在交互指南基础上介绍aave-v3
的合约源代码的相关情况。
与之前所写的深入解析Safe多签钱包智能合约系列文章不同,本文主要以我们在AAVE交互指南中进行的合约操作为主线进行分析介绍,较为实战化。
相比于其他项目,AAVE
提供了一个较为完整的文档。在文档内基本涵盖了所有函数的签名及其作用,读者也可作为阅读源代码的重要参考。
AAVE
的总体架构如下:
本文使用存款描述用户向流动性池内注入资产的行为,或称
supply
或deposit
,当然在 V3 版本中,deposit
已被遗弃。当然,有很多人认为此名词应翻译为质押,由于作者的写作习惯,后文统称为存款
代码准备
我们在此处仍使用Foundry
作为开发和测试框架,使用以下命令初始化仓库:
forge init aave-v3
前往AAVE Releases页面下载最新的源代码,并解压。将解压后的contracts
中的文件转移到上文初始化的aave-v3
仓库中的src
文件夹下,最终形成如下目录结构:
.
├── foundry.toml
├── lib
│ └── forge-std
├── script
│ └── Counter.s.sol
├── src
│ ├── Counter.sol
│ ├── dependencies
│ ├── deployments
│ ├── flashloan
│ ├── interfaces
│ ├── misc
│ ├── mocks
│ └── protocol
└── test
└── Counter.t.sol
整体逻辑
在介绍具体的合约代码前,我们首先应当明确存款行为的具体逻辑。作为金融系统,其逻辑具有相当的数学性,我们会结合具体的数学公式介绍存款的具体逻辑。与上一篇文章相比,本节给出的逻辑会更加详细且主要服务于后文代码解释,建议以本节为纲要以避免迷失在具体实现中。
本文主要参考了AAVE V2 Whitepaper,此文档给出了具体的逻辑阐述。
AAVE V3 的白皮书是建立在 V2 白皮书基础上的,所以 V3 白皮书仅介绍了与 V2 不同的部分,不足够详细。
我们引入以下参数:
-
L R t {LR}_t LRt 当前的存款利率(
currentLiquidityRate
),计算方法为
L R t = R t ˉ U t {LR}_t=\bar{R_t}{U_t} LRt=RtˉUt(此公式在上一篇文章内有详细解释,读者可作为参考)参数含义如下:
- R t ˉ \bar{R_t} Rtˉ 为浮动存款和固定存款利率的加权平均数
- U t U_t Ut 为利用率
-
L I t {LI}_t LIt 贴现因子(liquidityIndex),计算方法为
L I _ t = ( L R _ t Δ _ y e a r + 1 ) L I _ t − 1 {LI}\_t=({LR}\_t{\Delta}\_{year} + 1){LI}\_{t-1} LI_t=(LR_tΔ_year+1)LI_t−1如果有读者阅读过原文,可能发现此遍历英文名为
cumulated liquidity index
,但本质是贴现因子。我们会在后文讨论此参数,当然读者也可以通过各种方式了解此概念。
有读者可能发现 L R _ t Δ _ y e a r + 1 {LR}\_t{\Delta}\_{year} + 1 LR_tΔ_year+1 是以线性利率的形式进行的计算,与我们上一篇文章所说明的存款利率复利计算是不符的,但为什么上一篇文章内使用复利计算的结果与和约相同? 原因在于此处的单利计算会在用户每一次进行操作时更新,高频率的单利计算与复利计算会渐趋一致
在AAVE的设计中,贴现因子的使用具有普遍性,如存款、贷款等情况下均使用了贴现因子概念,由于此文主要分析存款,所以若无特殊说明,后文的贴现因子均指存款的贴现因子
假设用户在 t 0 t_0 t0 时刻存入资产Token
的数量为 q q q ,我们在智能合约中记录的用户存入数值为
q L I t 0 \frac{q}{LI_{t0}}