# Aave V3 Incentives on Aptos

> [!WARNING]
> Aave V3 on Aptos is deprecated. Supplying and borrowing are disabled, but
> users can still repay debt and withdraw supplied assets. See the [governance
> proposal](https://app.aave.com/governance/v3/proposal/?proposalId=521).

Reference for the incentives modules in `sources/aave-periphery` of the `aave-pool` package.

The fee collector, coin migration and UI pool data provider modules are on the [Periphery](/aave-v3/aptos/smart-contracts/periphery) page.

## Incentives

The incentives system in Aave allows for distributing rewards to users who supply or borrow assets in the protocol. The system is managed through several key modules that work together to configure, track, and distribute rewards.

## RewardsController

The `rewards_controller` module is the main component for managing incentives in the Aave protocol. It handles the distribution of rewards to protocol participants who hold incentivized assets (aTokens or variableDebtTokens).

Users accrue rewards automatically when they hold these tokens without needing to stake or lock their assets. The rewards can be claimed through various functions that provide flexibility in how rewards are collected.

### Key Structures

```move
struct RewardsConfigInput has store, drop {
    emission_per_second: u128,
    total_supply: u256,
    distribution_end: u32,
    asset: address,
    reward: address,
    pull_rewards_transfer_strategy: Object<PullRewardsTransferStrategy>
}
```

This structure defines the configuration for a reward emission, including:

- `emission_per_second`: The rate at which rewards are distributed

- `total_supply`: The total supply of the asset being incentivized

- `distribution_end`: When the reward distribution ends

- `asset`: The address of the asset being incentivized (aToken or variableDebtToken)

- `reward`: The address of the reward token

- `pull_rewards_transfer_strategy`: The strategy for transferring rewards

### Write Methods

#### claim_rewards

```move
public fun claim_rewards(
    caller: &signer,
    assets: vector<address>,
    amount: u256,
    to: address,
    reward: address,
    rewards_controller_address: address
): u256
```

Claims rewards of one reward token for the caller on specific assets, with the rewards sent to a designated address.

**Input Parameters:**

| Name                       | Type              | Description                              |
| -------------------------- | ----------------- | ---------------------------------------- |
| **caller**                 | &signer           | The signer claiming the rewards          |
| **assets**                 | vector\<address\> | The addresses of the incentivized assets |
| **amount**                 | u256              | The amount of rewards to claim           |
| **to**                     | address           | The address receiving the rewards        |
| **reward**                 | address           | The address of the reward token          |
| **rewards_controller_address** | address           | The address of the rewards controller    |

**Return Values:**

| Type | Description                   |
| ---- | ----------------------------- |
| u256 | The amount of rewards claimed |

`rewards_distributor` also exposes `claim_rewards_on_behalf`, which takes an extra `user: address` and requires the caller to be an authorized claimer for that user, and `claim_rewards_to_self`, which omits `to` and sends the rewards to the caller.

#### claim_all_rewards

```move
public fun claim_all_rewards(
    caller: &signer,
    assets: vector<address>,
    to: address,
    rewards_controller_address: address
): (vector<address>, vector<u256>)
```

Claims all available rewards for the caller across specified assets, returning the list of reward tokens and amounts claimed.

**Input Parameters:**

| Name                       | Type              | Description                              |
| -------------------------- | ----------------- | ---------------------------------------- |
| **caller**                 | &signer           | The signer claiming the rewards          |
| **assets**                 | vector\<address\> | The addresses of the incentivized assets |
| **to**                     | address           | The address receiving the rewards        |
| **rewards_controller_address** | address           | The address of the rewards controller    |

**Return Values:**

| Type              | Description                               |
| ----------------- | ----------------------------------------- |
| vector\<address\> | The reward tokens claimed                 |
| vector\<u256\>    | The amounts claimed for each reward token |

`rewards_distributor` also exposes `claim_all_rewards_on_behalf`, which takes an extra `user: address`, and `claim_all_rewards_to_self`, which omits `to`.

### Friend Functions

Callable only by friend modules (emission_manager, pool logic); integrators use the emission_manager entry functions.

#### configure_assets

```move
public(friend) fun configure_assets(
    config_inputs: vector<RewardsConfigInput>,
    rewards_controller_address: address
)
```

Configures assets to incentivize with an emission of rewards per second until the end of distribution.

**Input Parameters:**

| Name                       | Type                         | Description                           |
| -------------------------- | ---------------------------- | ------------------------------------- |
| **config_inputs**          | vector\<RewardsConfigInput\> | The reward configurations to apply    |
| **rewards_controller_address** | address                      | The address of the rewards controller |

#### set_pull_rewards_transfer_strategy

```move
public(friend) fun set_pull_rewards_transfer_strategy(
    reward: address,
    strategy: Object<PullRewardsTransferStrategy>,
    rewards_controller_address: address
)
```

Sets a transfer strategy for a specific reward token that determines how rewards are transferred to users.

**Input Parameters:**

| Name                       | Type                                  | Description                           |
| -------------------------- | ------------------------------------- | ------------------------------------- |
| **reward**                 | address                               | The address of the reward token       |
| **strategy**               | Object\<PullRewardsTransferStrategy\> | The pull rewards transfer strategy    |
| **rewards_controller_address** | address                               | The address of the rewards controller |

#### handle_action

```move
// This function is called when users perform actions like supply, withdraw,
// transfer, etc. to update reward calculations
public(friend) fun handle_action(
    asset: address,
    user: address,
    total_supply: u256,
    user_balance: u256,
    rewards_controller_address: address
)
```

Called when a user performs an action that affects their balance of an incentivized asset, updating the rewards distribution accordingly.

**Input Parameters:**

| Name                       | Type    | Description                                                         |
| -------------------------- | ------- | ------------------------------------------------------------------- |
| **asset**                  | address | The address of the incentivized asset (aToken or variableDebtToken) |
| **user**                   | address | The address of the user                                             |
| **total_supply**           | u256    | The total supply of the asset                                       |
| **user_balance**           | u256    | The balance of the user in the asset                                |
| **rewards_controller_address** | address | The address of the rewards controller                               |

### View Methods

#### get_pull_rewards_transfer_strategy

```move
#[view]
public fun get_pull_rewards_transfer_strategy(
    reward: address,
    rewards_controller_address: address
): Option<Object<PullRewardsTransferStrategy>>
```

Returns the pull rewards transfer strategy for a reward, if one is set.

**Input Parameters:**

| Name                       | Type    | Description                           |
| -------------------------- | ------- | ------------------------------------- |
| **reward**                 | address | The address of the reward token       |
| **rewards_controller_address** | address | The address of the rewards controller |

**Return Values:**

| Type                                            | Description                                 |
| ----------------------------------------------- | ------------------------------------------- |
| Option\<Object\<PullRewardsTransferStrategy\>\> | The transfer strategy of the reward, if set |

#### get_rewards_data

```move
#[view]
public fun get_rewards_data(
    asset: address,
    reward: address,
    rewards_controller_address: address
): (u256, u256, u256, u256)
```

Returns reward data for a specific asset and reward token, including emission rates and distribution end time.

**Input Parameters:**

| Name                       | Type    | Description                                                         |
| -------------------------- | ------- | ------------------------------------------------------------------- |
| **asset**                  | address | The address of the incentivized asset (aToken or variableDebtToken) |
| **reward**                 | address | The address of the reward token                                     |
| **rewards_controller_address** | address | The address of the rewards controller                               |

**Return Values:**

| Type | Description                     |
| ---- | ------------------------------- |
| u256 | The current index of the reward |
| u256 | The emission per second         |
| u256 | The last update timestamp       |
| u256 | The distribution end timestamp  |

#### get_user_asset_index

```move
// Used to get the user's index for a specific asset and reward
#[view]
public fun get_user_asset_index(
    user: address,
    asset: address,
    reward: address,
    rewards_controller_address: address
): u256
```

Returns the user’s index for a specific asset and reward, used for calculating accrued rewards.

**Input Parameters:**

| Name                       | Type    | Description                                                         |
| -------------------------- | ------- | ------------------------------------------------------------------- |
| **user**                   | address | The address of the user                                             |
| **asset**                  | address | The address of the incentivized asset (aToken or variableDebtToken) |
| **reward**                 | address | The address of the reward token                                     |
| **rewards_controller_address** | address | The address of the rewards controller                               |

**Return Values:**

| Type | Description                                    |
| ---- | ---------------------------------------------- |
| u256 | The index of the user for the asset and reward |

#### get_user_accrued_rewards

```move
// Used to get the user's accrued rewards for a specific reward token
#[view]
public fun get_user_accrued_rewards(
    user: address,
    reward: address,
    rewards_controller_address: address
): u256
```

Returns the amount of rewards accrued by a user for a specific reward token.

**Input Parameters:**

| Name                       | Type    | Description                           |
| -------------------------- | ------- | ------------------------------------- |
| **user**                   | address | The address of the user               |
| **reward**                 | address | The address of the reward token       |
| **rewards_controller_address** | address | The address of the rewards controller |

**Return Values:**

| Type | Description                     |
| ---- | ------------------------------- |
| u256 | The rewards accrued by the user |

## EmissionManager

The `emission_manager` module manages the configuration of reward emissions and acts as an administrative layer above the `rewards_controller`.

### Key Functions

#### configure_assets

```move
public entry fun configure_assets(
    account: &signer,
    emissions_per_second: vector<u128>,
    total_supplies: vector<u256>,
    distribution_ends: vector<u32>,
    assets: vector<address>,
    rewards: vector<address>,
    pull_rewards_transfer_strategies: vector<Object<PullRewardsTransferStrategy>>
)
```

Configures assets for incentives, creating reward configurations and passing them to the rewards controller.

**Input Parameters:**

| Name                             | Type                                            | Description                                        |
| -------------------------------- | ----------------------------------------------- | -------------------------------------------------- |
| **account**                      | &signer                                         | The signer with emission admin privileges          |
| **emissions_per_second**         | vector\<u128\>                                  | The emission per second for each reward            |
| **total_supplies**               | vector\<u256\>                                  | The total supply of each asset                     |
| **distribution_ends**            | vector\<u32\>                                   | The distribution end timestamp for each reward     |
| **assets**                       | vector\<address\>                               | The addresses of the incentivized assets           |
| **rewards**                      | vector\<address\>                               | The addresses of the reward tokens                 |
| **pull_rewards_transfer_strategies** | vector\<Object\<PullRewardsTransferStrategy\>\> | The pull rewards transfer strategy for each reward |

#### set_pull_rewards_transfer_strategy

```move
public entry fun set_pull_rewards_transfer_strategy(
    caller: &signer,
    reward: address,
    pull_rewards_transfer_strategy: Object<PullRewardsTransferStrategy>
)
```

Sets the transfer strategy for a specific reward token.

**Input Parameters:**

| Name                           | Type                                  | Description                               |
| ------------------------------ | ------------------------------------- | ----------------------------------------- |
| **caller**                     | &signer                               | The signer with emission admin privileges |
| **reward**                     | address                               | The address of the reward token           |
| **pull_rewards_transfer_strategy** | Object\<PullRewardsTransferStrategy\> | The pull rewards transfer strategy        |

#### set_distribution_end

```move
public entry fun set_distribution_end(
    caller: &signer,
    asset: address,
    reward: address,
    new_distribution_end: u32
)
```

Updates the end time for a reward distribution on a specific asset.

**Input Parameters:**

| Name                 | Type    | Description                                                         |
| -------------------- | ------- | ------------------------------------------------------------------- |
| **caller**           | &signer | The signer with emission admin privileges                           |
| **asset**            | address | The address of the incentivized asset (aToken or variableDebtToken) |
| **reward**           | address | The address of the reward token                                     |
| **new_distribution_end** | u32     | The new distribution end timestamp                                  |

#### set_emission_admin

```move
// Sets the admin for a specific reward token
public entry fun set_emission_admin(
    account: &signer,
    reward: address,
    new_admin: address
)
```

Sets the address that has permission to configure emissions for a specific reward token.

**Input Parameters:**

| Name      | Type    | Description                           |
| --------- | ------- | ------------------------------------- |
| **account** | &signer | The signer with admin privileges      |
| **reward** | address | The address of the reward token       |
| **new_admin** | address | The address of the new emission admin |

### View Methods

#### get_rewards_controller

```move
#[view]
public fun get_rewards_controller(): address
```

Returns the address of the rewards controller.

**Return Values:**

| Type    | Description                           |
| ------- | ------------------------------------- |
| address | The address of the rewards controller |

#### get_emission_admin

```move
#[view]
public fun get_emission_admin(reward: address): address
```

Returns the admin address for a specific reward token.

**Input Parameters:**

| Name   | Type    | Description                     |
| ------ | ------- | ------------------------------- |
| **reward** | address | The address of the reward token |

**Return Values:**

| Type    | Description                      |
| ------- | -------------------------------- |
| address | The emission admin of the reward |

## TransferStrategy

The `transfer_strategy` module defines how rewards are transferred to users when they claim them.

### PullRewardsTransferStrategy

```move
struct PullRewardsTransferStrategy has key {
    rewards_admin: address,
    incentives_controller: address,
    rewards_vault: SignerCapability
}
```

This strategy pulls rewards from a vault resource account to the recipient address.

### Key Functions

#### pull_rewards_transfer_strategy_perform_transfer

```move
public(friend) fun pull_rewards_transfer_strategy_perform_transfer(
    incentives_controller: address,
    to: address,
    reward: address,
    amount: u256,
    strategy: Object<PullRewardsTransferStrategy>
): bool
```

Transfers rewards from the vault to the recipient.

**Input Parameters:**

| Name                  | Type                                  | Description                              |
| --------------------- | ------------------------------------- | ---------------------------------------- |
| **incentives_controller** | address                               | The address of the incentives controller |
| **to**                | address                               | The address receiving the rewards        |
| **reward**            | address                               | The address of the reward token          |
| **amount**            | u256                                  | The amount of rewards to transfer        |
| **strategy**          | Object\<PullRewardsTransferStrategy\> | The pull rewards transfer strategy       |

**Return Values:**

| Type | Description                      |
| ---- | -------------------------------- |
| bool | `true` if the transfer succeeded |

### View Methods

#### pull_rewards_transfer_strategy_get_incentives_controller

```move
public fun pull_rewards_transfer_strategy_get_incentives_controller(
    strategy: Object<PullRewardsTransferStrategy>
): address
```

Returns the incentives controller address associated with the strategy.

**Input Parameters:**

| Name     | Type                                  | Description                        |
| -------- | ------------------------------------- | ---------------------------------- |
| **strategy** | Object\<PullRewardsTransferStrategy\> | The pull rewards transfer strategy |

**Return Values:**

| Type    | Description                              |
| ------- | ---------------------------------------- |
| address | The address of the incentives controller |

#### pull_rewards_transfer_strategy_get_rewards_admin

```move
public fun pull_rewards_transfer_strategy_get_rewards_admin(
    strategy: Object<PullRewardsTransferStrategy>
): address
```

Returns the rewards admin address for the strategy.

**Input Parameters:**

| Name     | Type                                  | Description                        |
| -------- | ------------------------------------- | ---------------------------------- |
| **strategy** | Object\<PullRewardsTransferStrategy\> | The pull rewards transfer strategy |

**Return Values:**

| Type    | Description                      |
| ------- | -------------------------------- |
| address | The address of the rewards admin |

#### pull_rewards_transfer_strategy_get_rewards_vault

```move
public fun pull_rewards_transfer_strategy_get_rewards_vault(
    strategy: Object<PullRewardsTransferStrategy>
): address
```

Returns the address of the rewards vault.

**Input Parameters:**

| Name     | Type                                  | Description                        |
| -------- | ------------------------------------- | ---------------------------------- |
| **strategy** | Object\<PullRewardsTransferStrategy\> | The pull rewards transfer strategy |

**Return Values:**

| Type    | Description                      |
| ------- | -------------------------------- |
| address | The address of the rewards vault |

## UI Incentive Data Provider

The `ui_incentive_data_provider_v3` module provides view functions to query incentive data for UI display.

### Key Structures

```move
struct AggregatedReserveIncentiveData has store, drop {
    underlying_asset: address,
    a_incentive_data: IncentiveData,
    v_incentive_data: IncentiveData
}

struct IncentiveData has store, drop {
    token_address: address,
    incentive_controller_address: address,
    rewards_token_information: vector<RewardInfo>
}

struct RewardInfo has store, drop {
    reward_token_symbol: String,
    reward_token_address: address,
    emission_per_second: u256,
    // Additional fields…
}
```

### View Methods

#### get_reserves_incentives_data

```move
#[view]
public fun get_reserves_incentives_data(): vector<AggregatedReserveIncentiveData>
```

Returns incentive data for all reserves in the protocol, including information about reward tokens, emission rates, and other parameters.

**Return Values:**

| Type                                     | Description                         |
| ---------------------------------------- | ----------------------------------- |
| vector\<AggregatedReserveIncentiveData\> | The incentive data of every reserve |

#### get_user_reserves_incentives_data

```move
#[view]
public fun get_user_reserves_incentives_data(user: address): vector<UserReserveIncentiveData>
```

Returns incentive data specific to a user, including their accrued rewards and other user-specific incentive information.

**Input Parameters:**

| Name | Type    | Description             |
| ---- | ------- | ----------------------- |
| **user** | address | The address of the user |

**Return Values:**

| Type                               | Description                                      |
| ---------------------------------- | ------------------------------------------------ |
| vector\<UserReserveIncentiveData\> | The incentive data of the user for every reserve |
