概述

读者可以前往我的博客获得更好的阅读体验。

我们在上一篇文章AAVE交互指南中主要介绍了aave前端、利率计算等内容,本篇文章
将在交互指南基础上介绍aave-v3的合约源代码的相关情况。

与之前所写的深入解析Safe多签钱包智能合约系列文章不同,本文主要以我们在AAVE交互指南中进行的合约操作为主线进行分析介绍,较为实战化。

相比于其他项目,AAVE提供了一个较为完整的文档。在文档内基本涵盖了所有函数的签名及其作用,读者也可作为阅读源代码的重要参考。

AAVE的总体架构如下:

本文使用存款描述用户向流动性池内注入资产的行为,或称supplydeposit,当然在 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}} LIt0​q​

在 t 1 t1 t1 时刻,用户取出资产,获得的资产数量为

q L I t 0 × L I t 1 \frac{q}{LI_{t0}} \times LI_{t1} LIt0​q​×LIt1​

此部分使用了金融学内简单的贴现概念,我们将所有存入资产均贴现到 t 0 t_0 t0​ 时期,在用户提款时将其折算回 t 1 t_1 t1​ 。此处使用的 l i q u i d i t y I n d e x liquidityIndex liquidityIndex 事实上就是 贴现因子。如果读者无法理解此部分,可简单选择任一金融学课本阅读此部分内容。

假设用户的存款数量用 S c B t ( x ) {ScB}_t(x) ScBt​(x) 表示,则用户存入 m m m 单位质押品后,存款数量为:

S c B _ t ( x ) = S c B _ t − 1 ( x ) + m L I _ t {ScB}\_t(x) = {ScB}\_{t-1}(x) + \frac{m}{{LI}\_t} ScB_t(x)=ScB_t−1(x)+LI_tm​

取出 m m m 单位质押品后,存款数量为:

S c B _ t ( x ) = S c B _ t − 1 ( x ) − m L I _ t {ScB}\_t(x) = {ScB}\_{t-1}(x) - \frac{m}{{LI}\_t} ScB_t(x)=ScB_t−1(x)−LI_tm​

总结来说,存款的核心步骤如下:

  1. 计算当前的 L R _ t Δ _ y e a r + 1 {LR}\_t{\Delta}\_{year} + 1 LR_tΔ_year+1
  2. 更新 L I t {LI}_t LIt​
  3. 计算 S c B t ( x ) {ScB}_t(x) ScBt​(x)

当然,上述核心步骤会在合约编程中被高度复杂化。总体来说,复杂性主要来源于以下两点:

  1. 提高用户体验
  2. 更新数据

入口函数

在此处,我们在上一篇文章内进行存款交易的EthTx 地址。如下图:

非常明显,在存款交易时,我们使用了supply函数,并将USDC存入获得aEthUSDC

查阅源代码,我们可以在src/protocol/pool/Pool.sol找到此函数,代码如下:

function supply(address asset,uint256 amount,address onBehalfOf,uint16 referralCode
) public virtual override {SupplyLogic.executeSupply(_reserves,_reservesList,_usersConfig[onBehalfOf],DataTypes.ExecuteSupplyParams({asset: asset,amount: amount,onBehalfOf: onBehalfOf,referralCode: referralCode}));
}

此函数的各参数含义如下:

  1. asset 存入资产的合约地址
  2. amount 存入资产的数量
  3. onBehalfOf 接受aToken代币的地址
  4. referralCode 第三方集成商的标识。此参数主要用于第三方供应商检索集成交易

只有持有aToken的用户可以获得存款回报,所以一般情况下onBehalfOf仅为用户自己的地址,但用户也可以设置为其他人的地址以方便进行利益转移。

虽然此函数看似简单,但其内部调用了一些复杂函数。使用Solidity Visual Developer中的ftrace工具获得如下调用栈:

└─ Pool::supply├─ SupplyLogic::executeSupply | [Ext] ❗️  												

深入解析AAVE智能合约:存款相关推荐

  1. 深入解析AAVE智能合约:计算和利率

    概述 读者可前往我的博客获得更好的阅读体验. 本文主要讨论AAVE V3中的数学计算模块,该模块位于src/protocol/libraries/math文件夹内,基础合约为WadRayMath. 本 ...

  2. 【许晓笛】 EOS智能合约案例解析(1)

    详解 EOS 智能合约的 hpp 文件 为了帮助大家熟悉 EOS 智能合约,EOS 官方提供了一个代币(资产)智能合约 Demo -- eosio.token.eosio.token 智能合约目前还不 ...

  3. 【许晓笛】 EOS 智能合约案例解析(2)

    详解 EOS 智能合约的 cpp 文件 之前的文章介绍了 eosio.token 智能合约的 hpp 文件,这次向大家介绍 eosio.token.cpp 文件,cpp 文件即 C++ 代码文件,智能 ...

  4. 【许晓笛】 EOS智能合约案例解析(1) 1

    详解 EOS 智能合约的 hpp 文件 为了帮助大家熟悉 EOS 智能合约,EOS 官方提供了一个代币(资产)智能合约 Demo -- eosio.token.eosio.token 智能合约目前还不 ...

  5. 弯道超车老司机戏耍智能合约——竞态条件漏洞 | 漏洞解析连载之三

    安全,区块链领域举足轻重的话题,为什么一行代码能瞬间蒸发几十亿市值?合约底层函数的使用不当会引起哪些漏洞?重入漏洞会导致什么风险? 「区块链大本营」携手「链安科技」团队重磅推出「合约安全漏洞解析连载」 ...

  6. 【许晓笛】EOS 智能合约案例解析(2)

    详解 EOS 智能合约的 cpp 文件 之前的文章介绍了 eosio.token 智能合约的 hpp 文件,这次向大家介绍 eosio.token.cpp 文件,cpp 文件即 C++ 代码文件,智能 ...

  7. 【许晓笛】EOS智能合约案例解析(1)

    为了帮助大家熟悉 EOS 智能合约,EOS 官方提供了一个代币(资产)智能合约 Demo -- eosio.token.eosio.token 智能合约目前还不是特别完善,个别功能还没有完成.但这个示 ...

  8. c++ eos智能合约开发_EOS开发完全解析(六):手摸手实现第一个EOS智能合约——Hello EOS...

    一.概述 EOS智能合约由C++编写,所以真正商业开发的时候,肯定是需要全面学习C++语法的,通过最近爆出的越来越多的合约漏洞我们就知道问题的严重性了.可以毫不客气的说,写智能合约要比写以往任何代码都 ...

  9. solidity采坑日记之智能合约返回事件内容解析

    最近在用java调用solidity智能合约方法的时候,遇到了方法Log解析的问题. 正常在调用合约后,如果该合约有event时间,那么执行结果会返回对应的log日志,但是返回的log日志是0x开头的 ...

最新文章

  1. 三天打入CV大赛决赛圈!我是如何做到的?
  2. 组态王浏览器java_1工程浏览器是组态王的集成开发环境在这里可以
  3. 定义简单类-创建多个猫对象
  4. IP地址便捷修改器 V3.5 绿色版
  5. RESTEasy教程第2部分:Spring集成
  6. 外星人电脑为什么那么贵_为什么隐形矫正那么贵
  7. c++ 状态模式(state)
  8. 模块化编程的分层设计经验
  9. 【github系列】github定位到历史版本(历史commit点)
  10. 大数据技术全解之三分虚拟化技术、七分分布式管理、十二分大数据
  11. ningx访问日志切割
  12. Ubuntu下 UltraEdit 破解/显色
  13. 【项目管理】Java OCR实现图片文字识别
  14. PHP搭建留言板,用PHP制作留言板_php
  15. ajax请求数据 ztree_ztree通过ajax获取json并勾选checkbook
  16. 【echarts应用】---pie饼图篇
  17. 最有效率的⽅法计算2乘以8
  18. java鼠标指针锤子,如果用4个技能打不过他,那就用7个
  19. 泰无聊服务器维护,泰无聊网站6年一线编辑实战分享:接地气的软文是…
  20. 世界上最高的山峰的排名

热门文章

  1. C语言,将一个八进制数转换为十进制数(含延伸)
  2. MMX指令集(详解)https://blog.csdn.net/dahan_wangtao/article/details/1944153
  3. PHP最全的正则表达式大全
  4. TrinityCore 魔兽世界私服11159 完整配置
  5. 网页播放rtsp视频解决方案(unity webplayer页面播放遮挡问题解决方案)
  6. 大专计算机类英语翻译,专科英文(大学专科用英文怎么说)
  7. 老前辈分享:使用python-opencv读取视频,计算视频总帧数及FPS的实现
  8. linux安装mysql,显示尚未安装gpg密钥
  9. linux usermod用法,Linux中Usermod命令的一些使用技巧
  10. 反欺诈之设备指纹(上篇)