Rewards

Technical documentation

Description

Depositing tokens into the concrete's Earn flow provides the user with a ctAsset representing a share of the total amount in the vault. The vault will then move the money to different strategies to generate the best yield possible. Some of the strategies in the vault interact with third-party lending protocols like Aave, Compound, and Radiant. These protocols not only provide yield but also rewards in the form of tokens. For example, Compound provides COMP, and Aave provides AAVE. Holders of the vault shares not only receive yield through the increase in their share values but also are entitled to a portion of the rewards based on the duration they leave their tokens inside the vault.

How does it work?

The vault maintains the state of accrued rewards using an index, which represents the rewards per token at the time of the last claim. This is stored in a mapping as follows:

mapping(address => uint256) public rewardIndex;

The first time a new reward token is collected is added to this array:

address[] private rewardAddresses;

Each concrete vault has a function called harvestRewards that calls a function with the same name for each strategy. This function returns the reward token and the amount collected. This information is used to calculate the reward index.

Every time a user deposits an amount into the vault, a snapshot of the rewardIndex is taken for each reward token collected so far:

mapping(address => mapping(address => uint256)) public userRewardIndex;

When the user wants to claim their rewards, they can call claimRewards on the vault. It will collect all the pending rewards by calculating the difference between the rewardIndex and the userRewardIndex for each token. The result of that subtraction is the amount the user will receive per share. Then, the userRewardIndex is updated with the rewardIndex value.

The claimRewards function calls an internal function that acts as a hook and is executed every time the token balances are updated. Each time a user withdraws, deposits, or transfers ctAssets, the rewards are calculated and the user indexes are updated.

What happens in the Strategies?

Each strategy has its own logic to collect rewards based on the specific strategy. The strategy does not account for the rewards claimed. It can only claim rewards and send them to its vault. In cases where the claim is triggered by an action like pulling funds, it will collect the rewards first and send them to the vault once harvestRewards is executed.

Reference

For a more in-depth rationale of the implementation, please refer to this paper:

Last updated