AAVE Source Code Analysis: Deployment and Initialization
Because AAVE contains many contracts, its deployment process is correspondingly complex. AAVE splits deployment into seven tasks, each implemented as a hardhat task, and then uses a full task to orchestrate deployment and initialization end to end.
Full task
Inside package.json, the project defines many deployment commands. The following one deploys to mainnet and verifies contracts:
| |
Here, aave:mainnet is the task name, and it is defined in tasks/migrations/aave.mainnet.ts. The main body looks like this:
| |
Now let’s look at what each task does.
1. full:deploy-address-provider
Task name: full:deploy-address-provider
Task file: tasks/full/1_address_provider.ts
Purpose: deploy the address registry and address provider
Execution flow:
- deploy
LendingPoolAddressesProviderwithmarketIdsuch asAaveorAMM - run the
add-market-to-registrytask- if the registry does not exist, deploy
LendingPoolAddressesProviderRegistry - call
registerAddressesProvider
- if the registry does not exist, deploy
- call
setPoolAdmin - call
setEmergencyAdmin
2. full:deploy-lending-pool
Task name: full:deploy-lending-pool
Task file: tasks/full/2_lending_pool.ts
Purpose: deploy the lending pool and related contracts
Execution flow:
- if
LendingPoolis not yet deployed, deploy the related libraries and theLendingPoolimplementation, then initialize it - use the address provider created in step 1 to deploy a proxy for
LendingPool, and point that proxy to theLendingPoolimplementation - deploy
LendingPoolConfigurator - call
addressesProvider.setLendingPoolConfiguratorImpl, which deploys a proxy forLendingPoolConfiguratorand stores that address in the provider - deploy
StableAndVariableTokensHelper - deploy
ATokensAndRatesHelper
3. full:deploy-oracles
Task name: full:deploy-oracles
Task file: tasks/full/3_oracles.ts
Purpose: deploy oracle contracts
Execution flow:
- if
AaveOracledoes not exist, deploy it and callsetAssetSources - if
LendingRateOracledoes not exist, deploy it and initialize it throughsetInitialMarketRatesInRatesOracleByHelper - set
addressesProvider.setPriceOracleto the deployedAaveOracle - set
addressesProvider.setLendingRateOracleto the deployedLendingRateOracle
4. full:data-provider
Task name: full:data-provider
Task file: tasks/full/4_data-provider.ts
Purpose: deploy data-provider contracts
Execution flow:
- deploy
AaveProtocolDataProvider
5. WETH gateway contract
Task name: full-deploy-weth-gateway
Task file: tasks/full/5-deploy-wethGateWay.ts
Purpose: deploy WETHGateway
Execution flow:
- deploy
WETHGateway
6. Initialize contracts
Task name: full:initialize-lending-pool
Task file: tasks/full/6-initialize.ts
Purpose: deploy contracts, set proxies, and initialize the system
Execution flow:
initReservesByHelper: for each token in the market, do the following:- deploy
AToken - deploy
StableDebtToken - deploy
VariableDebtToken - deploy
DefaultReserveInterestRateStrategy - call
LendingPoolConfiguratorto deploy proxies for aToken and debt tokens, then initialize them
- deploy
configureReservesByHelper- if
LendingPoolCollateralManagerdoes not exist, deploy it - set the
LendingPoolCollateralManageraddress inaddressesProvider - deploy
WalletBalanceProvider, a read-only helper that exposes aggregated data - configure the
WETHGateway
7. Contract verification
Verification is mostly done through hardhat-etherscan.
AToken / debtToken
AToken, VariableDebtToken, and StableDebtToken all run behind proxies. Their proxy pattern is somewhat similar to OpenZeppelin’s transparent proxy model.
LendingPoolConfigurator is the creator and manager of those aToken and debt-token proxies, and is also responsible for initializing and upgrading them.
At the same time, LendingPoolConfigurator itself sits behind a proxy created by AddressProvider, and upgrades are managed through AddressProvider.