Aave就相当于去中心化交易所中的一个银行,在其中用户可以进行一系列的资金操作,下面从其两个主要的功能阐述:借贷、存款。借贷在Aave中借贷有两种方式:借款(有抵押物的)、闪电贷(无抵押物的)。闪电贷AaveV2的闪电贷感觉没有什么特别的地方,就是在一个区块交易内完成借出和还入两个
Aave 就相当于去中心化交易所中的一个银行,在其中用户可以进行一系列的资金操作,下面基于行为的角度对其两个功能进行阐述:借贷、存款。
在 Aave 中借贷有两种方式:借款(有抵押物的)、闪电贷(无抵押物的)。
Aave V2 的闪电贷感觉没有什么特别的地方,就是在一个区块交易内完成借出和还入两个操作。
function flashLoan(
address receiverAddress, // 借款受益人地址
address[] calldata assets, // 借款代币地址(数组)
uint256[] calldata amounts, // 借款数量(数组)
uint256[] calldata modes, // 借款模式(数组)
address onBehalfOf, // 还款人地址
bytes calldata params, // 入参编码
uint16 referralCode // 推荐码
) external override whenNotPaused {
查看 Aave V2 的代码(参考上述的函数头),我们可以知道,Aave V2 允许一次性借出多种贷款(assets
是个数组),并且允许选择模式(由modes
决定,不同资产可以选择不同模式),有:闪电贷模式(0,正常闪电贷)、借款模式(1,普通的借款,采用稳定利率;2,普通的借款,采用浮动利率)。
对于每一笔贷款(无论哪种模式) Aave V2 都会先转出借款费用、计算手续费,然后再根据模式进行判断:
receiverAddress
)转账还款(借款+手续费
)总的来说,Aave V2 在闪电贷种添加了一个转入正常借贷的机会,可以将闪电贷、正常借贷合并在一笔交易中。
关于借款,就开始麻烦起来了,借款可以分为三个部分:借款(借钱这件事)、还款(还钱这件事)、清算(清算合约中不良借款这件事)
我们首先来看看清算这件事。由于区块链中没办法轻易的溯源到账户拥有者本人,所以对于合约中每一笔借款都不能有坏账(借出款的价值大于抵押物的价值)这件事发生合约就会不被信任了。
我们知道合约对于借款策略采用的是超额抵押借贷(如抵押 100$价值的抵押物,借贷的钱不能到达 100$ 那么多,可能只有 50$),所以可以设定一个阈值(抵押物价值/所欠金额),到达一定比值后资产就会被清算(合约自动卖出抵押物,借款人就不用还款了)。
那么这个清算阈值是怎么确定的呢?Aave V2 定义了一个健康系数(HealthFactor)
,当其小于 1 时,该笔交易就可以清算。那么这个HealthFactor
如何定量呢?
$$ HealthFactor = \frac{TotalCollateralInETH * LiquidationThreshold}{TotalDebtInETH} $$
首先分母TotalDebtInETH
表示:总共的债务量(借款 + 利息,但在实际中只会计算债务量,因为 Aave V2 采用的是利滚利模型)。分子TotalCollateralInETH
表示:借款人抵押物的总价值(以ETH
为单位)。分子LiquidationThreshold
表示:该种资产设定的阈值(一个百分比,例如75%)。
分子两者相乘,得到当前抵押物能借出金额上限,分母表示当前借出的债务。分子受市场波动影响,抵押物价值下降,HealthFactor
就有可能逼近 1 了,而TotalDebtInETH
由于债务利率的存在,会不断的上涨,也会让HealthFactor
逐渐的逼近 1 。
清算具体会发生什么呢?当用户抵押了价值 200 $的抵押物,借出了 100 USDT,此时清算阈值是 75%,那么抵押物的价值如果下跌,最多跌倒133.3(用 100 / 0.75 得到,并且忽略利息对健康系数分母的影响),一旦跌倒这个价格之下,那么清算开始发生。
此时有一个清算人负责清算该资产,它可以清算该笔资产的一部分(用户自己决定,但有上限,由 Aave V2 决定,其不允许一次性清算完全部抵押资产),Aave V2 将对抵押物折价卖出,清算人付出借出债务的代币(0%~Aave V2 规定的上限 50%),以当前折扣价买入被清算的抵押物((市场价/代还款)*(1+奖励比例)
,其中奖励比例就是清算人比起在正常市场中购买代币,在 Aave V2 清算中能额外获得的利润)。此时借款人的健康系数受到影响,变得健康:以上清算行为相当于 Aave V2 自动帮借款人卖出一部分抵押物,来偿还借款(略低于市场价,但高于阈值 * 市场价
,因此可以提高健康系数)。
如何发起清算呢?合约由于不能说根据触发条件自动执行函数,所以需要外部的套利者不断的巡视整个市场,发现这些可以清算的交易,对于到达清算线的交易,所有人都可以对其进行清算。清算过后:套利者获得一定利润(通过奖励比例),合约避免了坏账的诞生,维护了市场的稳定。
Aave V2 对于借款人的债务进行了token
化,即债务就是一个个的代币。首先有一个问题:债务是token
那么转移token
是不是就不用还钱了。理论是这样的,但是 Aave V2 将transfer
函数重载了,调用后就会revert
,所以是没办法转移债务的。
然后就是如何借款了。在 Aave V2 中借款有两种:稳定利率债务、可变利率债务。前者利率固定,借钱时利率是多少,后面利滚利时利息就一直是多少(也有可能调整,如借钱时固定利率和当前利率差距过大);后者利率不固定,随着市场波动,借钱的人多(资金池使用率高),利率就高,人少,利率就低。
当我们想统计t
时刻债务总量即:$D^{asset}_t = SD_t(稳定利率债务) + VD_t(浮动利率债务)$,而借款关系到存款利率问题(借款为合约赚取收入,收入分配给存款用户,实现银行的基本功能)。
浮动利率虽然浮动(会因为资金池利用率而改变,利用率高,浮动利率就该,反之变低),但是其计算实现反而更加简单。Aave V2 对于每一笔可变债务都首先放缩到0
时刻(创世时间)然后利用一个变量存储累计可变债务指数,从而统计出用户当前总可变债务(仅浮动利率债务部分)。
首先理解这个放缩(scaled
),它将当前借出的债务换算到创世时间时(即假设你这笔债务在创世时间时借出),假设现在是 $t_1$ 时刻,从 $t_0$ 时刻(创世时间)到当前的累计可变债务 $VN_t^{asset}$ 为 200%(假设创世初借款100,现在 $t_1$ 就需要还200了),那么用户借出 1000 $ 相当于创世初时借了 500 $。上述这个 1000 到 500 的过程就是放缩。
然后就是这个累计可变债务指数 $VN_t^{asset}$ 又是如何确定的呢?白皮书中的定义是:
$$ V N_t = (1 + \frac{V Rt}{ T{year}} )^{ ∆T} *V I_{t−1} $$
下面介绍公式中的每个变量的定义,首先是 $VRt$ 表示的是:当前浮动利率(这种当前利率放到最后阐述,先默认已知),即当前所有浮动债务所需要每秒支付利息的利率,这个利率是年华利率。$T{year}$ 表示:一年的秒数(固定值),配合其分子进行除法运算,即可得到每秒的利率。$\Delta T$ 表示:前后两次操作发生之间的间隔时间,这个操作包含借出、存入、取出、偿还、交换、清算。$VI_{t-1}$ 表达的含义应该与 $VN_t^{asset}$ 一样(我认为的),因为两者白皮书上定义公式一致:
$$ V I_t = (1 + \frac{V Rt}{ T{year}} )^{ ∆T} *V I_{t−1} $$
而其初始值应该为 1 ,然后随着用户不断的操作使得这个变量单调递增。每当我们借出一笔价值为 m 的债务,然后合约进行放缩得到债务值$\frac{m}{VN_t} $ ,然后加上过去放缩到创世时间的债务(这种方式方便合约计算债务,只需要改变这个累计值,不然浮动利率不断变动,每次操作都要遍历所有债务计算新的债务,又或者记录每次利率变化,gas
消耗太大):
$$
ScVB{t}(x) =ScVB{t-1}(x) + \frac{m}{VN_t}
$$
当我们想知道当前债务到底是多少时,也很容易计算(其中 $x$ 指某个用户,$VN_t$ 在白皮书中为 $D_t$,查了下资料说可能是白皮书排版错误,$D_t$ 表示放缩后总债务,包含了浮动和固定的):
$$ V D(x) = ScV B(x) * VN_t $$
对于开头的 $SD_t$ (浮动利率债务)的计算就是所有用户的 $VD(x)$ 的总和了。
对于稳定利率,其计算方法就不一样了。首先需要明确,稳定利率债务不是说借贷利率恒定不变(非硬编码在合约中),而是在计算复利(利滚利)时,利率固定下来,不会因为资金利用率(合约中资金使用程度)而改变,当然当前稳定利率还是会不断改变的。
那么借出一笔稳定利率的债务是怎么进行的呢?在 Aave V2 中记录的是用户的平均稳定借款利率和稳定借款债务,通过两者即可计算当前债务量。
为什么要计算平均稳定借款利率呢?如果使用平均稳定借款利率,那么统计债务的时候就需要遍历每一笔稳定利率借款,而且每一笔债务都需要单独的存储,这都会需要大量的gas
,而采用平均稳定利率,那么对于每个用户想要得到当前时刻的债务 $SD_t(x)$,需要存储的就变为,用户所有债务的平均稳定利率 $\overline{SR_t}$ 和稳定利率债务总量 $SB(x)$:
$$ SD_t(x) = SB(x) * (1 + \frac{\overline{SRt}}{T{year}})^{\Delta T} $$
上述公式另外几个变量的含义都比较清楚,与浮动利率中的一致。那么上面的平均稳定利率这些变量是怎么确定的呢?首先是平均稳定利率 $\overline{SR_t}$ ,作为平均的利率,肯定是稳定利率平均而来,其公式为:
$$ \overline{SR_t} = \frac{SDt * \overline{SR{t−1}} + SB_{new} * SR_t}{SDt + SB{new}} $$
上述公式表示,当用户借出一笔新的资金 $SB_{new}$ ,在此时,资金池的稳定利率为 $SR_t$ ,而用户此前的稳定利率债务为 $SDt$ (不包含 $SB{new}$,并且个人觉得使用 $SD{t-1}$更加符合含义)此前的平均稳定利率为 $\overline{SR{t−1}} $。在初始和还清债务时,用户的 $SDt$ 和 $\overline{SR{t−1}} $ 均为 0 。如此,如果用户不断借钱,那么这个平均稳定利率就会不断靠近当前稳定利率。
在上面的几个公式中 $SD_t$ 和 $SB(x)$ 不断交替出现,其含义十分相似,都表示用户的稳定利率的债务,但还是有一些区别。对于 $SB(x)$ 其表示的存储于合约上的债务,即用户当前拥有的债务 token,而$SD_t(x)$ 更多的表示实际需要还给合约的欠款,从$SB(x)$ 到 $SD_t(x)$ 需要经过开头的那个公式。
在前面我们知道,统计用户的浮动利率债务的时候用的是放缩后的债务 token,而还款也是一样,扣除的是放缩后的债务 token,以此保持浮动利率债务的统计。那么还款后应该扣除多少放缩后的债务 token 呢?这个逻辑和借款的逻辑相反,用户还款 $m$ 根据从创世到现在的累计可变债务 $VN_t^{asset}$ 即可得到新的债务:$ScVBt(x) = ScVB{t-1}(x) - \frac{m}{VN_t}$。
稳定利率和浮动利率不同,没有这个放缩的过程,所以是计算当前实际欠款 $SD_t(x)$(利用借款中其定义公式),然后减去还款数额,并且重新计算平均稳定利率(分母不能为 0 所以分条件):
$$ \overline{SR_t} =\left { \begin{array}{} &0 &, if \space SDt − SB(x) = 0,\ &\frac{SDt * \overline{SR{t−1}} − SB(x) * SR(x)}{SD_t−SB_x} &,if \space SD_t − SB_x > 0 \end{array}\right. $$
Aave V2中对于用户的存款也是采用放缩和 token 的方法存储用户的存款额度。首先是用户查看当前存款额度$aB_t(x)$(能取出多少钱):
$$ aB_t(x) = ScB_t(x) * NI_t $$
其中 $ScB_t(x)$ 正是用户放缩后的存款额度(同样是放缩到创世时间),而后面的 $NI_t$ 正是累计流动性指数,和借款里的累计类似,这是一个全局的变量(所有的存款共用):
$$ LI_t = (LRt * \Delta T{year} + 1 ) LI_{t-1} \ LI_0 = 1 10^{27} = 1 \space ray $$
上面阐述了这个累计指数的初始值和后续的变化方法,而其中的 $LR_t$ 是指当前的流动性(一个随着每次资金池操作而改变的值)。在上面我们看到了这个累计流动性指数也是和可变债务指数一样,在不断的单调递增,利用放缩到创世初的存储金额两者结合计算当前存款。
当用户新存入一笔存款 m 也是放缩到创世初,然后两个相加,取款类似(具体是按照取款额度还是放缩后的代币额度需要后续看源码):
$$ ScBt(x) = ScB{t-1}(x) + \frac{m}{NI_t} $$
在上述的各种操作,我们可以知道 Aave V2 其实挺像一个银行了,利用用户的存款进行出借,赚取借贷的利息,然后将利息作为存款的利息发放给存款用户,实现存款获得利息,借款付出利息(虽然是超额抵押借贷)。
但还有一个问题,上述的三个实时利率(当前稳定利率、当前浮动利率、当前流动性率)都是如何确定的呢?首先明确影响这些利率的因素:资金池使用率(使用率越高,借贷的利率理所当然的会更高,反之降低)。
基本上说所有的操作都会影响这个,然后影响其他:借款拉高、还款降低、存款拉低、取回拉高。同时借贷的利息越多,用户存款所得到的利息才会高(存款利息的来源就是借贷的利息)。
首先明确借款的当前利率如何确定:
$$ #R^{asset}_t = \left { \begin{align*}
&#R^{asset}_{base} + \frac{U^{asset}t}{U^{asset}{optimal}}
\end{align*} \right. $$
我们知道借款分为浮动和稳定,而上述公式同时适用于两种,将其中的 $#$ 替换成为V
或S
即表示浮动和稳定两种。上面的式子表达的意思是:利率从 $#R^{asset}_{base}$ (由管理员设置)开始起步计算(相当于起步价),根据当前的资金使用率 $U^{asset}t $ (总债务/总储蓄)判断,如果小于最佳借款使用率 $U^{asset}{optimal}$(由管理员设置),基础利率加上对应比例slope1
(由管理员设置)的利率($\frac{U^{asset}t}{U^{asset}{optimal}} #R^{asset}{slope1}$)。超过最佳借款使用率 $U^{asset}{optimal}$ 就在基础利率和slope1
利率的和上,根据超过对应比例的slope2
(由管理员设置)的利率($\frac{U^{asset}t −U{optimal}}{1−U_{optimal}} #R^{asset}_{slope2}$)递增。
而存款利率(即流动性利率),理所当然的根据债务所产生的利息决定:
$$ LR_t = \overline{R_t} * U_t $$
其中 $U_t$ 是资金池的使用率,$\overline{R_t}$ 是总体借款利率,总体借款利率通过计算浮动债务和稳定债务的得到:
$$ \overline{R_t} =\left { \begin{align} &0, if \space D_t = 0 \ &\frac{V D_t V R_t+SD_t \overline{SR_t}}{D_t} , if \space D_t > 0 \end{align}\right. $$
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!