{"content":{"title":"AAVE v2白皮书","body":"#  什么是AAVE?\r\n## AAVE介绍\r\nAAVE 在区块链领域是一个开源和非托管的加密货币借贷协议。其目标是创建一个开放、透明并且不需要信任的金融生态系统，使用户能够通过区块链技术在全球范围内进行借贷活动。\r\n\r\n在 AAVE 平台上，用户可以存入或借出一系列的加密货币，包括 ETH（以太坊）、USDT（泰达币）、DAI（Dai 稳定币）等。存款人将他们的资产存入特定的市场合约，并获得代表他们存款的 aTokens。这些 aTokens 会随着时间的推移而产生利息。\r\n\r\nAAVE 平台的另一个独特之处是它支持 \"闪电贷\"。闪电贷是一种无抵押借款，借款人可以在一笔交易中借款和还款，只要他们在交易结束时归还借款，无需提供任何抵押物。\r\n\r\n总的来说，AAVE 是一个利用区块链技术创造的去中心化金融（DeFi）借贷平台。\r\n\r\n简单来说，AAVE就是区块链上的“银行”。\r\n\r\n\r\n## AAVE主要功能\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2023/08/BXSy801P64cfa7d058ed9.png)\r\n* 存款：AAVE支持主流的虚拟币存款。\r\n* 赎回：可以随时随回，获得利息。\r\n* 借款：如果你有存款，并且开启了抵押功能，那么可以借款一定额度的虚拟币，你可以选择定期还是活期计息方式，如果抵押物贬值或者借贷物品升值，有被清算的风险。\r\n* 还款：随时还款，并且支付利息。\r\n* 清算：当发现借款健康度不足1，可以申请清算，以一定折扣价清算获得抵押物。\r\n* 闪电贷：无需抵押物借款，需要自己编写智能合约方式使用借款，并且在逻辑最后要还款加支付闪电贷手续费。\r\n\r\nDefi APP https://app.aave.com/  (https://debank.com/ranking 是区块链上的巨鲸钱包信息，你可以复制钱包跟踪对AAVE的使用情况)\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2023/08/l8oqiymx64d0be6f1bb3e.png)\r\n \r\nDefiLlama上AAVE相关统计数据：https://defillama.com/protocol/aave\r\ngithub https://github.com/aave/protocol-v2\r\n白皮书 https://github.com/aave/protocol-v2/blob/master/aave-v2-whitepaper.pdf\r\n\r\n# 白皮书中的公式\r\n\r\n## 总借款（Total amount of liquidity borrowed）\r\n$$D^{assert}_t=VD^{assert}_t+SD^{assert}_t$$\r\n$$D^{assert}_t$$=总借款\r\n$$VD^{assert}_t$$动态利息借款\r\n$$SD^{assert}_t$$固定利息借款\r\n例如:使用动态利息借款15ETH,使用固定利息借款5ETH,那么总借款就是15+5=20\r\n\r\n## 借款使用率（utilisation rate）\r\n$$U^{assert}_t=\\begin{cases}0,if  L^{assert}_t=0 \\\\ \\frac {D^{assert}} {L^{assert}_t} , if  L^{assert}_t>0 \\end{cases}$$\r\n$$U^{assert}_t$$=借款使用率\r\n$$L^{assert}_t$$=流动数总额，其实就是用户存款总额\r\n例如公共借出去20ETH,总存款50ETH,那么借款使用率就是20/50=0.4\r\n\r\n## 借款利率（borrow rate）\r\n$$\\# R^{assert}_t=\\begin{cases} \\# R^{assert}_{base}+ \\frac{U^{assert}_t}{U^{assert}_{optimal}} \\# R^{assert}_{slope1} , if U^{assert}_t < U^{assert}_{optimal} \\\\ R^{assert}_{base} + \\# R^{assert}_{slope1} + \\frac{U^{assert}_t-U_{optimal}}{1-U_{optimal}} \\# R^{assert}_{slope2} ,if U^{assert}_t \\geq U_{optimal}   \\end{cases}$$\r\n\r\n $$\\# R^{assert}_t$$=借款利率\r\n $$ U^{assert}_{optimal} $$ =最佳借款使用率，管理员配置的。 （假设这里是0.45）\r\n$$ \\# R^{assert}_{base} $$= 借款基础利率，管理员配置的。（假设这里是0.02）\r\n$$\\# R^{assert}_{slope1}$$=slope1最高年化率，管理员配置的。（假设这里是0.18）\r\n$$\\# R^{assert}_{slope2}$$=slope2最高年利率。管理员配置的。（假设这里是3）\r\n\r\n简单来说，AAVE设置了$$U^{assert}_{optimal}$$（最佳借款使用率，例如下图是0.45）。当使用率少于的最佳借款使用率的时候，利率增长是很平缓的，当借款使用率超过这个值，利率显著增加。\r\n\r\nX轴是借款使用率，Y轴是借款利率。\r\n![image.png](https://img.learnblockchain.cn/attachments/2023/08/NLV0BT2U64cf4b5317a2c.png)\r\n\r\n借款利率三种情况。\r\n情况一：没有借款，那么借款利率就是0；\r\n\r\n情况二：例如当前借款使用率0.15。小于最佳借款使用率。\r\n借款利率= 0.02+0.15/0.45*0.18=0.08\r\n计算当前借款使用率的在0到最佳使用率的占比去换算0到slope1最高年化率的值。然后加上基本借款利率。\r\n\r\n情况三：例如当前借款使用率是0.6.大于最佳借款使用率。\r\n借款利率= $$0.02+0.18+ \\frac{0.6-0.45}{1-0.45}*3=1.059$$\r\n当前使用率减去最佳借款使用率，计算剩余的借款使用率在0到100%使用率的占比去换算0到slope2最高年化率，然后加上slope1最高年化率，再加上基础借款利率。\r\n\r\n另外：借款利率分为**活期利率**和**固定利率**，不同点是**借款基础利率**不同。\r\n \r\n## 总体借款利率（overall borrow rate）\r\n $$ \\overline {R ^{assert}_t}=\\frac{VD_tVR_t+SD_t \\overline{SR_t}}{D^{assert}_t}$$\r\n \r\n  $$ \\overline {R ^{assert}_t}$$=总体借款利率\r\n  $$ VD_t$$=动态利率借款 （假如200）\r\n  $$ VR_t $$ =动态借款的利率 （假如0.07）\r\n  $$ SD_t$$=固定利率借款 （假如100）\r\n  $$ \\overline{SR_t } $$ =固定借款的利率 （假如0.04）\r\n  $$D^{assert}_t $$ =总借款=动态利率借款+固定利率借款\r\n  例如：$$\\frac {200*0.07+100*0.04}{200+100}=0.06$$\r\n其实很好理解，按各自权重得出总体借款利率\r\n\r\n## 流动性利率 （current liquidity rate）\r\n$$  LR_t= \\overline {R_t} U_t$$\r\n$$LR_t=流动性利率$$ \r\n$$   \\overline {R_t}$$=总体借款利率\r\n$$ U_t$$=借款使用率\r\n\r\n \r\n## 流动性累计指数 （cumulated liquidity index）\r\n这里使用线性利率公式计算复利，每次存钱、取钱、借钱、赎回、清算操作等动作。\r\n$$LI_t=(LR_t \\Delta T_{year}+1)LI_{t-1}$$\r\n$$LI_t$$=流动性累计指数。  其中T=0时 $$LI_0=1$$  \r\n$$T_{year}=3153600$$   意思一年含有3153600秒\r\n$$\\Delta T=T_c-T_p$$  意思复利周期的时长（单位秒），例如T_c是当前时刻，T_p指上一次时刻\r\n$$LR_t$$  =t时刻的流动性利率\r\n\r\n例如:\r\n0时刻，$$LI_0=1$$    假如：$$LR_t=0.05$$  \r\n$$t1$$时刻  $$LI_1=(LR_t \\Delta T_{year}+1)LI_0$$    假如：t1时刻=第10秒   $$LI_1=(0.05*(10/31536000)+1)*LI_0$$\r\n$$t2$$时刻  $$LI_2=(LR_t \\Delta T_{year}+1)LI_1$$    假如：t2时刻=第25秒   $$LI_2=(0.05*(15/31536000)+1)*LI_1$$    注意：15是25-10得来的。注意看$$\\Delta T$$的定义\r\n其实很好理解，更新累计指数的时候，根据距离上次计息动作的间隔秒数，然后根据年华率，复利计算方式放大累计指数。\r\n所以这里的复利周期是距离上次计息动作的间隔秒数。\r\n\r\n\r\n ## 借款累积指数。（the cumulated variable borrow index）\r\n 这里使用复利公式计算利息，每次存钱、取钱、借钱、赎回、清算操作等动作。\r\n $$VI_t=(1+ \\frac{VR_t}{T_{year}})^{\\Delta T}VI_{t-1}$$\r\n$$VI_t$$=借款累积指数\r\n$$VR_t$$=借款利率\r\n$$T_{year}$$=365*24*60*60=3153600 意思一年含有3153600秒\r\n$$\\Delta T$$=t秒\r\n因为在链上计算成本高，AAVE使用了泰勒展开式模拟这个公式，为了避免昂贵的求幂，使用二项式近似进行计算。\r\nhttps://github.com/aave/protocol-v2/blob/ce53c4a8c8620125063168620eba0a8a92854eb8/contracts/protocol/libraries/math/MathUtils.sol#L45\r\n不举例子了。任务每次计算复利的时候，$VI_t$都会大一点点，跟流动性累计指数相似。\r\n注意这里的复利周期是每秒计算的。\r\n \r\n ## 储备正常化收入 (reserve normalised income)\r\n $$NI_t=(LR_t\\Delta T_{year} + 1)LI_{t-1}$$\r\n我也不知道怎么解释 。我就认为是流动性利率累计指数吧\r\n\r\n \r\n ## 流动性缩放余额（Scaled Balance） \r\n 因为每次计算复利动作的时候，余额是会变化的，如果每个用户都更新累计指数在链上是不现实的。\r\n$ScB_t(x)$ =流动性缩放余额\r\n其他：\r\n$$ScB_t(0)=0$$\r\n$$ScB_t(x)=ScB_{t-1}+\\frac{m}{NI_t}$$  这里指充值\r\n$$ScB_t(x)=ScB_{t-1}-\\frac{m}{NI_t}$$  这里指提现\r\n\r\n 例如：\r\n第0秒，$Scb_{t0}(m_{0})=0$\r\n第t1秒，用户存款$m_1$金额。缩放余额是 $Scb_{t1}(m_{1})=Scb_{t0}(m_{0})+ \\frac {m_{1}} {NI_{t1}}$  这时候乘以当时的累积指数$NI_{t1}$,就可以得到余额m1，注意这里的$Scb_{t0}(m_{0})=0$\r\n第t2秒，用户存款$m_2$金额。缩放余额是 $Scb_{t2}(m_{2})=Scb_{t1}(m_{1})+ \\frac {m_{2}} {NI_{t2}}$ 这时候乘以当时的累积指数$NI_{t2}$,就可以得到余额$Scb_{t1}(m_{1})*NI_{t2}$ + m2,这里的$Scb_{t1}(m_{1})*NI_{t2}$是t2-t1这段时间m1复利结果。\r\n这里的累积指数实际上是复利放大的结果，用户存款的时候只需要将金额除以累积指数得到缩放余额再加上之前的缩放余额，提现亦然，如果要查看余额只需要缩放余额乘以下累积指数就等于余额了，就算再过一段时间，缩放余额乘以累积指数（累积指数会在任何AAVE智能合约写入操作的时候更新，例如存款、提现、赎回等等）都是算上复利的余额。这样做有什么好处呢？这个资产所有用户都可以公用一个累积指数得到余额，而不需要各自保存自己的复利余额。这在区块链储存昂贵的情况下是非常有必要的。\r\n\r\n\r\n## 动态借款的缩放欠款（variable scaled balance） \r\n和**流动性缩放余额**计算方式一样，唯一不同就是$NI_t$换成$VI_t$\r\n\r\n## 用户固定利率（overall stable rate）\r\n$$\\overline{SR_t} = \\frac{SD_{t-1} \\overline{SR_{t-1}}+SB(x)SR(x)}{SD_{t-1}+SB_x} $$ （借款)\r\n$$\\overline{SR_t} = \\frac{SD_{t-1} \\overline{SR_{t-1}}-SB(x)SR(x)}{SD_{t-1}-SB_x} $$ （还款）\r\n$$\\overline{SR_t}$$=用户固定利率\r\n$$SD_t$$=用户之前的的固定借款（如果之前没借款就是0）\r\n$$\\overline{SR_{t-1}}$$=用户之前的固定利率（如果之前没借款就是0）\r\n$$SB(x)$$=用户的新借款\r\n$$SR(x)$$=最新固定借款利率（看上面**借款利率**定义）\r\n\r\n例如用户借款100，当时的固定利率是0.2。过了段时间。用户借款200，当时的固定利率是0.26.那么这时候用户的固定利率=$\\frac{100*0.2+200*0.26}{100+200}$=0.24\r\n \r\n ## 健康度\r\n$$HF=\\frac{CollateralinETH^{assert} *LT^{assert} }{CB^x+TotalFeesETH}$$\r\n* 其中HF=健康度\r\n* $$CollateralinETH^{assert}$$ =抵押物价值 \r\n* $$LT^{assert}$$=折算率（例如价值100ETH,折算率=0.8.那么抵押物在只价值80ETH）\r\n* $$CB^x$$=借款 \r\n* $$ TotalFeesETH $$=清算费\r\n注意：以上都是换算成ETH计算的，健康度少于1就可以被清算。\r\n例如：用户存入0.5BTC,BTC（30000U）和ETH(2000U)的汇率=15，并且作为抵押物,抵押折算率0.8，清算费=抵押物的0.1。 那么他借款8800U。\r\n\r\n健康度=$$\\frac{0.5*15*0.8}{8800+6*0.1}=1.2$$  \r\n \r\n \r\n # 主要代码模块介绍\r\n\r\n## 业务主入口\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/lendingpool/LendingPool.sol\r\n\r\n## aToken\r\naToken是存款记账的智能合约，继承ERC20协议。当用户存款,那么aToken就mint对应的**缩放余额**的aToken,用户提现的时候就brun。\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/tokenization/AToken.sol\r\n\r\n## StableDebtToken\r\n* StableDebtToken是选择固定利率借款记账智能合约，继承ERC20，但是没有实现ERC20的转账接口，用户发生借款，就通过mint对应的token转给用户，用户还款的时候burn.\r\n* _usersStableRate 字段记录的用户平均固定借款利率\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/tokenization/StableDebtToken.sol\r\n\r\n## VariableDebtToken\r\nStableDebtToken是选择动态利率借款记账智能合约，继承ERC20，但是没有实现ERC20的转账接口,用户发生借款，就通过mint对应的token转给用户，用户还款的时候burn.\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/tokenization/StableDebtToken.sol\r\n\r\n## 存款池子配置\r\n每个池子对应的配置信息。为了解释储存插槽的gas，使用了bitmap方式。配置有：是否启用、是否冻结、是否允许借贷等等。 \r\n \r\n池子配置类型信息\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/libraries/types/DataTypes.sol\r\n\r\n池子配置帮助类库\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/libraries/configuration/ReserveConfiguration.sol\r\n\r\n## 用户配置信息\r\n记录用户使用池子的情况，例如是否借钱，是否有存款、是否开启抵押等等信息。 这样再借款和还款动作的时候，就不用遍历所有池子的数据，介绍gas消耗。\r\nhttps://github.com/aave/protocol-v2/blob/master/contracts/protocol/libraries/configuration/UserConfiguration.sol\r\n\r\nAAVE针对借款人还有两个动作。\r\n## 切换借款方式（例如固定利率和动态利率切换）\r\n有人借款发现这个方法后，可以监控固定利率，只要发现当前固定利率足够比所持的固定利率低的时候，就切换成新的固定利率模式。这里涉及到的公式 **用户固定利率**\r\nhttps://github.com/aave/protocol-v2/blob/ce53c4a8c8620125063168620eba0a8a92854eb8/contracts/protocol/lendingpool/LendingPool.sol#L297\r\n\r\n## 重新平衡固定利率\r\n动态利率和固定利率的切换功能是为了借款人更方便的控制风险，如果有人像上面那样切换利率降低自己的借款利息，也意味着提供流动性的人会少获得利息。AAVE提供这个“重新平衡固定利率”的动作，这个方法是任何人都可以调用，参数是池子地址和借款人地址。调用这个方法还有两个前提，池子使用率达到95%，流动性提供者的收益率低于设置的阈值。\r\nhttps://github.com/aave/protocol-v2/blob/ce53c4a8c8620125063168620eba0a8a92854eb8/contracts/protocol/lendingpool/LendingPool.sol#L350\r\n\r\n## 闪电贷\r\n闪电贷可以一次性借多笔资产。\r\n如果闪电贷借款不是常规模式，可以自动变更为借款逻辑，前提是申请者有足够的抵押物。（好鸡肋的功能啊，白皮书中还专门举了两个例子。）\r\nhttps://github.com/aave/protocol-v2/blob/ce53c4a8c8620125063168620eba0a8a92854eb8/contracts/protocol/lendingpool/LendingPool.sol#L483\r\n\r\n## 清算\r\n这里使用了delegatecall方式调用清算逻辑，可能AAVE团队还是担心清算出现各种问题，通过更新实现合约地址可以更新实现逻辑。上面公式中有提到 **健康度**\r\nhttps://github.com/aave/protocol-v2/blob/ce53c4a8c8620125063168620eba0a8a92854eb8/contracts/protocol/lendingpool/LendingPool.sol#L425\r\n\r\n更详细的代码注释请看这里：\r\nhttps://github.com/Dapp-Learning-DAO/Dapp-Learning/blob/main/defi/Aave/contract/readme.md"},"author":{"user":"https://learnblockchain.cn/people/15238","address":"0x31110e53f4044c2b757d906bda84b5acf9b0c3ca"},"history":"QmRjgG7Rc2qqmN1L4HTyhgs9CNWwTHqNL4yZwVJFXmSbf2","timestamp":1692084699,"version":1}