AAVE Token

The Aave protocol is migrating from its native LEND token to the AAVE token, as detailed in Aavenomics. The AAVE token is an ERC-20 compatible token with the addition of a snapshot feature (used in governance balance tracking) and integrates EIP 2612 permit function, allowing gas-less transactions and one transaction approval/transfer.

This section will cover the technical aspects of the token and token migration. For governance, security, and incentive details, see the Aavenomics documentation.

The source code for the AAVE token and migration can be found on Github here.

Deployed Contracts

When integrating, only the proxy contracts should be used.

Proxy Contracts

Address and ABIs

The following are the current implementation of the contracts, which may be subject to change. Therefore always integrate the above proxy contracts only.

Implementations

Address and ABI

For details of staking and stkAAVE, see the Safety Module section.

Audits

Auditor

Audit Type

Smart Contract

Smart Contract

Properties Verification

LEND to AAVE migration

The LEND to AAVE migration will occur via user initiated actions, using the LendToAaaveMigrator contract. This can be performed in our app or by calling the LendToAaveMigrator contract directly.

For each amount of LEND migrated, amount/LEND_AAVE_RATIO of AAVE will be redeemed. The LEND_AAVE_RATIO is set at the time the contract is deployed and can be fetched by calling LEND_AAVE_RATIO() on the LendToAaveMigrator contract.

When the governance proposal for the token migration passes, the LendToAaveMigrator contract will be enabled. This is estimated to happen at Block 10978863.

Important considerations

Since the AAVE total supply will be lower than LEND total supply, the LEND_AAVE_RATIO must always be greater than 1, causing a loss of precision for amounts of LEND that are not multiples of LEND_AAVE_RATIO. For example, a person migrating 1.000000000000000022 LEND, with a LEND_AAVE_RATIO == 100, will receive 0.01 AAVE, losing the value of the last 22 units of LEND. For more details on the reasons for this approach, see the Github repo.

migrateFromLend()

function migrateFromLEND(uint256 amount) external

Migrates a certain amount of LEND to AAVE.

The user must approve() the amount for the LendToAaveMigrator contract to migrate, before execution.

Parameter

Type

Description

amount

uint256

The amount of LEND to be migrated

_totalLendMigrated()

function _totalLendMigrated() view public

Returns the total amount of LEND that has been migrated to AAVE.

Return Parameter

Type

Description

_totalLendMigrated

uint256

The amount of LEND already migrated

event LendMigrated()

event LendMigrated(address indexed sender, uint256 indexed amount)

An event emitted when a migrateFromLend() executes successfully.

Parameter

Type

Description

sender

address

The owner of the LEND and migrated AAVE

amount

uint256

The amount of LEND migrated

AAVE Token

As mentioned above, the AAVE token is an ERC-20 compatible token with the addition of a snapshot feature (used in governance balance tracking) and integrates EIP 2612 permit function, allowing gas-less transactions and one transaction approval/transfer.

Besides the standard ERC20 token features (transfer(), balanceOf(), allowance(), etc), the following features are also available.

permit()

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

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.

Parameter

Type

Description

owner

address

The owner of the funds

spender

address

The spender for the funds

value

uint256

The amount the spender is permitted to use

deadline

uint256

The deadline timestamp that the permit is valid. Use uint(-1) for no deadline.

v

uint8

Signature parameter

r

bytes32

Signature parameter

s

bytes32

Signature parameter

import { signTypedData_v4 } from 'eth-sig-util'
import { fromRpcSig } from 'ethereumjs-util'

// ... other imports

import AaveTokenAbi from "./AaveTokenAbi.json"

// ... setup your web3 provider

const aaveTokenAddress = "AAVE_TOKEN_ADDRESS"
const aaveTokenContract = new web3.eth.Contract(AaveTokenAbi, aaveTokenAddress)

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 permitted
const 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: "Aave Token",
    version: "1",
    chainId: chainId,
    verifyingContract: aaveTokenAddress,
  },
  message: {
    owner,
    spender,
    value,
    nonce,
    deadline,
  },
}

const signature = signTypedData_v4(
  Buffer.from(privateKey, "hex"),
  { data: permitParams }
)

const { v, r, s } = fromRpcSig(signature)

await aaveTokenContract.methods
    .permit({
      owner,
      spender,
      value,
      deadline,
      v,
      r,
      s
    })
    .send()
    .catch((e) => {
        throw Error(`Error permitting: ${e.message}`)
    })

_nonces()

function _nonces(address owner) public

Returns the next valid nonce to submit when calling permit()

event SnapshotDone

event SnapshotDone(address owner, uint128 oldValue, uint128 newValue)

An event emitted on every transfer, mint (with a valid to address), and burn (with a valid from address).

The snapshots are used for governance balance tracking.

Parameter

Type

Description

owner

address

The owner of the AAVE tokens

oldValue

uint128

The value before the operation was executed

newValue

uint128

The value after the operation was executed.

Last updated