# AToken

## Inheritance

Firstly, it is important to note the inheritance chain of the AToken contract:

```solidity
contract AToken is VersionedInitializable, ScaledBalanceTokenBase, EIP712Base, IAToken
```

AToken inherits VersionedInitializable, ScaledBalanceTokenBase, EIP712Base and IAToken.

### **VersionedInitializable**

* Abstract helper contract to implement initializer functions.
* Inspired by the OpenZeppelin Initializable contract.

<details>

<summary><strong>VersionedInitializable.sol</strong></summary>

{% code overflow="wrap" fullWidth="true" %}
```solidity
abstract contract VersionedInitializable {
  /**
   * @dev Indicates that the contract has been initialized.
   */
  uint256 private lastInitializedRevision = 0;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    uint256 revision = getRevision();
    require(
      initializing || isConstructor() || revision > lastInitializedRevision,
      'Contract instance has already been initialized'
    );

    bool isTopLevelCall = !initializing;
    if (isTopLevelCall) {
      initializing = true;
      lastInitializedRevision = revision;
    }

    _;

    if (isTopLevelCall) {
      initializing = false;
    }
  }

  /**
   * @notice Returns the revision number of the contract
   * @dev Needs to be defined in the inherited class as a constant.
   * @return The revision number
   */
  function getRevision() internal pure virtual returns (uint256);

  /**
   * @notice Returns true if and only if the function is running in the constructor
   * @return True if the function is running in the constructor
   */
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    uint256 cs;
    //solium-disable-next-line
    assembly {
      cs := extcodesize(address())
    }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

```
{% endcode %}

</details>

This contract is used to assist with initialization. It is modified from the Initializable contract of OpenZeppelin, and the revision version number is introduced. When the version number becomes larger, it can be initialized again.

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2F6IPPgro1VJkShi1ZahA3%2Fimage.png?alt=media&#x26;token=5046ef14-c6c3-4343-8e2a-1af0bfaf1cb2" alt=""><figcaption><p><strong>VersionedInitializable.sol</strong></p></figcaption></figure>

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FiFn2BrLH4kyoOVl7VSPM%2Fimage.png?alt=media&#x26;token=752f00eb-2b3c-4804-9ff0-98ff3e4e0199" alt=""><figcaption><p>AToken.sol</p></figcaption></figure>

The revision number is defined on AToken.sol, which is obtained via `getRevision`. However, when the modifier `initializer` executes, it calls `getRevision` as defined in AToken.sol, due to override.

{% hint style="info" %}
Both revision values and `getRevision` are defined on contracts inheriting VersionedInitializable; this keeps VersionedInitializable modular as it does not need to be altered for each inheritance.&#x20;
{% endhint %}

### IncentivizedERC20

ScaledBalanceTokenBase inherits MintableIncentivizedERC20, which in turn inherits IncentivizedERC20.&#x20;

IncentivizedERC20 is similar to the standard ERC-20, with two differences.&#x20;

1. **balanceOf is modified with struct `UserState`:**

{% code title="IncentivizedERC20" %}
```solidity
/**
   * @dev UserState - additionalData is a flexible field.
   * ATokens and VariableDebtTokens use this field store the index of the
   * user's last supply/withdrawal/borrow/repayment. StableDebtTokens use
   * this field to store the user's stable rate.
   */
  struct UserState {
    uint128 balance;
    uint128 additionalData;
  }
  
// Map of users address and their state data (userAddress => userStateData)
mapping(address => UserState) internal _userState;

function balanceOf(address account) public view virtual override returns (uint256) {
  return _userState[account].balance;
}
```
{% endcode %}

balance saved in UserState is the actual balance, and additionalData is the liquidity index.

2. **\_transfer will apply incentives via IAaveIncentivesController**

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2F3e2MRPWqk9I1AxxaH6wG%2Fimage.png?alt=media&#x26;token=52a6f352-b64e-4069-a7f6-27c8ab010051" alt=""><figcaption></figcaption></figure>

It is also interesting to note that transferFrom incorporates both approve and transfer.

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FI6FjuOrlqKnjaTPYa6ek%2Fimage.png?alt=media&#x26;token=da68e015-22a8-4a00-9387-474424811646" alt=""><figcaption></figcaption></figure>

### Mintable Incentivized ERC20 <a href="#id-2.2.2-mintableincentivizederc20" id="id-2.2.2-mintableincentivizederc20"></a>

Abstract contract MintableIncentivizedERC20 inherits IncentivizedERC20, and implements only two functions:

* \_mint&#x20;
* \_burn &#x20;

These two functions will update the balance in `_totalSupply` and `UserState`, and then call IAaveIncentivesController.

### ScaledBalanceTokenBase <a href="#id-2.2.3-scaledbalancetokenbase" id="id-2.2.3-scaledbalancetokenbase"></a>

Abstract contract ScaledBalanceTokenBase inherits MintableIncentivizedERC20 and implements three functions:

* \_mintScaled
* \_burnScaled
* \_transfer

### Visual Aid

<img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FN3m7UxlYThzVh8YAx0ir%2Ffile.excalidraw.svg?alt=media&#x26;token=d027d754-3fd8-470c-8263-8f9f933ad3c0" alt="" class="gitbook-drawing">

### EIP712Base <a href="#id-2.3-eip712base" id="id-2.3-eip712base"></a>

* WIP

## balanceOf

Aave implements a modified version of the ERC-20 standard for its aTokens, such that the balance of aTokens increments without any transactions.&#x20;

Let's examine the implementation for `balanceOf`:

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FyaYQqgfOwJj22tj09D4R%2Fimage.png?alt=media&#x26;token=ffe2a088-5b4d-4a5b-963c-f762a75469ec" alt=""><figcaption><p><a href="https://github.com/aave/aave-v3-core/blob/29ff9b9f89af7cd8255231bc5faf26c3ce0fb7ce/contracts/protocol/tokenization/AToken.sol#L128">AToken::balanceOf</a></p></figcaption></figure>

`override(IncentivizedERC20, IERC20)` serves to override `balanceOf` functions declared within its inheritance tree, so that the parent functions do not get called.&#x20;

<details>

<summary>On multiple inheritance</summary>

![](https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2Fmbr2Gkwcn8UDNzp2rotc%2Fimage.png?alt=media\&token=16ff1387-af60-4778-a777-6422bd0e5cbe)

In short, we need to specify the contracts if we are overriding from more than one contract. Otherwise, you just need to use the override keyword.

Read more: [https://solidity-by-example.org/inheritance/](https://solidity-by-example.org/inheritance/)

</details>

A user's aToken balance is the multiplication of two components:

1. `super.balanceOf`&#x20;
2. `POOL.getReserveNormalizedIncome()`

In a more digestible form, this basically translates to:

```solidity
super.balanceOf(user) * POOL.getReserveNormalizedIncome(_underlyingAsset)
        scaledBalance * currentLiquidityIndex
```

**Execution flow:**&#x20;

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2F9elz3nugnKQR9dCIqlpF%2Fimage.png?alt=media&#x26;token=37312607-b6aa-4c23-91b7-f1a8e2be96f9" alt=""><figcaption><p>super.balanceOf(user)</p></figcaption></figure>

### `super.BalanceOf`&#x20;

This calls balanceOf as declared in IncentivizedERC20.sol.

* Each user has a struct, `UserState` associated with their address via the mapping `_userState`
* The `balance` element within the `UserState` stores user's scaled balance&#x20;
* `super.balanceOf` returns `_userState[account].balance`

{% hint style="info" %}
`super.BalanceOf` returns the scaled balance of a user.
{% endhint %}

### `getReserveNormalizedIncome`

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2Fl19FuUnqnTLi8e36C2VD%2Fimage.png?alt=media&#x26;token=8d9315da-2255-4b96-af2c-f960ee09d70e" alt=""><figcaption></figcaption></figure>

`getReserveNormalizedIncome` returns the latest liquidity index, as `currentLiquidityIndex`.&#x20;

### Putting them together

```solidity
       super.balanceOf(user) * POOL.getReserveNormalizedIncome(_underlyingAsset)
 _userState[account].balance * currentLiquidityIndex
           userState.balance * currentLiquidityIndex
           "scaledBalance"   * "latest liquidity Index"
```

**Example:**

* user deposits 1000 DAI, when Index = 1.1
* scaledBalance = 909
* `_userState[account].balance` = 909

### Visual Aid

<img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FQbxmzL9NKEnfTQGMZ9zm%2Ffile.excalidraw.svg?alt=media&#x26;token=a169075a-10f8-4bd0-9812-fdd97896686b" alt="" class="gitbook-drawing">

## mint

**Execution flow**

AToken::`mint` -> ScaledBalanceTokenBase::`_mintScaled` ->  MintableIncentivizedERC20::`_mint`

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FvuE3REDzDFDRELio9P45%2Fimage.png?alt=media&#x26;token=dc206d67-2693-423f-8ac3-115edec29a3e" alt=""><figcaption><p>AToken inherits ScaledBalanceTokenBase</p></figcaption></figure>

* `amountScaled`, the amount to mint is scaled against the liquidity index in `_mintScaled`.&#x20;
* `_mint` increments the user's balance by `amountScaled`.
* user's balance held in `_userState[account].balance`.

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FxU73NNlwQZEZN6ucYyAh%2Fimage.png?alt=media&#x26;token=33877922-c48b-4a2d-8787-9c69b55571e9" alt=""><figcaption></figcaption></figure>

### Execution flow: Visual Aid

Here is a more complete execution flow chart spanning the relevant portions across different contracts.

<img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FyKDpPk6mn1Z5ZoVRupLQ%2Ffile.excalidraw.svg?alt=media&#x26;token=ef704779-dfc7-4ced-b9a6-c6f7b41f365e" alt="" class="gitbook-drawing">
