AAVE 整体架构
AAVE是一个借贷协议, 因此, 核心是围绕着存款,借款,还款,清算这四大环节展开的。我认为, AAVE 之所以看起来很复杂, 非常重要的一点是因为定息借款的存在, 极大的提高了利率模型的复杂度, 否则, AAVE 应该更加清晰。
AAVE 架构图如下:
目录结构及文件
合约主要在 contracts 目录下, contracts 目录结构如下:
├─adapters // 外部合约适配层
│ └─interfaces
├─dependencies // 一些基础库, 大部分基于 openzeppelin 修改
│ └─openzeppelin
│ ├─contracts
│ └─upgradeability
├─deployments // 部署相关
├─flashloan // 闪电贷
│ ├─base
│ └─interfaces
├─interfaces // 接口定义
├─misc
│ └─interfaces
├─mocks // 测试相关
│ ├─attacks
│ ├─dependencies
│ │ └─weth
│ ├─flashloan
│ ├─oracle
│ │ └─CLAggregators
│ ├─swap
│ ├─tokens
│ └─upgradeability
└─protocol // 核心实现, 核心代码全部在这个目录下
├─configuration
├─lendingpool
├─libraries
│ ├─aave-upgradeability
│ ├─configuration
│ ├─helpers
│ ├─logic
│ ├─math
│ └─types
└─tokenization
└─base
结合 AAVE
的部署代码, 算上Mock合约, AAVE 大概有 30 个合约:
LendingPoolAddressesProvider = 'LendingPoolAddressesProvider',
LendingPoolAddressesProviderRegistry = 'LendingPoolAddressesProviderRegistry',
LendingPoolParametersProvider = 'LendingPoolParametersProvider',
LendingPoolConfigurator = 'LendingPoolConfigurator',
ValidationLogic = 'ValidationLogic',
ReserveLogic = 'ReserveLogic',
GenericLogic = 'GenericLogic',
LendingPool = 'LendingPool',
PriceOracle = 'PriceOracle',
Proxy = 'Proxy',
LendingRateOracle = 'LendingRateOracle',
AaveOracle = 'AaveOracle',
DefaultReserveInterestRateStrategy = 'DefaultReserveInterestRateStrategy',
LendingPoolCollateralManager = 'LendingPoolCollateralManager',
InitializableAdminUpgradeabilityProxy = 'InitializableAdminUpgradeabilityProxy',
WalletBalanceProvider = 'WalletBalanceProvider',
AToken = 'AToken',
DelegationAwareAToken = 'DelegationAwareAToken',
AaveProtocolDataProvider = 'AaveProtocolDataProvider',
StableDebtToken = 'StableDebtToken',
VariableDebtToken = 'VariableDebtToken',
FeeProvider = 'FeeProvider',
TokenDistributor = 'TokenDistributor',
StableAndVariableTokensHelper = 'StableAndVariableTokensHelper',
ATokensAndRatesHelper = 'ATokensAndRatesHelper',
UiPoolDataProvider = 'UiPoolDataProvider',
WETHGateway = 'WETHGateway',
UniswapLiquiditySwapAdapter = 'UniswapLiquiditySwapAdapter',
UniswapRepayAdapter = 'UniswapRepayAdapter',
FlashLiquidationAdapter = 'FlashLiquidationAdapter',
以下是 Mock 合约
MockAToken = 'MockAToken',
MockAggregator = 'MockAggregator',
WETHMocked = 'WETHMocked',
SelfdestructTransferMock = 'SelfdestructTransferMock',
MockStableDebtToken = 'MockStableDebtToken',
MockVariableDebtToken = 'MockVariableDebtToken',
MockFlashLoanReceiver = 'MockFlashLoanReceiver',
MockUniswapV2Router02 = 'MockUniswapV2Router02',
MintableERC20 = 'MintableERC20', // mock
MintableDelegationERC20 = 'MintableDelegationERC20', // mock
借贷核心
借贷核心包括:
- 利率的计算
AAVE 将利率的计算移到了三个library中,路径为
contracts\protocol\libraries\logic\
, 主要是:
GenericLogic.sol 计算用户 account
ReserveLogic.sol 核心中的核心, 各种利率的计算
ValidationLogic.sol 这个库主要是各种安全校验, 存款校验, 借款校验, 还款校验, 清算校验, 转账校验, 活息定息转换校验等等
LendPool LendPool 是借贷动作的入口, 包括存款,借款,还款,清算等动作。
LendingPoolCollateralManager 主要负责完成清算
DefaultReserveInterestRateStrategy 利率变化的策略:calculateInterestRates
tokenization
AAVE 中用户的存款,借款都是以 token
的方式记录。Compound 中,只有存款是以 token 的方式记录,借款并没有 tokenization. 其实, 我觉得借款并没有 tokenization 的必要。
AToken 存款凭证,类似于 Compound 中的 cToken。当用户存入 token 时,AAVE 给用户 mint 对应的 aToken
DelegationAwareAToken AToken 的代理
StableDebtToken 定息借款 token, 用于记录用户的定息借款
VariableDebtToken 活息借款 token, 用于记录用户的活息借款
市场及Provider、配置管理
- LendingPoolAddressesProvider
- LendingPoolAddressesProviderRegistry
- LendingPoolParametersProvider
- LendingPoolConfigurator
Oracle
辅助合约
AaveProtocolDataProvider 把一些整合并计算好, 方便前端调用
UiPoolDataProvider 把一些整合并计算好, 方便前端调用
StableAndVariableTokensHelper 辅助管理合约, 同时设置多个 asset 的 borrowRate
WalletBalanceProvider 查询 balance 信息, 并不是很必要, 实际上可以通过 multicall 来完成这样的功能。当然, 这样可以更有针对性的获取数据, 速度也更快
ATokensAndRatesHelper 辅助管理合约, 设置配置信息
adapter
主要是 uniswap adapter,包括以下几个合约:
- UniswapLiquiditySwapAdapter
- UniswapRepayAdapter
- FlashLiquidationAdapter
Proxy
- LendPool 的 proxy
这么多合约确实让人眼花缭乱,然而,我们可以先从核心开始分析,也就是利率模型和风险控制相关的合约,大约7-8个合约。