Approve & Deposit
Aave LendingPool
contract is the main contract of the protocol. It exposes all the user-oriented actions that can be invoked using either Solidity or web3 libraries.
LendingPool
contracts are upgradable. This means that their addresses may change in the future.To prevent third party DApps from falling behind, Aave provides a
LendingPoolAddressesProvider
contract that will never be upgraded.This is used to retrieve the latest
LendingPool
. As soon as we have the latestLendingPool
, we can start depositing.
To interact with ILendingPoolAddressesProvider
contract, we will need its address and ABI.
ILendingPoolAddressesProvider
ABI
To obtain the ABI, we will use an interface.
Since we only require a select few functions: deposit, withdraw and so forth, we can create our own interface.
create ILendingPoolAddressesProvider.sol in interfaces folder.
either create your own interface by defining the functions (refer to etherscan or github)
or, just copy aave's interfaces
Address
Addresses Provider -> Deployed Contracts Section

Add these to brownie-config.yaml
def get_lendingpool():
# create lending_pool_addressess_provider contract object
lending_pool_addressess_provider = interface.ILendingPoolAddressesProvider(config["networks"][network.show_active()]["lending_pool_addressess_provider"])
lending_pool = lending_pool_addressess_provider.getLendingPool()
return lending_pool
Lending Pool
ABI -> interface
Change import path from local directories to github
Original:
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
import {DataTypes} from './DataTypes.sol';
Modified:
import {ILendingPoolAddressesProvider} from '@aave/contract/interfaces/ILendingPoolAddressesProvider.sol';
import {DataTypes} from '@aave/contract/protocol/libraries/types/DataTypes.sol';
compile after, to check if interfaces are correct.
Address
We will get the address by calling getLendingPool() from the ILendingPoolAddressesProvider
def get_lendingpool():
# create lending_pool_addressess_provider contract object
lending_pool_addressess_provider = interface.ILendingPoolAddressesProvider(config["networks"][network.show_active()]["lending_pool_addressess_provider"])
#get lending pool address
lending_pool = lending_pool_addressess_provider.getLendingPool()
return lending_pool
Code thus far
from code import interact
from distutils.command.config import config
from scripts.helpful_scripts import get_account
from brownie import network, config, interface
from scripts.get_weth import get_weth
def main():
account = get_account()
deposit_token = config["networks"][network.show_active()]["weth_token"]
# if no WETH, get_weth()
# local mainnet fork can use dummy acocunts to get WETH
# since local mainnet fork, can use dummy accounts. if actual mainnet/testnet then use private key account.
if network.show_active() in ["mainnet-fork"]:
get_weth()
# Get lending pool contract
lending_pool_address = get_lendingpool()
lending_pool = interface.ILendingPool(lending_pool_address)
print(f"....Lending pool contract: {lending_pool_address}....")
# Approve sending our ERC20(WETH) tokens
approve_erc20(deposit_amount, lending_pool.address, deposit_token, account)
def get_lendingpool():
# create lending_pool_addressess_provider contract object
lending_pool_addressess_provider = interface.ILendingPoolAddressesProvider(config["networks"][network.show_active()]["lending_pool_addressess_provider"])
#get lending pool address
lending_pool = lending_pool_addressess_provider.getLendingPool()
return lending_pool

Approve
Before we can deposit we must approve Aave's contract to use our WETH tokens. This is done with the approve function.

To reiterate, transacting with ERC-20 tokens is a 2-step process:
Approval of token allowance
Submission of transaction
approve_erc20()
def approve_erc20(amount,spender, erc20_address, account):
print("....Approving ERC20 token...")
# get ERC20 interface: https://github.com/PatrickAlphaC/aave_brownie_py_freecode/tree/main/interfaces
erc20 = interface.IERC20(erc20_address)
# approve(address spender, uint256 value)
tx = erc20.approve(spender,amount,{"from": account})
tx.wait(1)
print("....Approved....")
return tx
In a generic implementation, we would create IERC20.sol in our interfaces folder, and pass the ERC20 token contract into the interface as above. Subsequently, we call on the token contract to approve setting our allowance for another 3rd party contract (via erc20.approve).
Added to main():
approve_erc20(deposit_amount, lending_pool.address, deposit_token, account)
deposit_amount as global variable
Deposit
When depositing, the LendingPool
contract must haveallowance()
to spend funds on behalf ofmsg.sender
for at-leastamount
for the asset
being deposited. This can be done via the standard ERC20 approve()
method.
The referral program is currently inactive and you can pass0
as thereferralCode.
In future for referral code to be active again, a governance proposal, with the list of unique referral codes for various integration must be passed via governance.
We will the below to main():
## Deposit: deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)
# referralCode is deprecated - pass a 0 as parameter
print("....Depositing....")
tx = lending_pool.deposit(deposit_token_address, deposit_amount, account.address,0, {"from": account})
tx.wait(1) # wait one block
print("....Deposited!....")
Last updated