当前位置: 首页 > news >正文

aave v3 存款与借款利息的计算方式

本文只涉及到利率计算的数学原理,不作源码解析:

存款

首先我们假设小明在aave里面存了10000usdt,存的时候年化收益率是5%,那么半年后其存款的利息是多少呢?常规的计算方式如下:

利息=10000*5%*(存款的时长/一年的时长)

这么做有什么问题呢?假设现在的存款利率有变化,存的时候是5%,过了两个月变成了6%,那么现在到了第6个月用户提款的时候其利息就会变为:

利息=10000*0.05*(2/12)+10000*0.06*(4/12)

如果利率多变动几次,分步计算的数量会更多,并且需要把用户存款的时间点,以及每次利率变化的时间点和当时对应的利率记录下来,这样才能完整的计算利息。

aave的利率本身是动态的,每次有人存款,取款,借贷,还款都会触发利率的变化,如果把这些都记录下来的话对于智能合约来说是个很大的负担,不仅耗费存储量空间,在最终结息时候的计算量也是巨大的,随着合约的运行,其gas费用会越来越高!

liquidityIndex

aave使用了引入流动性指数这个参数来解决这个问题,aave中存储的每一种资产都有一个liquidityIndex的变量记录储备资产的累积流动性增长率。

一个用户最终的结息金额和三个条件相关:本金,储蓄时间,利率。实际上我们的期望是不管我存了多长时间,结息的时候乘以存款的最终利率是就好,打个比方在利率不变的情况下,年化利率5%,5%/12就是每个月的利率,存半年的最终利率就是5%/12*6=2.5%,那如果每个月利率都在变的情况下最终利率怎么算呢,按照上面的举例前面两个月是5%,后面4个月是6%,半年后取款的最终利率是多少(aave对利率计算的时间精确到秒,这里方便说明使用月代替),计算方式如下:

 

把时间作为权重,乘以相应的利率在累加就是最后的利率。结息的时候用本金乘以最终的利率就可以得到最后的利息金额。

这意味着每一种资产只需要记录3个值,当前的利率(currentLiquidityRate);上一次更新利率的时间戳(lastUpdateTimestamp);从存款开始到上一次更新利率所累计的总利率(liquidityIndex

liquidityIndex的初始值为1,代表尚未产生任何利润,lastUpdateTimestamp就是存款发生的时间,随着时间的推移,liquidityIndex的值会逐渐变大,因为每时每刻都在累积利息,但其并不会被更新,直到发生了利率变化,比如当前资产发生了存取,借贷,资金池的金额发生变化就会促使利率发生变化。这个时候就会发生liquidityIndex的累加,还是用上面的例子,前面两个月利率是5%:

后面4个月利率是6%则:

如果此时取款,直接用本金乘以liquidityIndex就可以得到本息的金额。

scaledBalance

细心的同学此时可能会有个疑问,上面的例子阐述了一种资产一个用户进行储蓄时的利息计算,如果有多个用户在不同的时间点存入金额,只用一个公共的liquidityIndex,如何精准计算每个人的利息呢?这就涉及到scaledBalance参数的应用,前面说到影响最终利息的三大要素本金,储蓄时间,利率,scaledBalance这个参数就是本金的变种,每个用户都会存储一份。接着上面的示例,假设现在的liquidityIndex已经从最初的1变成了1.01,那么是不是我存入10000立马就能取出10100出来呢,显然是太美好的想象,实际上每个用户存入资金的时候都会根据当前的liquidityIndex对本金进行换算,得到scaledBalance。比如此时的liquidityIndex为1.01,存入10000元,换算出的scaledBalance为10000/1.01=9900.99,真正计算本息的时候是用scaledBalance*liquidityIndex,所以存入立刻取出是不可能有任何利润的。

最后我们用示例总结下上面的内容:

场景:三个用户在不同时间存款
时间线

T0: liquidityIndex = 1.0, Alice 存入 10,000 USDC
T6: liquidityIndex = 1.025, Bob 存入 5,000 USDC  
T12: liquidityIndex = 1.051, Charlie 存入 8,000 USDC
T18: liquidityIndex = 1.078, 查询所有用户余额

计算过程

Alice:
- scaledBalance = 10,000 ÷ 1.0 = 10,000
- 最终余额 = 10,000 × 1.078 = 10,780 USDC
- 利息收入 = 780 USDC

Bob:
- scaledBalance = 5,000 ÷ 1.025 = 4,878.05
- 最终余额 = 4,878.05 × 1.078 = 5,258.54 USDC
- 利息收入 = 258.54 USDC

Charlie:
- scaledBalance = 8,000 ÷ 1.051 = 7,611.80
- 最终余额 = 7,611.80 × 1.078 = 8,205.52 USDC
- 利息收入 = 205.52 USD

借款

有了存款利率的原理做基础,理解借款利率的原理就很容易了,相应的借款最终利息的三要素借款金额,利率,时间,借款也有自己的变量存储随时间不断变大的累计利率variableBorrowIndex和经过转换后的借款金额scaledDebt,计算方式和存款的利率如出一辙。

总还款金额=variableBorrowIndex*scaledDebt

http://www.dtcms.com/a/330356.html

相关文章:

  • 码上爬第七题【协程+参数加密+响应解密+格式化检测】
  • C#面试题及详细答案120道(11-20)-- 面向对象编程(OOP)
  • LeetCode Day5 -- 二叉树
  • 嵌入式学习(day26)frambuffer帧缓冲
  • 【系统安装】虚拟机中安装win10企业版系统记录
  • HarmonyOS 开发实战:搞定应用名字与图标更换,全流程可运行示例
  • 101、【OS】【Nuttx】【周边】文档构建渲染:reStructuredText 格式
  • 硬件工程师八月实战项目分享
  • AI抢饭碗,软件测试该何去何从?
  • 基于离散余弦变换的激活水印(DCT-AW)
  • 交错字符串-二维dp
  • 如何通过 Actor 网络压缩为概率分布实现
  • RK3568 Linux驱动学习——新字符设备驱动
  • 人工智能入门①:AI基础知识(上)
  • Vue3 vs Vue2:全面对比与面试宝典
  • 接口添加了 @Transactional 注解并开启事务,而其中一个小方法启动了新线程并手动提交数据,会有什么影响?
  • 红黑树的特性与实现
  • 打靶日常-文件上传
  • 【Python】新手入门:什么是python运算符?python运算符有哪些种类?运算符优先级是怎么样的?
  • Go语言函数详解:从基础到高阶的行为逻辑构建
  • C5.4:光电器件
  • RagFlow启动源码说明
  • Linux framebuffer 编程入门:直接操作显存画图
  • Flutter权限管理三步曲:检查、申请、处理全攻略
  • 【超算】算力的精度,数据中心的划分标准与行业现状(国家超级计算机,企业万卡GPU集群)
  • 深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构
  • 关于linux软件编程4:目录IO和一些时间函数
  • PAT 1065 A+B and C (64bit)
  • 驱动开发系列62 - glBufferDataARB实现分析
  • Windows下cuda的安装和配置