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:
Name | Type | Description | |
---|---|---|---|
initializingPool | IPool | The address of the associated pool | |
treasury | address | The address of the treasury | |
underlyingAsset | address | The address of the underlying asset | |
incentivesController | IAaveIncentivesController | The address of the incentives controller for this aToken | |
aTokenDecimals | uint8 | The decimals of the underlying asset | |
aTokenName | string | The name of the aToken | |
aTokenSymbol | string | The symbol of the aToken | |
params | bytes | A 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:
Name | Type | Description | |
---|---|---|---|
caller | address | The address performing the mint | |
onBehalfOf | address | The address of the user that will receive the minted aTokens | |
amount | uint256 | The amount of tokens getting minted | |
index | uint256 | The next liquidity index of the reserve |
Return Values:
Type | Description | |
---|---|---|
bool | true 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:
Name | Type | Description | |
---|---|---|---|
from | address | The address from which the aTokens will be burned | |
receiverOfUnderlying | address | The address that will receive the underlying asset | |
amount | uint256 | The amount of tokens that will be burned | |
index | uint256 | The next liquidity index of the reserve |
mintToTreasury
function mintToTreasury(uint256 amount, uint256 index) external override onlyPool
Mints aTokens to the reserve treasury.
Input Parameters:
Name | Type | Description | |
---|---|---|---|
amount | uint256 | The amount of tokens getting minted | |
index | uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
from | address | The address getting liquidated, current owner of the aTokens | |
to | address | The recipient of aTokens | |
value | uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
user | address | The recipient of the underlying | |
amount | uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
user | address | The user executing the repayment | |
onBehalfOf | address` | The address for which the borrow position is repaid | |
amount | uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
owner | address | The owner of the funds | |
spender | address | The spender of the funds | |
value | uint256 | The amount the spender is permitted to spend | |
deadline | uint256 | The deadline timestamp, use type(uint256).max for max/no deadline | |
v | uint8 | The V signature parameter | |
r | bytes32 | The R signature parameter | |
s | bytes32 | The 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:
Name | Type | Description | |
---|---|---|---|
token | address | The address of the token | |
to | address | The address of the recipient | |
amount | uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
user | address | The address of the user |
Return Values:
Type | Description | |
---|---|---|
uint256 | The 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:
Type | Description | |
---|---|---|
uint256 | The 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:
Type | Description | |
---|---|---|
address | The 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:
Type | Description | |
---|---|---|
address | The 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:
Type | Description | |
---|---|---|
bytes32 | The 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:
Name | Type | Description | |
---|---|---|---|
owner | address | The address of the owner |
Return Values:
Type | Description | |
---|---|---|
uint256 | The 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:
Type | Description | |
---|---|---|
uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
underlyings | address[] | An array of underlying asset addresses |
Return Values:
Type | Description | |
---|---|---|
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:
Type | Description | |
---|---|---|
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:
Name | Type | Description | |
---|---|---|---|
underlying | address | The address of the underlying asset |
Return Values:
Type | Description | |
---|---|---|
address | The 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:
Type | Description | |
---|---|---|
IPool | The 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:
Type | Description | |
---|---|---|
address | The 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:
Type | Description | |
---|---|---|
ITransparentProxyFactory | The 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:
Type | Description | |
---|---|---|
address | The 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:
Name | Type | Description | |
---|---|---|---|
initializingPool | IPool | The pool contract that is initializing this contract | |
underlyingAsset | address | The address of the underlying asset of this aToken (E.g. WETH for aWETH) | |
incentivesController | IAaveIncentivesController | The smart contract managing potential incentives distribution | |
debtTokenDecimals | uint8 | The decimals of the variableDebtToken, same as the underlying asset's | |
debtTokenName | string | The name of the variable debt token | |
debtTokenSymbol | string | The symbol of the variable debt token | |
params | bytes | A 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:
Name | Type | Description | |
---|---|---|---|
user | address | The address receiving the borrowed underlying, being the delegatee in case of credit delegate, or same as onBehalfOf otherwise | |
onBehalfOf | address | The address receiving the variable debt tokens | |
amount | uint256 | The amount of variable debt tokens to mint | |
index | uint256 | The variable debt index of the reserve |
Return Values:
Type | Description | |
---|---|---|
bool | true if the previous balance of the user is 0, false otherwise | |
uint256 | The 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:
Name | Type | Description | |
---|---|---|---|
from | address | The address from which the debt will be burned | |
amount | uint256 | The amount of debt tokens that will be burned | |
index | uint256 | The variable debt index of the reserve |
Return Values:
Type | Description | |
---|---|---|
uint256 | The 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:
Type | Description | |
---|---|---|
address | The 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:
Name | Type | Description | |
---|---|---|---|
account | address | The balance of this address |
Return Values:
Type | Description | |
---|---|---|
uint256 | The 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:
Type | Description | |
---|---|---|
uint256 | The 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:
Type | Description | |
---|---|---|
uint256 | The 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.