引言
随着去中心化金融(DeFi)生态系统的迅速发展,AAVEV2作为领先的去中心化借贷协议之一,在提供创新借贷与流动性管理解决方案方面始终处于行业前沿。其独特的无信任机制和高效的资本利用率吸引了大量用户和机构的参与。然而,随着其应用的普及及所涉及的资金规模逐步扩大,安全审计和风控措施的重要性日益凸显。本手册将深入探讨AAVEV2协议的核心设计、关键功能及相关审计要点。项目背景概述
AAVEV2是一个基于EthereumBlockchain构建的开放式借贷平台,允许用户存入各种ERC-20Tokens并从中赚取利息,同时也允许以支付利息的形式借用市场中的Tokens。通过引入“利率市场”的概念,AAVEV2实现了去中心化的资金池管理和自动化的利率调整机制。此外,AAVEV2还提供了闪电贷、抵押贷款和Tokens交换等高级功能,以满足用户的多样化需求,进一步巩固了其在DeFi领域的领先地位。项目架构分析
OraclesProxy:依赖外部预言机(Chainlink)提供资产市场价格数据,用于评估用户抵押资产的价值,确保借贷行为的定价准确性和系统的稳定性。
LendingRateOracle:根据系统的状态和市场情况,提供动态的借贷利率,优化资本利用率和流动性。配置与管理
Configurator:用于配置系统参数,如不同资产的风险参数和借贷限额,管理储备金的各种操作,包括激活、借款、抵押、冻结、更新参数及在紧急情况下启用或禁用功能。确保协议可以根据市场变化进行动态调整。其他关键功能
LiquidationManager:当用户抵押品价值下降至清算门槛以下时,管理清算操作,保护系统的资金安全。清算人可以通过清算操作获得奖励。
ReservesBalances:存储系统的储备资金数据,用于计算和调整利率策略。利率策略
InterestRateStrategy:根据市场和用户需求,动态调整利率以实现最佳资本配置,同时考虑流动性风险,确保系统在不同市场条件下的灵活性和稳定性。
尽管存在两种利率模型(稳定型和浮动型),但是其模型计算都类似于一个拐点型模型。在拐点最优利用率下的slope1和超过最优利用率的slope2分段计算,且在这个条件下也分为固定利率模型和可变利率模型。
用户通过调用LendingPool合约的deposit函数进行存款,该函数接受四个参数:资产地址、存款金额、接收方地址及推荐码。首先验证合约未处于启用状态,然后通过ValidationLogic.validateDeposit验证存款金额必须大于0,同时确认储备处于激活状态且未被冻结。接着系统会更新储备状态,调用reserve.updateState()更新流动性累积指数和可变借款指数,并计算时间段内产生的利息,其中一部分利息会被铸造并转入协议国库。
公式如下:
与Compound相比,AAVEV2的提现过程有以下主要特点:
使用aToken代表用户在协议中的存款,提现实际上是销毁aToken。
允许用户提现到指定地址(通过to参数),增加了灵活性。
提供了部分提现和全额提现的选项。
在提现验证中,AAVE使用了更复杂的balanceDecreaseAllowed函数来检查提现对用户整体抵押品状况的影响。
AAVE的提现过程直接更新了利率,而不是像Compound那样通过accrueInterest函数来更新。借贷
用户通过borrow函数进行借贷,执行借款会先从价格预言机获取资产的当前价格,将借款金额转换为ETH等价。随后通过ValidationLogic.validateBorrow检查以及GenericLogic.calculateUserAccountData用户借款是否合法,计算包括onBehalfOf地址的总抵押资产、总债务、当前贷款价值比率(LTV)、清算阈值和健康因子以及市场的稳定性等(类似于Compound的getHypotheticalAccountLiquidityInternal),是否有足够的抵押资产借贷。reserve.updateState更新储备状态,如利率和借款指数(这一步类似于Compound中的accrueInterest),用于计算并更新利息。
随后根据用户选择进行的interestRateMode(稳定利率或浮动利率)生成债务,选择不同的利率模型的Tokens合约来铸造Tokens。同时,铸造Tokens时也会进行检查,如果onBehalfOf地址不是调用者,则会在Tokens合约中减去其对调用用户的借贷授权。如果是用户的首次借款,会将其配置为活跃借款者。DebtToken铸造给用户后,协议会通过updateInterestRates更新借款利率,反映借款后的新利率和储备池的变化。如果用户请求释放借款的底层资产,协议会将资产直接转移给用户。
与Compound相比,AAVEV2的借贷过程有以下主要特点:
支持稳定和可变两种利率模式。
使用单独的验证逻辑合约进行借贷验证。
使用债务Tokens(DebtToken)来表示用户的借款。
支持信用委托,允许用户代表其他地址进行借款。
还款
用户通过repay函数进行还款,首先获取用户的当前债务(包括稳定债务stableDebt和浮动债务variableDebt)。根据用户选择的利率模式(稳定或浮动),由ValidationLogic.validateRepay验证用户的还款操作合法性,包括用户的债务余额是否足够进行还款。根据用户选择的利率模式来确定还款的具体债务类型(稳定利率或浮动利率)。如果用户要还的金额小于当前债务余额,系统会使用用户提供的还款金额进行部分还款;否则,将偿还所有债务。更新储备的状态updateState,用于计算并更新协议中的利息、借贷量以及借贷指数。随后燃烧相应的稳定债务Tokens,并通过updateInterestRates更新借款利率。此时,如果用户的所有债务(包括稳定和浮动债务)在还款后为零,则会将该用户的借款状态标记为false,表示用户不再借款。最后用户将还款金额从其账户转移到协议的aToken合约地址。
与Compound相比,AAVEV2的还款过程有以下主要特点:
支持稳定和浮动两种利率模式的还款。
使用DebtToken来表示和管理债务,还款时燃烧对应债务Tokens。
支持部分还款和全额还款,并分别处理稳定债务和浮动债务。
支持用户通过信用委托为其他地址还款。清算
用户通过lendingpool的liquidationCall函数进行清算,函数通过代理模式调用LendingPoolCollateralManager的liquidationCall函数,确保函数的成功执行。首先GenericLogic.calculateUserAccountData获取抵押品资产及债务资产的储备数据和用户的配置信息,计算用户的健康因子,并通过getUserCurrentDebt获取用户的当前稳定和可变负债。
ValidationLogic.validateLiquidationCall函数验证清算调用的合法性,包括检查用户的健康因子、债务状态和抵押品配置。若健康因子小于阀值,已作为抵押品,且两种债务都不为0则验证通过。接着计算用户的最大可清算债务,并确定实际需要清算的债务数量。如果清算的债务超过用户的可用抵押物,将调整清算金额。
如果清算人选择接收被清算人抵押的底层资产,需要确保抵押物储备中有足够的流动性。更新债务储备的状态,并根据清算人是否接收aToken情况,燃烧相应数量的可变和稳定债务Tokens。更新债务的利率,反映清算后的市场情况。清算人奖励如果选择接收aToken,清算人将获得相应数量的aToken。如果不接受aToken,则更新其抵押状态和抵押物的利率,从用户账户中燃烧掉对应数量的aToken,将底层资产转移给清算人。最后,将清算所需的债务资产从清算人转移到相应的储备aToken中,完成清算过程。
与Compound相比,AAVEV2的清算过程有以下主要特点:
支持多种抵押品和债务资产的组合清算。
允许清算人选择接收aToken或底层资产。
清算过程更加模块化,将验证逻辑、计算逻辑等分离到不同的函数中。
支持稳定利率和可变利率两种债务类型的清算。闪电贷
用户通过lendingpool的flashLoan函数进行闪电贷。作为借贷协议的闪电贷,可以允许当前闪电贷立刻还款或是作为债务来后续还款,其中以传入的modes参数不同而决定。0为立刻还款,1为作为稳定型债务,2为浮动型债务。
函数首先通过ValidationLogic.validateFlashloan检查输入参数匹配,计算闪电贷所需的溢价成本,并直接将所需的aToken转给接收者地址。调用接受者的executeOperation操作实现预设的闪电贷。AAVE实现的闪电贷操作已包括了兑换,兑换清算,以及兑换偿还操作。在executeOperation完成以上操作后,记录需偿还的闪电贷金额和相应的费用。如果用户选择以非债务模式归还资金:系统更新储备状态,累积储备流动性以及更新流动性指数。最后再从请求者转移资金和费用至储备池。若用户选择以债务模式处理,则调用_executeBorrow,开启相应的债务头寸。转换债务模式
在AAVEV2中,用户可以通过swapBorrowRateMode函数在稳定利率模式和浮动利率模式之间切换。首先通过getUserCurrentDebt函数获取用户在目标资产上的当前稳定利率债务和浮动利率债务,确定用户的债务状况。接着调用ValidationLogic.validateSwapRateMode函数验证切换操作是否合法。其中检查用户是否有足够的稳定或浮动债务以支持模式切换,确保切换目标模式符合资产的配置和用户的债务情况。调用reserve.updateState更新资产储备的状态,确保储备数据最新。随后就是对于两种债务Tokens的相互转换,燃烧稳定债务Tokens铸造浮动债务Tokens或是燃烧浮动债务Tokens铸造稳定债务Tokens。转换完成后,reserve.updateInterestRates更新目标资产利率,确保反映当前市场状态和用户债务的变化。安全漏洞Checklist空市场导致的舍入漏洞
在AAVE和Compound中,都存在空市场中精度损失而造成的漏洞问题。如果在一个空市场的情况(即没有用户在市场中进行借贷),由于cumulateToLiquidityIndex函数中liquidityIndex的值依赖于合约对应的底层资产Tokens的数量,所以攻击者可以通过闪电贷向合约存入大量的底层资产Tokens来操纵aToken的价格。
与之前Compoundfork项目HundredFinance第一次被黑相似,在HopeLend事件中,攻击者先操纵liquidityIndex将hETHWBTC兑WBTC的价值控制为1:1,通过兑换底层资产以及借贷的方式又提高liquidityIndex的值。随后通过循环的闪电贷不断调用_handleFlashLoanRepayment函数。
审计要点:在审计时,需要关注兑换率的计算方式是否容易被操控以及舍入的方式是否恰当,同时可以建议项目团队在新的市场创建后立刻铸造aToken,以防止市场为空进而被操控。ERC677/ERC777Tokens导致的重入漏洞
与之前Compoundfork项目HundredFinance第二次被黑相同,在Agave攻击事件中,攻击者在没有任何负债的情况下调用了liquidateCall函数来清算自己。而清算的Tokens是GnosisChain链上使用的ERC-677标准Tokens,该类Tokens转账时会外部调用接收地址的函数,所以使得清算合约调用了攻击合约,攻击合约在此过程中存入了2728个通过闪电贷获取的WETH,铸造出2728aWETH,并以此为抵押,借出了Agave项目中所有可用资产。外部调用结束后,liquidationCall函数直接清算了攻击者之前存入的2728aWETH,并将其转给清算者。
审计要点:在审计时,需特别关注与外部第三方协议的交互代码。重点评估外部合约的输入和输出是否经过严格限制,交互逻辑是否对协议核心模型或资金安全产生潜在影响,输入数据是否经过清理和验证,防止恶意数据引发安全问题。通过严格审查外部交互的代码逻辑以及数据验证机制,可有效降低此类漏洞风险。Tokens与利率策略兼容问题
在Polygon链上,AAVE部署过程中,由于InterestRateStrategy设置不兼容的问题导致功能异常,错误地为WETH设置了不兼容的利率策略。
错误设置的InterestRateStrategy合约中的interface如下:
而AAVEV2的LendingPool实现的代码如下:
(参考来源:https://x.com/mookim_eth/status/1659589328727859205)
由于接口不兼容,新InterestRateStrategy无法正常被LendingPool调用,直接导致AAVEV2的WETH池功能中断,用户无法存入或提取ETH。
审计要点:在审计时,需确保代码(或fork)中关键组件的接口完全兼容。同时,尽管以上问题并不是由多链特性导致的原因,但是审计时仍需要注意不同链的特性下是否会造成非预期的结果。DustTokens问题
AAVE的存款和取款会通过setUsingAsCollateral函数设置usingAsCollateral来实现,从而灵活地管理抵押策略。当外部协议或合约通过AAVE借贷函数第一次借入资金时,借贷函数会将usingAsCollateral设置为true。当外部协议或合约从AAVE完全提取资金时,AAVE中协议处理程序的usingAsCollateral状态将被设置为false。但实际上,AAVE在计算取款需要烧掉的aToken数量时,此时如果由于算术精度误差,协议处理程序中可能还有极少的aToken剩余。因此,当协议处理程序下次向AAVE存款时,usingAsCollateral将不会变动,依然设置为true,由于协议处理程序合约中没有调用setUserUseReserveAsCollateral函数的接口,这可能导致协议处理程序无法再执行借款操作。
审计要点:在审计时,需要对所调用的协议有充分的熟悉度,充分了解其特性的情况下,判断是否对于其与外部协议交互存在一定的兼容性问题,如Tokens兼容性、调用实现逻辑兼容性等。
写在最后
本手册深入探讨了AAVEV2协议的核心设计、关键功能及相关审计要点,我们希望该手册可以更好地帮助开发人员和安全研究人员识别潜在风险并确保协议的安全运行。由于篇幅限制,本文省略了部分代码和图片,读者可点击文末的阅读原文跳转至GitHub阅读完整版(https://github.com/slowmist/AAVE-V2-Security-Audit-Checklist)。
免责声明:慢雾:AAVE V2 安全审计手册文章转发自互联网,版权归其所有。
文章内容不代表本站立场和任何投资暗示。加密货币市场极其波动,风险很高,可能不适合所有投资者。在投资加密货币之前,请确保自己充分了解市场和投资的风险,并考虑自己的财务状况和风险承受能力。此外,请遵循您所在国家的法律法规,以及遵守交易所和钱包提供商的规定。对于任何因使用加密货币所造成的投资损失或其他损失,本站不承担任何责任。
Copyright © 2021.Company 元宇宙YITB.COM All rights reserved.元宇宙YITB.COM