@aave/safety-module 中文文档教程

发布于 3 年前 浏览 26 更新于 2 年前

Aave Incentives contracts

一组智能合约,以实现 Aave 相关资产的股权和基于它们的奖励分配。

Specification

Architecture

General architecture

一个通用的父合约 AaveDistributionManager 用于保持一组子前端合约的“会计”逻辑每种类型的奖励; 这些,最初是一个 StakedAave 合约,用于在 Aave SM(安全模块)上持有 Aave 代币,这将在不久的将来用作安全基金,以及一个 AaveIncentivesController Aave 协议将通过该合约进行交互,以提供奖励作为对用户的激励。 这个继承链分为 2 个主要层的基本原理是在分布配置和数学计算的公共部分与每种类型激励的一个特定部分(将资金锁定在股份中,为协议提供流动性以及未来可能更多)。 此外,还有一个奖励金库,用于保存 AAVE 奖励,通过 StakedAaveAaveIncentivesController 进行分配。 两者都将提前获得拨款津贴。 以下部分将详细介绍 AaveDistributionManager 和不同的前端合约的规范。

AaveDistributionManager

用于计算具有不同配置的多个分布的核心合同。 用户/aave 协议将与之交互的所有前端合约都继承自 AaveDistributionManager。 它根据分配的前端合约定义的用户情况计算属于某个用户的奖励有多少。 该计算是通过使用代表每秒排放的奖励累积的分布指数并在每个用户上快照该指数以考虑总数中有多少属于他来完成的。

Data

  • assets. Mapping of AssetData structs which, for each front contract connected to the AaveDistributionManager stores 1 or more of:
  • emissionPerSecond: Amount of rewards per second distribution-wide. It's used to calculate the raw amount of rewards to distribute in a time delta since the last update of the following described index.
  • index: Variable representing the accumulated rewards distributed distribution-wide per unit of token used in the specific child contract of the distribution (per unit of staked Aave in the case of the StakedAave child contract). The next index is calculated by the formula on _getNormalizedDistribution() emissionPerSecond _ timeDelta _ 10^PRECISION / balanceOnFrontContract + previousIndex, scaling it up multiplying by 10^18 in order to not lose precision.
  • lastUpdateTimestamp: timestamp when the struct was updated.
  • userIndexes: mapping user address => index snapshotted on the user from the one of the distribution.

对于子 StakedAave,它们使用的映射的键是 StakedAave 本身的地址。 对于 AaveIncentivesController,提交给激励的每个 aToken 和 debtToken 都有不同的键和结构。

Logic

该合约允许执行以下操作:

  • Configuration of multiple distributions: only allowed to a trusted EMISSION_MANAGER, allows to list an specific distribution, with some emission per second and front contract.
  • Update of user/distribution state on interaction: called by the child contract when something happened concerning the situation on the user, for example when he stakes on StakedAave, redeems, deposit on the Aave protocol, etc…
  • Get the unclaimed rewards of an user: self-explanatory, used by the children contracts to check how much rewards were accrued for an user and store the data if needed on their side, by interacting with the claimRewards() function.
  • Query information about distributions/users: by using the different view functions available.

StakedAave

持有 AAVE 代币的合约,在不久的将来与削减机制连接,以保护 Aave 协议,形成所谓的 Aave SM(安全模块)。 Aave 代币的持有者将他们加入此合约,他们将收到等量的 stkAAVE 代币,并开始在 AAVE 中累积奖励; 先前由受信任的 EMISSION_MANAGER 在父合约 AaveDistributionManager 上配置的奖励。 一旦他们累积了 AAVE 奖励,他们就可以随时领取,但是,要提取他们抵押的 AAVE 代币,他们需要激活并等待一段冷却时间,然后在提取时间窗口内立即提取。

Data

  • stakerRewardsToClaim: mapping storing the accrued rewards accrued and stored for an user, not taking into account those accrued but not stored yet.
  • stakersCooldowns: mapping the timestamp of activation of cooldown period for an user, if activated.

Logic

该合约允许执行以下操作:

  • Stake AAVE tokens to start accruing rewards: through the stake() function. The AAVE tokens will be locked in this same contract, and stkAAVE tokens will be minted for the user in the same proportion as AAVE staked, the state in the father AaveDistributionManager will be updated and the timestamp of the cooldown will be updated too.
  • Withdraw staked AAVE tokens: if an user has stkAAVE, he can call the redeem() function, burning the stkAAVE and receiving the same proportion of previously staked AAVE. The withdrawal will only suceed if the user in on the withdrawal window after the cooldown period.
  • Activate the cooldown period: self-explanatory, calling the cooldown() function and needed to withdraw the staked AAVE.
  • Claim the accrued rewards: by calling the claimRewards() function, used to update the state and transfer to the user the accrued rewards, consequence of the time he was/is staking.
  • Query information about users: about their rewards or cooldown period.

Cooldown period

冷却期的主要目标是避免未来安全模块出现的情况,如果发生削减事件,人们开始大量撤回他们的抵押资金,让协议暴露并删除实用程序股份本身。 为实现这一点,涉及 StakedAave 合约的任何状态更新/操作都需要满足的最重要条件是,如果用户质押退出,他已经遵守了冷却时间,这会导致资金流动应该只会对冷却时间产生“负面”影响。 根据操作类型,冷却时间受到以下方式的影响:

  • If an user stakes AAVE with/without having any fund staked before, if he didn't have the cooldown activated, it remains the same way.
  • If an user stakes AAVE holding already stkAAVE and with cooldown period activated:
  • If the cooldown is expired, remains expired.
  • If the cooldown is still valid, using the amount staked and the current timestamp, it does the weighted average with the current cooldown timestamp of the user.
  • If the user redeems AAVE, the cooldown timestamp is set to 0.
  • If the user claims rewards, the cooldown timestamp is not affected.
  • On transfer of stkAAVE:
  • The cooldown timestamp of the sender remains as it is.
  • On the recipient:
  • If the recipient is on a valid cooldown period finishing before that the one of the sender, we do the same weighted average as in stake().
  • If the recipient has an expired cooldown timestamp, his cooldown timetamp is set to 0.
  • If both sender and recipient have valid cooldown period activated and the one of the sender ends before than the recipient, the recipient keeps his own.

AaveIncentivesController

合同负责 Aave 协议上活动的激励,继承自 AaveDistributionManager。 每次在 Aave 协议上发生涉及用户任何激励的动作时,都会调用该合约来管理激励状态的更新。

Data

  • _usersUnclaimedRewards: mapping storing the accrued rewards accrued and stored for an user, not taking into account those accrued but not stored yet.

Logic

该合约允许执行以下操作:

  • Communication Aave protocol -> incentives: through the whitelisted function handleAction(), only callable by the Aave lending pool. For every asset and user, one call to this function needs to be done, which will trigger a state update in both the rewards of the user and the distribution data.
  • Claim of user rewards: by claimRewards() function, transferring to the user the AAVE rewards. If the user tries to claim his rewards with the StakedAave as target, a bonus will applied on the rewards accumulated from his activity on the protocol, and the stake() function on the StakedAave will be called.
  • Query information about users: mainly about the state of their rewards.

Audits

该存储库中的 Solidity 代码已经过 Consensys Diligence 和 Certik 的 2 次传统智能合约审计。 报告如下:

  • Consensys Diligence
  • Certik

Current Mainnet contracts (25/09/2020)

[MAIN]

Credits

对于与代理相关的合约,我们使用了来自 OpenZeppelin 的朋友的实现。

License

此存储库的内容受 AGPLv3 许可。

Aave Incentives contracts

Sets of smart contracts to enable stake of Aave-related assets and rewards distribution based on them.

Specification

Architecture

General architecture

A common parent contract AaveDistributionManager is used to keep the "accounting" logic for a set of children front contracts taking care of each type of incentive; being these, initially, a StakedAave contract for stake of Aave tokens on the Aave SM (Security Module) which will which be used as security fund in the near future, and a AaveIncentivesController contract through which the Aave protocol will interact in order to provider rewards as incentives to users. The rationale of this inheritance chain in 2 main layers is the clearly conceptual separation between a common part of configurations of the distributions and mathematical calculation, and one specific part for each type of incentive (locking funds in a stake, providing liquidity to a protocol and potentially more in the future). Additionally, there will be a Rewards vault where the AAVE rewards will be keep, to distribute through the StakedAave and the AaveIncentivesController. Both will be granted in advance with allowance to pull funds from. The following sections will go in detail on the specification of both the AaveDistributionManager and the different front contracts.

AaveDistributionManager

Core contract for calculation of multiple distributions with different configurations. All the front contracts which users/aave protocol will interact with inherit from the AaveDistributionManager. It calculates how many rewards belong to a certain user depending on the user's situation defined by the front contract of the distribution. This calculation is done by using a distribution index representing the accumulation of rewards from an emission per second and snapshoting that index on each user to take into account how much of the total belongs to him.

Data

  • assets. Mapping of AssetData structs which, for each front contract connected to the AaveDistributionManager stores 1 or more of:
  • emissionPerSecond: Amount of rewards per second distribution-wide. It's used to calculate the raw amount of rewards to distribute in a time delta since the last update of the following described index.
  • index: Variable representing the accumulated rewards distributed distribution-wide per unit of token used in the specific child contract of the distribution (per unit of staked Aave in the case of the StakedAave child contract). The next index is calculated by the formula on _getNormalizedDistribution() emissionPerSecond _ timeDelta _ 10^PRECISION / balanceOnFrontContract + previousIndex, scaling it up multiplying by 10^18 in order to not lose precision.
  • lastUpdateTimestamp: timestamp when the struct was updated.
  • userIndexes: mapping user address => index snapshotted on the user from the one of the distribution.

For the child StakedAave, they key of the mapping used is the address of the StakedAave itself. In the case of the AaveIncentivesController, there is a different key and struct for each aToken and debtToken submitted to incentives.

Logic

This contract allows to do the following:

  • Configuration of multiple distributions: only allowed to a trusted EMISSION_MANAGER, allows to list an specific distribution, with some emission per second and front contract.
  • Update of user/distribution state on interaction: called by the child contract when something happened concerning the situation on the user, for example when he stakes on StakedAave, redeems, deposit on the Aave protocol, etc…
  • Get the unclaimed rewards of an user: self-explanatory, used by the children contracts to check how much rewards were accrued for an user and store the data if needed on their side, by interacting with the claimRewards() function.
  • Query information about distributions/users: by using the different view functions available.

StakedAave

Contract to stake AAVE token, to be connected with a slashing mechanism in the near future in order to secure the Aave protocol, forming the so called Aave SM (Security Module). Holders of Aave tokens stae them in this contract, they receive equivalent amount in stkAAVE tokens and start accruing rewards in AAVE; rewards previously configured on the father contract AaveDistributionManager by the a trusted EMISSION_MANAGER. Once they accrued AAVE rewards, they can claim them at any moment but, to withdraw their staked AAVE tokens, they need to activate and wait a cooldown period, and withdraw just after it, during a withdrawal time window.

Data

  • stakerRewardsToClaim: mapping storing the accrued rewards accrued and stored for an user, not taking into account those accrued but not stored yet.
  • stakersCooldowns: mapping the timestamp of activation of cooldown period for an user, if activated.

Logic

This contract allows to do the following:

  • Stake AAVE tokens to start accruing rewards: through the stake() function. The AAVE tokens will be locked in this same contract, and stkAAVE tokens will be minted for the user in the same proportion as AAVE staked, the state in the father AaveDistributionManager will be updated and the timestamp of the cooldown will be updated too.
  • Withdraw staked AAVE tokens: if an user has stkAAVE, he can call the redeem() function, burning the stkAAVE and receiving the same proportion of previously staked AAVE. The withdrawal will only suceed if the user in on the withdrawal window after the cooldown period.
  • Activate the cooldown period: self-explanatory, calling the cooldown() function and needed to withdraw the staked AAVE.
  • Claim the accrued rewards: by calling the claimRewards() function, used to update the state and transfer to the user the accrued rewards, consequence of the time he was/is staking.
  • Query information about users: about their rewards or cooldown period.

Cooldown period

The main objective of the cooldown period is to avoid situations on the future Security Module when, if an slashing event happens, people starts withdrawing in mass their staked funds, leaving the protocol uncover and removing the utility on the stake itself. To achieve this, the most important condition to be fullfilled on any state update/operation involving the StakedAave contract is that, if a user staking withdraws, he already respected a cooldown period, which leads that movement of funds should only affect "negatively" the cooldown period. Depending on the type of operation, the cooldown period is affected in the following way:

  • If an user stakes AAVE with/without having any fund staked before, if he didn't have the cooldown activated, it remains the same way.
  • If an user stakes AAVE holding already stkAAVE and with cooldown period activated:
  • If the cooldown is expired, remains expired.
  • If the cooldown is still valid, using the amount staked and the current timestamp, it does the weighted average with the current cooldown timestamp of the user.
  • If the user redeems AAVE, the cooldown timestamp is set to 0.
  • If the user claims rewards, the cooldown timestamp is not affected.
  • On transfer of stkAAVE:
  • The cooldown timestamp of the sender remains as it is.
  • On the recipient:
  • If the recipient is on a valid cooldown period finishing before that the one of the sender, we do the same weighted average as in stake().
  • If the recipient has an expired cooldown timestamp, his cooldown timetamp is set to 0.
  • If both sender and recipient have valid cooldown period activated and the one of the sender ends before than the recipient, the recipient keeps his own.

AaveIncentivesController

Contract in charge of the incentives for activity on the Aave protocol, inheriting from the AaveDistributionManager. Each time an action involving any incentive for an user happens on the Aave protocol, this contract is called to manage the update of the incentives state.

Data

  • _usersUnclaimedRewards: mapping storing the accrued rewards accrued and stored for an user, not taking into account those accrued but not stored yet.

Logic

This contract allows to do the following:

  • Communication Aave protocol -> incentives: through the whitelisted function handleAction(), only callable by the Aave lending pool. For every asset and user, one call to this function needs to be done, which will trigger a state update in both the rewards of the user and the distribution data.
  • Claim of user rewards: by claimRewards() function, transferring to the user the AAVE rewards. If the user tries to claim his rewards with the StakedAave as target, a bonus will applied on the rewards accumulated from his activity on the protocol, and the stake() function on the StakedAave will be called.
  • Query information about users: mainly about the state of their rewards.

Audits

The Solidity code in this repository has undergone 2 traditional smart contracts' audits by Consensys Diligence and Certik. The reports are:

  • Consensys Diligence
  • Certik

Current Mainnet contracts (25/09/2020)

[MAIN]

Credits

For the proxy-related contracts, we have used the implementation of our friend from OpenZeppelin.

License

The contents of this repository are under the AGPLv3 license.

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文