aTokens

The aTokens are interest-bearing derivative tokens that are minted and burned upon deposit (called from LendingPool) and redeem(called from the aToken contract). The aTokens' value is pegged to the value of the corresponding deposited asset at a 1:1 ratio, and can be safely stored, transferred or traded. All interest collected by the aTokens reserves are distributed to aTokens holders directly by continuously increasing their wallet balance. Users can decide to redirect their stream of interest payments to any Ethereum public address.

The source code for aTokens can be found here.

If you need development support, join the #developers channel on our Aave community Discord server.

Methods

redeem()

function redeem(uint256 _amount)

Non-standard ERC20 function to redeem an _amount of aTokens for the underlying asset, burning the aTokens during the process.

NOTE:

  • redeem() will fail if the aTokens to be redeemed are being used as collateral. Please refer to the transferAllowed() function to understand how to check if a specific redeem/transfer action can be performed.

Parameter Name

Type

Description

_amount

uint256

Amount of aTokens to redeem.

To redeem the entire balance, use a value of uint(-1)

Solidity
Web3.js
Solidity
/// Instantiation of the aToken address
aToken aTokenInstance = AToken("/*aToken_address*/");
/// Input variables
uint256 amount = 1000 * 1e18;
/// redeem method call
aTokenInstance.redeem(amount)
Web3.js
// Import the ABIs, see: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
import ADaiTokenABI from "./ADaiToken.json"
import LendingPoolAddressesProviderABI from "./LendingPoolAddressesProvider.json"
import LendingPoolABI from "./LendingPool.json"
const lpAddressProviderAddress = '0x24a42fD28C976A61Df5D00D0599C34c4f90748c8' // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
const lpAddressProviderContract = new web3.eth.Contract(LendingPoolAddressesProviderABI, lpAddressProviderAddress)
// Get the latest LendingPoolCore address
const lpCoreAddress = await lpAddressProviderContract.methods
.getLendingPoolCore()
.call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
})
const aDaiToken = '0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d'
const aDaiContract = new web3.eth.Contract(ADaiTokenABI, aDaiToken)
// redeem 1000 DAI
const amountInWei = web3.utils.toWei("1000", "ether")
await aDaiContract.methods
.redeem(amountInWei)
.send()
.catch((e) => {
throw Error(`Error redeeming aDai: ${e.message}`)
})
The redeem() flow within the protocol

transfer()

function transfer(address recipient, uint256 amount) public

Standard ERC20 function to transfer tokens from msg.sender to a specified recipient.

NOTE:

  • transfer() will fail if the aTokens to be redeemed are being used as collateral. Please refer to the transferAllowed() function to understand how to check if a specific redeem/transfer action can be performed.

  • transfer() will fail if an amount of 0 is used, which is non-standard ERC20 behaviour.

Solidity
Web3.js
Solidity
/// Instantiation of the aToken address
aToken aTokenInstance = aToken("/*aToken_address*/");
/// Input variables
address recipient = /*transfer_recipient_address*/;
uint256 amount = 1000 * 1e18;
/// transfer method call
aTokenInstance.transfer(recipient, amount)
Web3.js
// Import the ABIs, see: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
import ADaiTokenABI from "./ADaiToken.json"
import LendingPoolAddressesProviderABI from "./LendingPoolAddressesProvider.json"
import LendingPoolABI from "./LendingPool.json"
const lpAddressProviderAddress = '0x24a42fD28C976A61Df5D00D0599C34c4f90748c8' // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
const lpAddressProviderContract = new web3.eth.Contract(LendingPoolAddressesProviderABI, lpAddressProviderAddress)
// Get the latest LendingPoolCore address
const lpCoreAddress = await lpAddressProviderContract.methods
.getLendingPoolCore()
.call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
})
const aDaiToken = '0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d'
const aDaiContract = new web3.eth.Contract(ADaiTokenABI, aDaiToken)
// transfer 1000 DAI
const amountInWei = web3.utils.toWei("1000", "ether")
await aDaiContract.methods
.transfer(amountInWei)
.send()
.catch((e) => {
throw Error(`Error transfering aDai: ${e.message}`)
})

transferFrom()

function transferFrom(address from, address to, uint256 amount) public

Standard ERC20 function to transfer tokens from an address to another.

NOTE:

  • transferFrom() will fail if the aTokens to be redeemed are being used as collateral. Please refer to the transferAllowed() function to understand how to check if a specific redeem/transfer action can be performed.

  • transferFrom() will fail if an amount of 0 is used, which is non-standard ERC20 behaviour.

Solidity
Web3.js
Solidity
/// Instantiation of the AToken address
AToken aTokenInstance = AToken("/*aToken_address*/");
/// Input variables
address from = /*transfer_source_address*/
address to = /*transfer_recipient_address*/;
uint256 amount = 1000 * 1e18;
/// transferFrom method call
aTokenInstance.transferFrom(from, to, amount)
Web3.js
// Import the ABIs, see: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
import ADaiTokenABI from "./ADaiToken.json"
import LendingPoolAddressesProviderABI from "./LendingPoolAddressesProvider.json"
import LendingPoolABI from "./LendingPool.json"
const lpAddressProviderAddress = '0x24a42fD28C976A61Df5D00D0599C34c4f90748c8' // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
const lpAddressProviderContract = new web3.eth.Contract(LendingPoolAddressesProviderABI, lpAddressProviderAddress)
// Get the latest LendingPoolCore address
const lpCoreAddress = await lpAddressProviderContract.methods
.getLendingPoolCore()
.call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
})
const aDaiToken = '0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d'
const aDaiContract = new web3.eth.Contract(ADaiTokenABI, aDaiToken)
// transfer 1000 DAI between two addresses
const amountInWei = web3.utils.toWei("1000", "ether")
const from = "FROM_ADDRESS"
const to = "TO_ADDRESS"
await aDaiContract.methods
.transferFrom(from, to, amountInWei)
.send()
.catch((e) => {
throw Error(`Error transferFrom for aDai: ${e.message}`)
})

isTransferAllowed()

function isTransferAllowed(address user, uint256 amount)

Non-standard ERC20 function that checks if a transfer or a redeem will fail. Specifically, a transfer/redeem will fail if the resulting Health Factor of the user performing the action will end up being below 1.

return name

Type

Description

transferAllowed

bool

true if the transfer is allowed, otherwise false

redirectInterestStream()

function redirectInterestStream(address _to)

Redirects the interest generated to a target address. When the interest is redirected, the user balance is added to the receiver balance.

Parameter Name

Type

Description

_to

address

Address of the receiver of the interest stream

Solidity
Web3.js
Solidity
/// Instantiation of the aToken address
aToken aTokenInstance = aToken("/*aToken_address*/");
/// Input variables
address receiver = /*receiver_public_address*/;
/// transfer method call
aTokenInstance.redirectInterestStream(receiver)
Web3.js
// Import the ABIs, see: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
import ADaiTokenABI from "./ADaiToken.json"
import LendingPoolAddressesProviderABI from "./LendingPoolAddressesProvider.json"
import LendingPoolABI from "./LendingPool.json"
const lpAddressProviderAddress = '0x24a42fD28C976A61Df5D00D0599C34c4f90748c8' // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
const lpAddressProviderContract = new web3.eth.Contract(LendingPoolAddressesProviderABI, lpAddressProviderAddress)
// Get the latest LendingPoolCore address
const lpCoreAddress = await lpAddressProviderContract.methods
.getLendingPoolCore()
.call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
})
const aDaiToken = '0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d'
const aDaiContract = new web3.eth.Contract(ADaiTokenABI, aDaiToken)
// redirect interest stream to a different address
const to = "TO_ADDRESS"
await aDaiContract.methods
.redirectInterestStream(to)
.send()
.catch((e) => {
throw Error(`Error redeeming Dai: ${e.message}`)
})

redirectInterestStreamOf()

function redirectInterestStreamOf(address _from, address _to)

Allows an allowed third-party to redirect the interest generated by a depositor to a target address. When the interest is redirected, the depositor balance is added to the receiver balance. The caller needs to have allowance on the interest redirection to be able to execute the function.

Parameter Name

Type

Description

_from

address

Address of the depositor

_to

address

Address of the receiver of the interest stream

Solidity
Web3.js
Solidity
/// Instantiation of the aToken address
aToken aTokenInstance = aToken("/*aToken_address*/");
/// Input variables
address depositor = /*depositor_public_address*/;
address receiver = /*receiver_public_address*/;
/// transfer method call
aTokenInstance.redirectInterestStreamOf(depositor, receiver)
Web3.js
// Import the ABIs, see: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
import ADaiTokenABI from "./ADaiToken.json"
import LendingPoolAddressesProviderABI from "./LendingPoolAddressesProvider.json"
import LendingPoolABI from "./LendingPool.json"
const lpAddressProviderAddress = '0x24a42fD28C976A61Df5D00D0599C34c4f90748c8' // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
const lpAddressProviderContract = new web3.eth.Contract(LendingPoolAddressesProviderABI, lpAddressProviderAddress)
// Get the latest LendingPoolCore address
const lpCoreAddress = await lpAddressProviderContract.methods
.getLendingPoolCore()
.call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
})
const aDaiToken = '0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d'
const aDaiContract = new web3.eth.Contract(ADaiTokenABI, aDaiToken)
// redirect interest stream between two addresses
const from = "FROM_ADDRESS"
const to = "TO_ADDRESS"
await aDaiContract.methods
.redirectInterestStreamOf(from, to)
.send()
.catch((e) => {
throw Error(`Error redeeming Dai: ${e.message}`)
})

allowInterestRedirectionTo()

function allowInterestRedirectionTo(address _to)

Gives allowance to an address to execute the interest redirection on behalf of the caller. This method allows third parties to setup interest stream redirections on behalf of the depositors.

Parameter Name

Type

Description

_to

address

depositor Ethereum public address

Solidity
Web3.js
Solidity
/// Instantiation of the aToken address
aToken aTokenInstance = aToken("/*aToken_address*/");
/// Input variables
address receiver = /*receiver_public_address*/;
/// transfer method call
aTokenInstance.allowInterestRedirectionTo(receiver)
Web3.js
// Import the ABIs, see: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
import ADaiTokenABI from "./ADaiToken.json"
import LendingPoolAddressesProviderABI from "./LendingPoolAddressesProvider.json"
import LendingPoolABI from "./LendingPool.json"
const lpAddressProviderAddress = '0x24a42fD28C976A61Df5D00D0599C34c4f90748c8' // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
const lpAddressProviderContract = new web3.eth.Contract(LendingPoolAddressesProviderABI, lpAddressProviderAddress)
// Get the latest LendingPoolCore address
const lpCoreAddress = await lpAddressProviderContract.methods
.getLendingPoolCore()
.call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
})
const aDaiToken = '0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d'
const aDaiContract = new web3.eth.Contract(ADaiTokenABI, aDaiToken)
// allow `to` address to redirect interest stream
const to = "TO_ADDRESS"
await aDaiContract.methods
.allowInterestRedirectionTo(to)
.send()
.catch((e) => {
throw Error(`Error redeeming Dai: ${e.message}`)
})

View methods

aTokens contracts have a set of methods designed to help monitor Aave Protocol activity for third-parties. Methods and their output are described in this section.

balanceOf()

function balanceOf(address _user)

Returns the current total aToken balance of _user all interest collected included.

return name

Type

Description

balance

uint256

aToken balance of the user, in wei units.

principalBalanceOf()

function principalBalanceOf(address _user)

Returns user current balance deposited to the Aave Protocol reserve contract, with interest collected amount removed.

return name

Type

Description

amount

uint256

user balance, in wei units.

getInterestRedirectionAddress()

function getInterestRedirectionAddress(address _user)

Returns user current interest stream recipient address, if the user doesn't have set any receiver the method return 0x00....

return name

Type

Description

receiver

address

receiver public address.

Emitted Events

Each aToken contract produces events that can easily be monitored directly on the Ethereum blockchain. For more information about event monitoring and filters on Ethereum, please refer to the official solidity documentation.

If you are analysing data about Aave Protocol, see the Analysing Data section.

The aTokens contracts have standard ERC20 behaviour and events. The below section will only detail the aToken specific events.

Redeem

return name

type

description

_from

address

address of the user performing the redeem() call

_value

uint256

the amount to be redeemed, in Wei.

_fromBalanceIncrease

uint256

the cumulated balance increase since the last user action

_fromindex

uint256

the last index of the user

MintOnDeposit

return name

type

description

_from

address

address of the user performing the mint action

_value

uint256

the amount to be minted, in Wei.

_fromBalanceIncrease

uint256

the cumulated balance increase since the last user action

_fromindex

uint256

the last index of the user

BurnOnLiquidation

return name

type

description

_from

address

address of the user from which the tokens are being burned

_value

uint256

the amount to be burned, in Wei.

_fromBalanceIncrease

uint256

the cumulated balance increase since the last user action

_fromindex

uint256

the last index of the user

BalanceTransfer

return name

type

description

_from

address

address of the user from which the tokens are being transferred

_to

address

address of the tokens receiver

_value

uint256

the amount to be transferred, in Wei.

_fromBalanceIncrease

uint256

the cumulated balance since the last user action

_toBalanceIncrease

uint256

the cumulated balance increase since the last receiver action

_fromindex

uint256

the last index of the user

_toindex

uint256

the last index of the receiver

InterestStreamRedirected

return name

type

description

_from

address

address of the user from which the interest are redirected

_to

address

address of the receiver of the interest

_redirectedBalance

uint256

amount of interest redirected, in Wei.

_fromBalanceIncrease

uint256

the cumulated balance increase since the last user action

_fromindex

uint256

the last index of the user

RedirectedBalanceUpdated

return name

type

description

_targetAddress

address

address of the user from which the balance is updated

_targetBalanceIncrease

uint256

the cumulated balance increase since the last user action

_targetIndex

uint256

the last index of the user

_redirectedBalanceAdded

uint256

the redirected balance being added

_redirectedBalanceRemoved

uint256

the redirected balance being removed

InterestRedirectionAllowanceChanged

return name

type

description

_from

address

address of the user initiating the interest redirection

_to

address

address of the receiver of the interest redirection

ReserveUpdated

An event emitted by the LendingPoolCore contract

return name

type

description

reserve

address

address of the reserve being updated

liquidityRate

uint256

updated liquidityRate, in Ray.

stableBorrowRate

uint256

updated stable rate APY, in Ray units.

variableBorrowRate

uint256

updated variable rate APY, in Ray units.

liquidityIndex

uint256

updated liquidity index

variableBorrowIndex

uint256

updated variable borrow index