引言
隨著去中心化金融(DeFi)生態(tài)系統(tǒng)的迅速發(fā)展,AAVEV2作為領(lǐng)先的去中心化借貸協(xié)議之一,在提供創(chuàng)新借貸與流動(dòng)性管理解決方案方面始終處于行業(yè)前沿。其獨(dú)特的無(wú)信任機(jī)制和高效的資本利用率吸引了大量用戶和機(jī)構(gòu)的參與。然而,隨著其應(yīng)用的普及及所涉及的資金規(guī)模逐步擴(kuò)大,安全審計(jì)和風(fēng)控措施的重要性日益凸顯。本手冊(cè)將深入探討AAVEV2協(xié)議的核心設(shè)計(jì)、關(guān)鍵功能及相關(guān)審計(jì)要點(diǎn)。項(xiàng)目背景概述
AAVEV2是一個(gè)基于EthereumBlockchain構(gòu)建的開(kāi)放式借貸平臺(tái),允許用戶存入各種ERC-20Tokens并從中賺取利息,同時(shí)也允許以支付利息的形式借用市場(chǎng)中的Tokens。通過(guò)引入“利率市場(chǎng)”的概念,AAVEV2實(shí)現(xiàn)了去中心化的資金池管理和自動(dòng)化的利率調(diào)整機(jī)制。此外,AAVEV2還提供了閃電貸、抵押貸款和Tokens交換等高級(jí)功能,以滿足用戶的多樣化需求,進(jìn)一步鞏固了其在DeFi領(lǐng)域的領(lǐng)先地位。項(xiàng)目架構(gòu)分析
OraclesProxy:依賴外部預(yù)言機(jī)(Chainlink)提供資產(chǎn)市場(chǎng)價(jià)格數(shù)據(jù),用于評(píng)估用戶抵押資產(chǎn)的價(jià)值,確保借貸行為的定價(jià)準(zhǔn)確性和系統(tǒng)的穩(wěn)定性。
LendingRateOracle:根據(jù)系統(tǒng)的狀態(tài)和市場(chǎng)情況,提供動(dòng)態(tài)的借貸利率,優(yōu)化資本利用率和流動(dòng)性。配置與管理
Configurator:用于配置系統(tǒng)參數(shù),如不同資產(chǎn)的風(fēng)險(xiǎn)參數(shù)和借貸限額,管理儲(chǔ)備金的各種操作,包括激活、借款、抵押、凍結(jié)、更新參數(shù)及在緊急情況下啟用或禁用功能。確保協(xié)議可以根據(jù)市場(chǎng)變化進(jìn)行動(dòng)態(tài)調(diào)整。其他關(guān)鍵功能
LiquidationManager:當(dāng)用戶抵押品價(jià)值下降至清算門檻以下時(shí),管理清算操作,保護(hù)系統(tǒng)的資金安全。清算人可以通過(guò)清算操作獲得獎(jiǎng)勵(lì)。
ReservesBalances:存儲(chǔ)系統(tǒng)的儲(chǔ)備資金數(shù)據(jù),用于計(jì)算和調(diào)整利率策略。利率策略
InterestRateStrategy:根據(jù)市場(chǎng)和用戶需求,動(dòng)態(tài)調(diào)整利率以實(shí)現(xiàn)最佳資本配置,同時(shí)考慮流動(dòng)性風(fēng)險(xiǎn),確保系統(tǒng)在不同市場(chǎng)條件下的靈活性和穩(wěn)定性。
盡管存在兩種利率模型(穩(wěn)定型和浮動(dòng)型),但是其模型計(jì)算都類似于一個(gè)拐點(diǎn)型模型。在拐點(diǎn)最優(yōu)利用率下的slope1和超過(guò)最優(yōu)利用率的slope2分段計(jì)算,且在這個(gè)條件下也分為固定利率模型和可變利率模型。
用戶通過(guò)調(diào)用LendingPool合約的deposit函數(shù)進(jìn)行存款,該函數(shù)接受四個(gè)參數(shù):資產(chǎn)地址、存款金額、接收方地址及推薦碼。首先驗(yàn)證合約未處于啟用狀態(tài),然后通過(guò)ValidationLogic.validateDeposit驗(yàn)證存款金額必須大于0,同時(shí)確認(rèn)儲(chǔ)備處于激活狀態(tài)且未被凍結(jié)。接著系統(tǒng)會(huì)更新儲(chǔ)備狀態(tài),調(diào)用reserve.updateState()更新流動(dòng)性累積指數(shù)和可變借款指數(shù),并計(jì)算時(shí)間段內(nèi)產(chǎn)生的利息,其中一部分利息會(huì)被鑄造并轉(zhuǎn)入?yún)f(xié)議國(guó)庫(kù)。
公式如下:
與Compound相比,AAVEV2的提現(xiàn)過(guò)程有以下主要特點(diǎn):
使用aToken代表用戶在協(xié)議中的存款,提現(xiàn)實(shí)際上是銷毀aToken。
允許用戶提現(xiàn)到指定地址(通過(guò)to參數(shù)),增加了靈活性。
提供了部分提現(xiàn)和全額提現(xiàn)的選項(xiàng)。
在提現(xiàn)驗(yàn)證中,AAVE使用了更復(fù)雜的balanceDecreaseAllowed函數(shù)來(lái)檢查提現(xiàn)對(duì)用戶整體抵押品狀況的影響。
AAVE的提現(xiàn)過(guò)程直接更新了利率,而不是像Compound那樣通過(guò)accrueInterest函數(shù)來(lái)更新。借貸
用戶通過(guò)borrow函數(shù)進(jìn)行借貸,執(zhí)行借款會(huì)先從價(jià)格預(yù)言機(jī)獲取資產(chǎn)的當(dāng)前價(jià)格,將借款金額轉(zhuǎn)換為ETH等價(jià)。隨后通過(guò)ValidationLogic.validateBorrow檢查以及GenericLogic.calculateUserAccountData用戶借款是否合法,計(jì)算包括onBehalfOf地址的總抵押資產(chǎn)、總債務(wù)、當(dāng)前貸款價(jià)值比率(LTV)、清算閾值和健康因子以及市場(chǎng)的穩(wěn)定性等(類似于Compound的getHypotheticalAccountLiquidityInternal),是否有足夠的抵押資產(chǎn)借貸。reserve.updateState更新儲(chǔ)備狀態(tài),如利率和借款指數(shù)(這一步類似于Compound中的accrueInterest),用于計(jì)算并更新利息。
隨后根據(jù)用戶選擇進(jìn)行的interestRateMode(穩(wěn)定利率或浮動(dòng)利率)生成債務(wù),選擇不同的利率模型的Tokens合約來(lái)鑄造Tokens。同時(shí),鑄造Tokens時(shí)也會(huì)進(jìn)行檢查,如果onBehalfOf地址不是調(diào)用者,則會(huì)在Tokens合約中減去其對(duì)調(diào)用用戶的借貸授權(quán)。如果是用戶的首次借款,會(huì)將其配置為活躍借款者。DebtToken鑄造給用戶后,協(xié)議會(huì)通過(guò)updateInterestRates更新借款利率,反映借款后的新利率和儲(chǔ)備池的變化。如果用戶請(qǐng)求釋放借款的底層資產(chǎn),協(xié)議會(huì)將資產(chǎn)直接轉(zhuǎn)移給用戶。
與Compound相比,AAVEV2的借貸過(guò)程有以下主要特點(diǎn):
支持穩(wěn)定和可變兩種利率模式。
使用單獨(dú)的驗(yàn)證邏輯合約進(jìn)行借貸驗(yàn)證。
使用債務(wù)Tokens(DebtToken)來(lái)表示用戶的借款。
支持信用委托,允許用戶代表其他地址進(jìn)行借款。
還款
用戶通過(guò)repay函數(shù)進(jìn)行還款,首先獲取用戶的當(dāng)前債務(wù)(包括穩(wěn)定債務(wù)stableDebt和浮動(dòng)債務(wù)variableDebt)。根據(jù)用戶選擇的利率模式(穩(wěn)定或浮動(dòng)),由ValidationLogic.validateRepay驗(yàn)證用戶的還款操作合法性,包括用戶的債務(wù)余額是否足夠進(jìn)行還款。根據(jù)用戶選擇的利率模式來(lái)確定還款的具體債務(wù)類型(穩(wěn)定利率或浮動(dòng)利率)。如果用戶要還的金額小于當(dāng)前債務(wù)余額,系統(tǒng)會(huì)使用用戶提供的還款金額進(jìn)行部分還款;否則,將償還所有債務(wù)。更新儲(chǔ)備的狀態(tài)updateState,用于計(jì)算并更新協(xié)議中的利息、借貸量以及借貸指數(shù)。隨后燃燒相應(yīng)的穩(wěn)定債務(wù)Tokens,并通過(guò)updateInterestRates更新借款利率。此時(shí),如果用戶的所有債務(wù)(包括穩(wěn)定和浮動(dòng)債務(wù))在還款后為零,則會(huì)將該用戶的借款狀態(tài)標(biāo)記為false,表示用戶不再借款。最后用戶將還款金額從其賬戶轉(zhuǎn)移到協(xié)議的aToken合約地址。
與Compound相比,AAVEV2的還款過(guò)程有以下主要特點(diǎn):
支持穩(wěn)定和浮動(dòng)兩種利率模式的還款。
使用DebtToken來(lái)表示和管理債務(wù),還款時(shí)燃燒對(duì)應(yīng)債務(wù)Tokens。
支持部分還款和全額還款,并分別處理穩(wěn)定債務(wù)和浮動(dòng)債務(wù)。
支持用戶通過(guò)信用委托為其他地址還款。清算
用戶通過(guò)lendingpool的liquidationCall函數(shù)進(jìn)行清算,函數(shù)通過(guò)代理模式調(diào)用LendingPoolCollateralManager的liquidationCall函數(shù),確保函數(shù)的成功執(zhí)行。首先GenericLogic.calculateUserAccountData獲取抵押品資產(chǎn)及債務(wù)資產(chǎn)的儲(chǔ)備數(shù)據(jù)和用戶的配置信息,計(jì)算用戶的健康因子,并通過(guò)getUserCurrentDebt獲取用戶的當(dāng)前穩(wěn)定和可變負(fù)債。
ValidationLogic.validateLiquidationCall函數(shù)驗(yàn)證清算調(diào)用的合法性,包括檢查用戶的健康因子、債務(wù)狀態(tài)和抵押品配置。若健康因子小于閥值,已作為抵押品,且兩種債務(wù)都不為0則驗(yàn)證通過(guò)。接著計(jì)算用戶的最大可清算債務(wù),并確定實(shí)際需要清算的債務(wù)數(shù)量。如果清算的債務(wù)超過(guò)用戶的可用抵押物,將調(diào)整清算金額。
如果清算人選擇接收被清算人抵押的底層資產(chǎn),需要確保抵押物儲(chǔ)備中有足夠的流動(dòng)性。更新債務(wù)儲(chǔ)備的狀態(tài),并根據(jù)清算人是否接收aToken情況,燃燒相應(yīng)數(shù)量的可變和穩(wěn)定債務(wù)Tokens。更新債務(wù)的利率,反映清算后的市場(chǎng)情況。清算人獎(jiǎng)勵(lì)如果選擇接收aToken,清算人將獲得相應(yīng)數(shù)量的aToken。如果不接受aToken,則更新其抵押狀態(tài)和抵押物的利率,從用戶賬戶中燃燒掉對(duì)應(yīng)數(shù)量的aToken,將底層資產(chǎn)轉(zhuǎn)移給清算人。最后,將清算所需的債務(wù)資產(chǎn)從清算人轉(zhuǎn)移到相應(yīng)的儲(chǔ)備aToken中,完成清算過(guò)程。
與Compound相比,AAVEV2的清算過(guò)程有以下主要特點(diǎn):
支持多種抵押品和債務(wù)資產(chǎn)的組合清算。
允許清算人選擇接收aToken或底層資產(chǎn)。
清算過(guò)程更加模塊化,將驗(yàn)證邏輯、計(jì)算邏輯等分離到不同的函數(shù)中。
支持穩(wěn)定利率和可變利率兩種債務(wù)類型的清算。閃電貸
用戶通過(guò)lendingpool的flashLoan函數(shù)進(jìn)行閃電貸。作為借貸協(xié)議的閃電貸,可以允許當(dāng)前閃電貸立刻還款或是作為債務(wù)來(lái)后續(xù)還款,其中以傳入的modes參數(shù)不同而決定。0為立刻還款,1為作為穩(wěn)定型債務(wù),2為浮動(dòng)型債務(wù)。
函數(shù)首先通過(guò)ValidationLogic.validateFlashloan檢查輸入?yún)?shù)匹配,計(jì)算閃電貸所需的溢價(jià)成本,并直接將所需的aToken轉(zhuǎn)給接收者地址。調(diào)用接受者的executeOperation操作實(shí)現(xiàn)預(yù)設(shè)的閃電貸。AAVE實(shí)現(xiàn)的閃電貸操作已包括了兌換,兌換清算,以及兌換償還操作。在executeOperation完成以上操作后,記錄需償還的閃電貸金額和相應(yīng)的費(fèi)用。如果用戶選擇以非債務(wù)模式歸還資金:系統(tǒng)更新儲(chǔ)備狀態(tài),累積儲(chǔ)備流動(dòng)性以及更新流動(dòng)性指數(shù)。最后再?gòu)恼?qǐng)求者轉(zhuǎn)移資金和費(fèi)用至儲(chǔ)備池。若用戶選擇以債務(wù)模式處理,則調(diào)用_executeBorrow,開(kāi)啟相應(yīng)的債務(wù)頭寸。轉(zhuǎn)換債務(wù)模式
在AAVEV2中,用戶可以通過(guò)swapBorrowRateMode函數(shù)在穩(wěn)定利率模式和浮動(dòng)利率模式之間切換。首先通過(guò)getUserCurrentDebt函數(shù)獲取用戶在目標(biāo)資產(chǎn)上的當(dāng)前穩(wěn)定利率債務(wù)和浮動(dòng)利率債務(wù),確定用戶的債務(wù)狀況。接著調(diào)用ValidationLogic.validateSwapRateMode函數(shù)驗(yàn)證切換操作是否合法。其中檢查用戶是否有足夠的穩(wěn)定或浮動(dòng)債務(wù)以支持模式切換,確保切換目標(biāo)模式符合資產(chǎn)的配置和用戶的債務(wù)情況。調(diào)用reserve.updateState更新資產(chǎn)儲(chǔ)備的狀態(tài),確保儲(chǔ)備數(shù)據(jù)最新。隨后就是對(duì)于兩種債務(wù)Tokens的相互轉(zhuǎn)換,燃燒穩(wěn)定債務(wù)Tokens鑄造浮動(dòng)債務(wù)Tokens或是燃燒浮動(dòng)債務(wù)Tokens鑄造穩(wěn)定債務(wù)Tokens。轉(zhuǎn)換完成后,reserve.updateInterestRates更新目標(biāo)資產(chǎn)利率,確保反映當(dāng)前市場(chǎng)狀態(tài)和用戶債務(wù)的變化。安全漏洞Checklist空市場(chǎng)導(dǎo)致的舍入漏洞
在AAVE和Compound中,都存在空市場(chǎng)中精度損失而造成的漏洞問(wèn)題。如果在一個(gè)空市場(chǎng)的情況(即沒(méi)有用戶在市場(chǎng)中進(jìn)行借貸),由于cumulateToLiquidityIndex函數(shù)中l(wèi)iquidityIndex的值依賴于合約對(duì)應(yīng)的底層資產(chǎn)Tokens的數(shù)量,所以攻擊者可以通過(guò)閃電貸向合約存入大量的底層資產(chǎn)Tokens來(lái)操縱aToken的價(jià)格。
與之前Compoundfork項(xiàng)目HundredFinance第一次被黑相似,在HopeLend事件中,攻擊者先操縱liquidityIndex將hETHWBTC兌WBTC的價(jià)值控制為1:1,通過(guò)兌換底層資產(chǎn)以及借貸的方式又提高liquidityIndex的值。隨后通過(guò)循環(huán)的閃電貸不斷調(diào)用_handleFlashLoanRepayment函數(shù)。
審計(jì)要點(diǎn):在審計(jì)時(shí),需要關(guān)注兌換率的計(jì)算方式是否容易被操控以及舍入的方式是否恰當(dāng),同時(shí)可以建議項(xiàng)目團(tuán)隊(duì)在新的市場(chǎng)創(chuàng)建后立刻鑄造aToken,以防止市場(chǎng)為空進(jìn)而被操控。ERC677/ERC777Tokens導(dǎo)致的重入漏洞
與之前Compoundfork項(xiàng)目HundredFinance第二次被黑相同,在Agave攻擊事件中,攻擊者在沒(méi)有任何負(fù)債的情況下調(diào)用了liquidateCall函數(shù)來(lái)清算自己。而清算的Tokens是GnosisChain鏈上使用的ERC-677標(biāo)準(zhǔn)Tokens,該類Tokens轉(zhuǎn)賬時(shí)會(huì)外部調(diào)用接收地址的函數(shù),所以使得清算合約調(diào)用了攻擊合約,攻擊合約在此過(guò)程中存入了2728個(gè)通過(guò)閃電貸獲取的WETH,鑄造出2728aWETH,并以此為抵押,借出了Agave項(xiàng)目中所有可用資產(chǎn)。外部調(diào)用結(jié)束后,liquidationCall函數(shù)直接清算了攻擊者之前存入的2728aWETH,并將其轉(zhuǎn)給清算者。
審計(jì)要點(diǎn):在審計(jì)時(shí),需特別關(guān)注與外部第三方協(xié)議的交互代碼。重點(diǎn)評(píng)估外部合約的輸入和輸出是否經(jīng)過(guò)嚴(yán)格限制,交互邏輯是否對(duì)協(xié)議核心模型或資金安全產(chǎn)生潛在影響,輸入數(shù)據(jù)是否經(jīng)過(guò)清理和驗(yàn)證,防止惡意數(shù)據(jù)引發(fā)安全問(wèn)題。通過(guò)嚴(yán)格審查外部交互的代碼邏輯以及數(shù)據(jù)驗(yàn)證機(jī)制,可有效降低此類漏洞風(fēng)險(xiǎn)。Tokens與利率策略兼容問(wèn)題
在Polygon鏈上,AAVE部署過(guò)程中,由于InterestRateStrategy設(shè)置不兼容的問(wèn)題導(dǎo)致功能異常,錯(cuò)誤地為WETH設(shè)置了不兼容的利率策略。
錯(cuò)誤設(shè)置的InterestRateStrategy合約中的interface如下:
而AAVEV2的LendingPool實(shí)現(xiàn)的代碼如下:
(參考來(lái)源:https://x.com/mookim_eth/status/1659589328727859205)
由于接口不兼容,新InterestRateStrategy無(wú)法正常被LendingPool調(diào)用,直接導(dǎo)致AAVEV2的WETH池功能中斷,用戶無(wú)法存入或提取ETH。
審計(jì)要點(diǎn):在審計(jì)時(shí),需確保代碼(或fork)中關(guān)鍵組件的接口完全兼容。同時(shí),盡管以上問(wèn)題并不是由多鏈特性導(dǎo)致的原因,但是審計(jì)時(shí)仍需要注意不同鏈的特性下是否會(huì)造成非預(yù)期的結(jié)果。DustTokens問(wèn)題
AAVE的存款和取款會(huì)通過(guò)setUsingAsCollateral函數(shù)設(shè)置usingAsCollateral來(lái)實(shí)現(xiàn),從而靈活地管理抵押策略。當(dāng)外部協(xié)議或合約通過(guò)AAVE借貸函數(shù)第一次借入資金時(shí),借貸函數(shù)會(huì)將usingAsCollateral設(shè)置為true。當(dāng)外部協(xié)議或合約從AAVE完全提取資金時(shí),AAVE中協(xié)議處理程序的usingAsCollateral狀態(tài)將被設(shè)置為false。但實(shí)際上,AAVE在計(jì)算取款需要燒掉的aToken數(shù)量時(shí),此時(shí)如果由于算術(shù)精度誤差,協(xié)議處理程序中可能還有極少的aToken剩余。因此,當(dāng)協(xié)議處理程序下次向AAVE存款時(shí),usingAsCollateral將不會(huì)變動(dòng),依然設(shè)置為true,由于協(xié)議處理程序合約中沒(méi)有調(diào)用setUserUseReserveAsCollateral函數(shù)的接口,這可能導(dǎo)致協(xié)議處理程序無(wú)法再執(zhí)行借款操作。
審計(jì)要點(diǎn):在審計(jì)時(shí),需要對(duì)所調(diào)用的協(xié)議有充分的熟悉度,充分了解其特性的情況下,判斷是否對(duì)于其與外部協(xié)議交互存在一定的兼容性問(wèn)題,如Tokens兼容性、調(diào)用實(shí)現(xiàn)邏輯兼容性等。
寫在最后
本手冊(cè)深入探討了AAVEV2協(xié)議的核心設(shè)計(jì)、關(guān)鍵功能及相關(guān)審計(jì)要點(diǎn),我們希望該手冊(cè)可以更好地幫助開(kāi)發(fā)人員和安全研究人員識(shí)別潛在風(fēng)險(xiǎn)并確保協(xié)議的安全運(yùn)行。由于篇幅限制,本文省略了部分代碼和圖片,讀者可點(diǎn)擊文末的閱讀原文跳轉(zhuǎn)至GitHub閱讀完整版(https://github.com/slowmist/AAVE-V2-Security-Audit-Checklist)。
免責(zé)聲明:慢霧:AAVE V2 安全審計(jì)手冊(cè)文章轉(zhuǎn)發(fā)自互聯(lián)網(wǎng),版權(quán)歸其所有。
文章內(nèi)容不代表本站立場(chǎng)和任何投資暗示。加密貨幣市場(chǎng)極其波動(dòng),風(fēng)險(xiǎn)很高,可能不適合所有投資者。在投資加密貨幣之前,請(qǐng)確保自己充分了解市場(chǎng)和投資的風(fēng)險(xiǎn),并考慮自己的財(cái)務(wù)狀況和風(fēng)險(xiǎn)承受能力。此外,請(qǐng)遵循您所在國(guó)家的法律法規(guī),以及遵守交易所和錢包提供商的規(guī)定。對(duì)于任何因使用加密貨幣所造成的投資損失或其他損失,本站不承擔(dān)任何責(zé)任。
Copyright © 2021.Company 元宇宙YITB.COM All rights reserved.元宇宙YITB.COM