Tokenization

AToken

aTokens are tokens minted and burnt upon supply and withdraw of assets to an Aave market. aTokens denote the amount of crypto assets supplied to the protocol and the yield earned on those assets. The aTokens’ value is pegged to the value of the corresponding supplied asset at a 1:1 ratio and can be safely stored, transferred or traded. All yield collected by the aTokens' reserves are distributed to aToken holders directly by continuously increasing their wallet balance.

This contract is the implementation of the interest bearing token for the Aave Protocol. It inherits the ScaledBalanceTokenBase and EIP712Base token contracts.

All standard EIP20 methods are implemented for aTokens, such as balanceOf, transfer, transferFrom, approve, totalSupply etc.

balanceOf will always return the most up to date balance of the user, which includes their principal balance and the yield generated by the principal balance.

The source code is available on GitHub.

Write Methods

initialize

function initialize(    IPool initializingPool,    address treasury,    address underlyingAsset,    IAaveIncentivesController incentivesController,    uint8 aTokenDecimals,    string calldata aTokenName,    string calldata aTokenSymbol,    bytes calldata params) public virtual

Called when aToken instance is initialized.

Input Parameters:

NameTypeDescription
initializingPoolIPoolThe address of the associated pool
treasuryaddressThe address of the treasury
underlyingAssetaddressThe address of the underlying asset
incentivesControllerIAaveIncentivesControllerThe address of the incentives controller for this aToken
aTokenDecimalsuint8The decimals of the underlying asset
aTokenNamestringThe name of the aToken
aTokenSymbolstringThe symbol of the aToken
paramsbytesA set of encoded parameters for additional initialization

mint

function mint(    address caller,    address onBehalfOf,    uint256 amount,    uint256 index) external virtual override onlyPool returns (bool)

Mints amount aTokens to user.

Input Parameters:

NameTypeDescription
calleraddressThe address performing the mint
onBehalfOfaddressThe address of the user that will receive the minted aTokens
amountuint256The amount of tokens getting minted
indexuint256The next liquidity index of the reserve

Return Values:

TypeDescription
booltrue if the the previous balance of the user was 0

burn

function burn(    address from,    address receiverOfUnderlying,    uint256 amount,    uint256 index) external virtual override onlyPool

Burns aTokens from user and sends the equivalent amount of underlying to receiverOfUnderlying.

In some instances, the mint event could be emitted from a burn transaction if the amount to burn is less than the interest that the user accrued.

Input Parameters:

NameTypeDescription
fromaddressThe address from which the aTokens will be burned
receiverOfUnderlyingaddressThe address that will receive the underlying asset
amountuint256The amount of tokens that will be burned
indexuint256The next liquidity index of the reserve

mintToTreasury

function mintToTreasury(uint256 amount, uint256 index) external override onlyPool

Mints aTokens to the reserve treasury.

Input Parameters:

NameTypeDescription
amountuint256The amount of tokens getting minted
indexuint256The address that will receive the underlying asset

transferOnLiquidation

function transferOnLiquidation(    address from,    address to,    uint256 value) virtual override onlyPool

Transfers aTokens in the event of a borrow being liquidated, in case the liquidator reclaims the aToken.

Input Parameters:

NameTypeDescription
fromaddressThe address getting liquidated, current owner of the aTokens
toaddressThe recipient of aTokens
valueuint256The amount of tokens getting transferred

transferUnderlyingTo

function transferUnderlyingTo(address target, uint256 amount) external virtual override onlyPool

Transfers the underlying asset to target.

Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan().

Input Parameters:

NameTypeDescription
useraddressThe recipient of the underlying
amountuint256The amount getting transferred

handleRepayment

function handleRepayment(address user, address onBehalfOf, uint256 amount) external virtual override onlyPool

Handles the underlying received by the aToken after the transfer has been completed.

The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying to receive LM rewards. In that case, handleRepayment() would perform the staking of the underlying asset.

Input Parameters:

NameTypeDescription
useraddressThe user executing the repayment
onBehalfOfaddress`The address for which the borrow position is repaid
amountuint256The amount getting repaid

permit

function permit(    address owner,    address spender,    uint256 value,    uint256 deadline,    uint8 v,    bytes32 r,    bytes32 s) external override

Allows a user to permit another account (or contract) to use their funds using a signed message. This enables gas-less transactions and single approval/transfer transactions. Allow passing a signed message to approve spending.

Implements the permit function as for EIP-2612.

Input Parameters:

NameTypeDescription
owneraddressThe owner of the funds
spenderaddressThe spender of the funds
valueuint256The amount the spender is permitted to spend
deadlineuint256The deadline timestamp, use type(uint256).max for max/no deadline
vuint8The V signature parameter
rbytes32The R signature parameter
sbytes32The S signature parameter

Example of signing and utilizing permit:

import { signTypedData_v4 } from "eth-sig-util";import { fromRpcSig } from "ethereumjs-util";// ... other importsimport aTokenAbi from "./aTokenAbi.json";// ... setup your web3 providerconst aTokenAddress = "ATOKEN_ADDRESS";const aTokenContract = new web3.eth.Contract(aTokenAbi, aTokenAddress);const privateKey = "YOUR_PRIVATE_KEY_WITHOUT_0x";const chainId = 1;const owner = "OWNER_ADDRESS";const spender = "SPENDER_ADDRESS";const value = 100; // Amount the spender is permittedconst nonce = 1; // The next valid nonce, use `_nonces()`const deadline = 1600093162;const permitParams = {  types: {    EIP712Domain: [      { name: "name", type: "string" },      { name: "version", type: "string" },      { name: "chainId", type: "uint256" },      { name: "verifyingContract", type: "address" },    ],    Permit: [      { name: "owner", type: "address" },      { name: "spender", type: "address" },      { name: "value", type: "uint256" },      { name: "nonce", type: "uint256" },      { name: "deadline", type: "uint256" },    ],  },  primaryType: "Permit",  domain: {    name: "aTOKEN_NAME",    version: "1",    chainId: chainId,    verifyingContract: aTokenAddress,  },  message: {    owner,    spender,    value,    nonce,    deadline,  },};const signature = signTypedData_v4(Buffer.from(privateKey, "hex"), {  data: permitParams,});// The signature can now be used to execute the transactionconst { v, r, s } = fromRpcSig(signature);await aTokenContract.methods  .permit({    owner,    spender,    value,    deadline,    v,    r,    s,  })  .send()  .catch((e) => {    throw Error(`Error permitting: ${e.message}`);  });

rescueTokens

function rescueTokens(    address token,    address to,    uint256 amount) external override onlyPoolAdmin

Rescue and transfer tokens locked in this contract. Only callable by POOL_ADMIN.

Input Parameters:

NameTypeDescription
tokenaddressThe address of the token
toaddressThe address of the recipient
amountuint256The amount of token to transfer

View Methods

balanceOf

function balanceOf(address user)    public    view    virtual    override(IncentivizedERC20, IERC20)    returns (uint256)

Returns the amount of tokens owned by user.

Overrides the base function.

Input Parameters:

NameTypeDescription
useraddressThe address of the user

Return Values:

TypeDescription
uint256The amount of tokens owned by user

totalSupply

function totalSupply() public view virtual override(IncentivizedERC20, IERC20 returns (uint256)

Returns the amount of tokens in existence.

Overrides the base function.

Return Values:

TypeDescription
uint256The amount of tokens in existence

RESERVE_TREASURY_ADDRESS

function RESERVE_TREASURY_ADDRESS() external view override returns (address)

Returns the address of the Aave treasury, controlled by governance, receiving the fees on this aToken.

Return Values:

TypeDescription
addressThe address of the Aave treasury

UNDERLYING_ASSET_ADDRESS

function UNDERLYING_ASSET_ADDRESS() external view override returns (address)

Returns the address of the underlying reserve asset of this aToken (E.g. WETH for aWETH).

Return Values:

TypeDescription
addressThe address of the underlying asset

DOMAIN_SEPARATOR

function DOMAIN_SEPARATOR() public view override(IAToken, EIP712Base) returns (bytes32)

Get the domain separator for the token at the current chain.

Return cached value if chainId matches cache, otherwise recomputes separator.

Overrides the base function to fully implement IAToken.

Return Values:

TypeDescription
bytes32The domain separator of the token at current chain

nonces

function nonces(address owner) public view override(IAToken, EIP712Base) returns (uint256)

Returns the nonce value for address specified as parameter. This is the nonce used when calling permit().

Overrides the base function to fully implement IAToken.

Input Parameters:

NameTypeDescription
owneraddressThe address of the owner

Return Values:

TypeDescription
uint256The nonce of the owner

Example:

const token = new Contract(aTokenAddress, aToken.abi, provider);await token.nonces(user);

Pure Methods

getRevision

function getRevision() internal pure virtual override returns (uint256)

Returns the revision number of the contract. Needs to be defined in the inherited class as a constant.

Returns 0x1.

Return Values:

TypeDescription
uint256The revision number

StaticATokenFactory

The StataTokenFactory is a factory and registry contract that manages all deployed StataToken instances for a specified Aave pool. It allows deploying new StataToken instances on demand and validates that there is only one StataToken instance per underlying asset. This contract maintains a mapping between underlying assets and their corresponding StataToken addresses.

StataTokens are ERC-4626 compliant tokens that wrap Aave's aTokens to provide a non-rebasing yield accrual mechanism.

The source code is available on GitHub.

Write Methods

initialize

function initialize() external initializer

Initializes the StataTokenFactory contract. This function is part of the Initializable pattern and is required to initialize the contract after deployment. In this implementation, it does not perform any actions.

createStataTokens

function createStataTokens(address[] memory underlyings) external returns (address[] memory)

Creates new StataToken instances for the given underlying assets if they do not already exist. For each provided underlying asset, the function checks if a StataToken already exists. If it does, the existing StataToken address is returned. If not, it deploys a new StataToken for that underlying asset, registers it, and returns the new address.

Input Parameters:

NameTypeDescription
underlyingsaddress[]An array of underlying asset addresses

Return Values:

TypeDescription
address[]An array of StataToken addresses corresponding to the provided underlying assets

Emits:

  • StataTokenCreated(address indexed stataToken, address indexed underlying) event for each new StataToken created.

Reverts:

  • NotListedUnderlying(address underlying) if the underlying asset is not listed in the Aave pool.

View Methods

getStataTokens

function getStataTokens() external view returns (address[] memory)

Returns all StataToken instances deployed via this factory.

Return Values:

TypeDescription
address[]An array of all StataToken contract addresses

getStataToken

function getStataToken(address underlying) external view returns (address)

Returns the StataToken address for a given underlying asset.

Input Parameters:

NameTypeDescription
underlyingaddressThe address of the underlying asset

Return Values:

TypeDescription
addressThe address of the corresponding StataToken; returns address(0) if not found

POOL

function POOL() external view returns (IPool)

Returns the address of the Aave pool associated with this factory.

Return Values:

TypeDescription
IPoolThe address of the associated Aave pool

PROXY_ADMIN

function PROXY_ADMIN() external view returns (address)

Returns the address of the proxy admin used for the StataToken proxies.

Return Values:

TypeDescription
addressThe address of the proxy admin

TRANSPARENT_PROXY_FACTORY

function TRANSPARENT_PROXY_FACTORY() external view returns (ITransparentProxyFactory)

Returns the address of the transparent proxy factory used for creating new StataToken proxies.

Return Values:

TypeDescription
ITransparentProxyFactoryThe address of the transparent proxy factory

STATA_TOKEN_IMPL

function STATA_TOKEN_IMPL() external view returns (address)

Returns the address of the StataToken implementation used when deploying new StataToken instances.

Return Values:

TypeDescription
addressThe address of the StataToken implementation

VariableDebtToken

Implements a variable debt token to track the borrowing positions of users at variable rate mode.

transfer and approve functionalities are disabled as variable debt tokens are non-transferable.

The vToken value is pegged 1:1 to the value of underlying borrowed asset and represents the current total amount owed to the protocol i.e. principal debt + interest accrued.

The VariableDebtToken contract inherits the DebtTokenBase and ScaledBalanceTokenBase token contracts.

The source code is available on GitHub.

Write Methods

initialize

function initialize(    IPool initializingPool,    address underlyingAsset,    IAaveIncentivesController incentivesController,    uint8 debtTokenDecimals,    string memory debtTokenName,    string memory debtTokenSymbol,    bytes calldata params) external virtual

Called when variableDebtToken instance is initialised.

Input Parameters:

NameTypeDescription
initializingPoolIPoolThe pool contract that is initializing this contract
underlyingAssetaddressThe address of the underlying asset of this aToken (E.g. WETH for aWETH)
incentivesControllerIAaveIncentivesControllerThe smart contract managing potential incentives distribution
debtTokenDecimalsuint8The decimals of the variableDebtToken, same as the underlying asset's
debtTokenNamestringThe name of the variable debt token
debtTokenSymbolstringThe symbol of the variable debt token
paramsbytesA set of encoded parameters for additional initialization

mint

function mint(    address user,    address onBehalfOf,    uint256 amount,    uint256 index) external virtual override onlyPool returns (bool, uint256)

Mints the variable debt token to the onBehalfOf address.

Input Parameters:

NameTypeDescription
useraddressThe address receiving the borrowed underlying, being the delegatee in case of credit delegate, or same as onBehalfOf otherwise
onBehalfOfaddressThe address receiving the variable debt tokens
amountuint256The amount of variable debt tokens to mint
indexuint256The variable debt index of the reserve

Return Values:

TypeDescription
booltrue if the previous balance of the user is 0, false otherwise
uint256The scaled total debt of the reserve

burn

function burn(    address from,    uint256 amount,    uint256 index) external virtual override onlyPool returns (uint256)

Burns user variable debt.

In some instances, a burn transaction will emit a mint event if the amount to burn is less than the interest that the user accrued.

Input Parameters:

NameTypeDescription
fromaddressThe address from which the debt will be burned
amountuint256The amount of debt tokens that will be burned
indexuint256The variable debt index of the reserve

Return Values:

TypeDescription
uint256The scaled total debt of the reserve

View Methods

UNDERLYING_ASSET_ADDRESS

function UNDERLYING_ASSET_ADDRESS() external view override returns (address)

Returns the address of the underlying asset of this variableDebtToken (e.g. WETH for variableDebtWETH)

Return Values:

TypeDescription
addressThe address of the underlying asset

balanceOf

function balanceOf(address account) public view virtual override returns (uint256)

Returns the amount of tokens owned by account - the most up to date accumulated debt (principal + interest) of the user.

Standard ERC20 function.

Input Parameters:

NameTypeDescription
accountaddressThe balance of this address

Return Values:

TypeDescription
uint256The amount of tokens owned by account

totalSupply

function totalSupply() public view virtual override returns (uint256)

Returns the amount of tokens in existence - the most up to date total debt accrued by all protocol users for that specific variable rate of debt token.

Standard ERC20 function.

Return Values:

TypeDescription
uint256The amount of tokens in existence

Pure Methods

getRevision

function getRevision() internal pure virtual override returns (uint256)

Returns the revision number of the contract. Needs to be defined in the inherited class as a constant.

Returns 0x1.

Return Values:

TypeDescription
uint256The revision number

NOT SUPPORTED OPERATIONS

Being non-transferrable, the variable debt token does not implement any of the standard ERC20 functions for transfer and allowance.

The following functions below will revert with the error code 80, OPERATION_NOT_SUPPORTED: transfer, allowance, approve, transferFrom, increaseAllowance, decreaseAllowance.

Aave.com provides information and resources about the fundamentals of the decentralised non-custodial liquidity protocol called the Aave Protocol, comprised of open-source self-executing smart contracts that are deployed on various permissionless public blockchains, such as Ethereum (the "Aave Protocol" or the "Protocol"). Aave Labs does not control or operate any version of the Aave Protocol on any blockchain network.