Staking AAVE
The AAVE token can also be staked in the Safety Module, a core part of Aavenomics. By staking AAVE in the Safety Module, users help protect the protocol from a short fall event and earn an incentive as a result.
This section will cover the technical aspects of staking and the Safety Module. For governance, security, and incentive details, see the Aavenomics documentation.
The source code for the Safety Module, which includes the Staked AAVE token, can be found on Github here.
Deployed Contracts
Proxy Contracts | Interface | Address and ABIs |
Staked AAVE (stkAAVE) | ||
Staked Balancer LP (stkABPT) |
Underlying token | Address |
AAVE token | |
ABPT token |
Note that the interface for AAVE/WETH Balancer pool can be found here.
Audits
Auditor | Audit Type |
Consensys Diligence (Safety Module / Staked AAVE) | Smart Contract |
CertiK (Safety Module / Staked AAVE) | Smart Contract |
Integrating Staking
To perform AAVE staking in your integration, the following steps should be followed:
1. Ensure your users have AAVE
If they still have LEND, then the LEND tokens need to be migrated. See the LEND to AAVE migration guide of the V1 docs.
2. Stake the user's AAVE
The user must first
approve()
the amount for theStaked AAVE contract
to stake.The user should call
stake()
, passing in their address and the amount to stake.
3. Claim staking rewards
After a period of time, the user will accrue rewards. To check the rewards accrued for a certain user, call getTotalRewardsBalance()
to fetch the pending rewards. To claim the rewards, call claimRewards()
.
4. Un-staking
To un-stake, a user must first activate the cool down timer, wait for the cool down time to elapse, then redeem their staked tokens.
To activate the cool down timer, call
cooldown()
.To check if the cool down timer has finished, the current unix timestamp must be greater than the value returned from
stakersColldowns()
+COOLDOWN_SECONDS()
.When the cool down has finished, the user will have a maximum
UNSTAKE_WINDOW()
of time to redeem their tokens. If they do not redeem before this time period has elapsed, then the cool down timer is reset and they will need to activate the cool down again.The final step to un-stake it to call
redeem()
.
Staked AAVE (stkAAVE)
When a user stakes AAVE in the Safety Module, the user receives an equivalent amount of stkAAVE in return, and starts accruing rewards in AAVE. The user is then able to claim the rewards at anytime. To withdraw their staked AAVE, the user needs to activate a coolDown()
period, as detailed below.
stake()
function stake(address onBehalfOf, uint256 amount)
- code
Stakes a certain amount of AAVE tokens, with the option of sending the staked AAVE tokens (stkAAVE) to another address (i.e. the onBehalfOf
address).
Note: the msg.sender
must already have a balance of AAVE token.
The user must approve()
the amount
for the Staked AAVE
contract to stake, before execution.
Parameter | Type | Description |
| address | The address which will receive the stkAAVE tokens. Use |
| uint256 | The amount of AAVE to be staked |
claimRewards()
function claimRewards(address to, uint256 amount)
- code
Claims an amount
of AAVE rewards that the msg.sender
has accrued, with the option of sending the rewards to a different account.
Parameter | Type | Description |
| address | The address which will receive the AAVE tokens rewards. Use |
| uint256 | The amount of AAVE to be claimed. Use |
redeem()
function redeem(address to, uint256 amount)
- code
Redeems the staked tokens - receiving AAVE tokens and burning stkAAVE tokens.
A user can only redeem the underlying AAVE tokens if the following has been satisfied:
Activated their
cooldown()
period, andThe sum of
stakersCooldowns()
+COOLDOWN_SECONDS()
for their address must be less than the current unix block timestamp, andThey must call
redeem()
before the sum ofstakersCooldowns()
+COOLDOWN_SECONDS()
+UNSTAKE_WINDOW()
has passed.
Parameter | Type | Description |
| address | The address which will receive the redeemed AAVE tokens. Use |
| uint256 | The amount of AAVE to be redeemed. Use |
cooldown()
function cooldown()
- code
Activates the cool down timer to be able to unstake.
See getNextCooldownTimestamp()
for example cool down periods and scenarios.
stakersCooldowns()
function stakersCooldowns(address staker) view returns uint
- code
Returns the unix timestamp in seconds for when the staker
activated the cool down by calling cooldown()
.
A staker is able to successfully unstake when this value + COOLDOWN_SECONDS
in unix time has passed.
COOLDOWN_SECONDS()
function COOLDOWN_SECONDS() view returns uint
- code
Returns the current minimum cool down time needed to elapse before a staker is able to unstake their tokens.
As of October 2020, the current COOLDOWN_SECONDS
value is 864000 seconds (i.e. 10 days). This value should always be checked directly from the contracts.
UNSTAKE_WINDOW()
function UNSTAKE_WINDOW() view returns uint
- code
Returns the maximum window of time in seconds that a staker can redeem()
their stake once a cooldown()
period has been completed.
As of October 2020, the current UNSTAKE_WINDOW
value is 172800 seconds (i.e. 2 days). This value should always be checked directly from the contracts.
getNextCooldownTimestamp()
function getNextCooldownTimestamp(uint256 fromCooldownTimestamp, uint256 amountToReceive, address toAddress, uint256 toBalance) public returns (uint256)
- code
Calculates the cool down timestamp based on the sender / receiver timestamps.
Cool down examples:
A user stakes AAVE for the first time. Their cool down time is set to the current block timestamp.
A user already has stkAAVE and decides to stake more AAVE (i.e. call
stake()
), while they already have a cool down period active:If the cool down is expired (e.g. beyond the
UNSTAKE_WINDOW
), then the cool down period will remain expired.If the cool down period is still valid, using the amount staked and and the current block timestamp, a weighted average is calculated with the current cool down timestamp of the user.
A user calls
redeem()
. This will reset the cool down timestamp.A user calls
claimRewards()
. The cool down timestamp is not affected.A user transfers (i.e. sends) stkAAVE to another address:
The cool down timestamp of the
msg.sender
remains the same.For the receiver of the stkAAVE:
If they have a valid cool down period finishing before the cool down period of the
msg.sender
, a weighted average is calculated with the current cool down timestamp of the user.If the receiver has an expired cool down timestamp, the cool down timestamp is reset.
If both the receiver and
msg.sender
have valid cool down periods, and themsg.sender
cool down period ends before the receiver, then the receiver's cool down period remains the same.
Parameter | Type | Description |
| uint256 | The cool down timestamp of the sender |
| uint256 | The amount of stkAAVE tokens to be sent |
| address | The receiver's address |
| uint256 | The current stkAAVE balance of the receiver |
getTotalRewardsBalance()
function getTotalRewardsBalance(address staker) external view returns (uint256)
- code
Returns the total rewards that are pending to be claimed by a staker.
Parameter | Type | Description |
| address | The staker's address |
Calculating APR for stkAAVE
To calculate the APR (as shown in the client UI), simply use:
emissionsPerSecond
x seconds in a year
/ current stakes
To get the emissionsPerSecond
, go to the stkAAVE contract and under assets()
input the stkAave address.
To get current stakes
, fetch the balanceOf()
the stkAAVE contract for the AAVE token.
Last updated