AAVE Source Code Analysis: Overall Code Architecture
AAVE Architecture Overview
AAVE is a lending protocol, so its core revolves around four major actions: deposit, borrow, repay, and liquidation. In my view, one major reason AAVE looks complex is the existence of stable-rate borrowing, which significantly increases the complexity of the interest-rate model. Without that feature, the overall design would be much easier to understand.
The high-level AAVE architecture looks like this:

Directory Structure and Files
The contracts live mainly under the contracts directory, which is organized like this:
| |
If you combine the main codebase with the deployment scripts and mocks, AAVE has roughly 30 contracts:
| |
Lending Core
The core lending system includes:
Interest-rate logic
AAVE moves most interest and validation logic into libraries under
contracts/protocol/libraries/logic/, mainly:GenericLogic.solCalculates user account-level data.ReserveLogic.solThe core of the core. It handles the main interest-related calculations.ValidationLogic.solThis library performs safety checks for deposits, borrows, repayments, liquidations, transfers, stable/variable rate switching, and so on.
LendingPoolLendingPoolis the main entry point for lending actions such as deposit, borrow, repay, and liquidation.LendingPoolCollateralManagerResponsible mainly for liquidation handling.
DefaultReserveInterestRateStrategyDefines how interest rates change through
calculateInterestRates.
Tokenization
In AAVE, both user deposits and user debt are recorded as tokens. In Compound, only deposits are tokenized; debt is not. Personally, I do not think debt strictly needs tokenization, but AAVE chose that design.
ATokenDeposit receipt token, similar to Compound’s cToken. When a user deposits an asset, AAVE mints the corresponding aToken.
DelegationAwareATokenAn AToken variant that supports delegation-related behavior.
StableDebtTokenToken used to record stable-rate borrowing.
VariableDebtTokenToken used to record variable-rate borrowing.
Markets, Providers, and Configuration Management
LendingPoolAddressesProviderLendingPoolAddressesProviderRegistryLendingPoolParametersProviderLendingPoolConfigurator
Oracle
The oracle layer provides the pricing inputs needed for borrowing power, liquidation, and other protocol decisions.
Helper Contracts
AaveProtocolDataProviderAggregates and precomputes data for frontend consumption.UiPoolDataProviderAlso aggregates and prepares data for frontends.StableAndVariableTokensHelperHelper management contract for setting borrow-rate-related parameters across multiple assets.WalletBalanceProviderQueries balance information. It is not strictly necessary because similar functionality can be built with multicall, but this contract offers a more targeted and often faster interface.ATokensAndRatesHelperHelper contract for configuration updates.
Adapters
The adapter layer mainly consists of Uniswap-related adapters:
UniswapLiquiditySwapAdapterUniswapRepayAdapterFlashLiquidationAdapter
Proxy
LendingPoolproxy- plus several additional upgradeable proxies throughout the system
At first glance, this many contracts can feel overwhelming. The practical way to study AAVE is to start from the core, especially the interest-rate model and risk-control-related contracts. That narrows the focus to roughly 7 or 8 contracts and makes the codebase much easier to digest.