AAVE Source Code Analysis: The Proxy System
Smart Contract Proxies
Upgradeable smart contracts rely heavily on proxy patterns, and AAVE’s proxy system is quite complex. To really understand it, you need to unpack it layer by layer.
Global AAVE proxy diagram:

According to OpenZeppelin’s proxy model, smart contract proxies are commonly divided into two kinds: transparent proxies and UUPS proxies.
Today, OpenZeppelin generally recommends the UUPS approach because it is more lightweight and easier to work with.
LendingPoolAddressesProvider
The first contract to understand is LendingPoolAddressesProvider, which sits at the center of the system. It acts both as a registry and as a management contract. It mainly serves two purposes:
- create, upgrade, and manage other contracts
- act as a registry of addresses so other contracts can look up one another through it
Several core contracts are created, upgraded, initialized, and managed through this contract:
LENDING_POOLLENDING_POOL_CONFIGURATOR
Its name already gives away one of its main responsibilities: providing addresses. The following addresses are configured through LendingPoolAddressesProvider:
LENDING_POOLLENDING_POOL_CONFIGURATORLENDING_POOL_COLLATERAL_MANAGERPOOL_ADMINEMERGENCY_ADMINPRICE_ORACLELENDING_RATE_ORACLE
How does LendingPoolAddressesProvider actually create and manage contracts? The rough flow is:
- When needed, it deploys a proxy template and sets the concrete implementation behind it.
- The core contracts listed above each store an
addressesProvidervariable. During initialization, they receive the provider address as a parameter. - When those contracts need to call one another, they first query the other party’s address through
addressesProvider, and then perform the call.
The code for creating or upgrading a proxy-backed contract looks like this:
| |
LendingPoolConfigurator
LendingPoolConfigurator, together with LendingPoolAddressesProvider, is used to create proxies for:
ATokenStableDebtTokenVariableDebtToken
The initialization code is:
| |
Upgrading those token contracts is done like this:
| |
Relationship diagram:
The broader takeaway is that AAVE layers its upgradeability. LendingPoolAddressesProvider manages the top-level core contracts, while LendingPoolConfigurator manages reserve-specific token proxies beneath that. That multi-level arrangement is one reason the proxy system feels more complicated than many simpler protocols.