-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b118742
Showing
94 changed files
with
31,500 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# EditorConfig helps developers define and maintain consistent | ||
# coding styles between different editors and IDEs | ||
# http://editorconfig.org | ||
|
||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
ij_typescript_use_double_quotes = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.env | ||
|
||
#Buidler files | ||
cache | ||
artifacts | ||
|
||
node_modules | ||
dist/ | ||
build/ | ||
.vscode | ||
.idea | ||
|
||
coverage | ||
.coverage_artifacts | ||
.coverage_cache | ||
.coverage_contracts | ||
types/ | ||
deployed-contracts.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
stages: | ||
- prepare | ||
- test | ||
- deploy | ||
|
||
variables: | ||
IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA} | ||
|
||
prepare: | ||
stage: prepare | ||
tags: | ||
- docker-builder | ||
script: | ||
- docker build -t ${IMAGE} . | ||
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY | ||
- docker push ${IMAGE} | ||
test: | ||
stage: test | ||
tags: | ||
- aave-build-runner | ||
before_script: | ||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build | ||
script: | ||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run test | ||
after_script: | ||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean | ||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down | ||
|
||
.image_step: | ||
image: ${IMAGE} | ||
tags: | ||
- docker | ||
|
||
deploy: | ||
extends: .image_step | ||
stage: deploy | ||
script: | ||
- echo @aave-tech:registry=https://gitlab.com/api/v4/packages/npm/ >> .npmrc | ||
- echo //gitlab.com/api/v4/packages/npm/:_authToken=${CI_JOB_TOKEN} >> .npmrc | ||
- echo //gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN} >> .npmrc | ||
- ${VERSION} | ||
- npm --no-git-tag-version version prerelease --preid=beta-$CI_COMMIT_SHORT_SHA | ||
- npm --tag $CI_COMMIT_REF_NAME publish | ||
only: | ||
- master | ||
- merge_requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
artifacts | ||
cache | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"printWidth": 100, | ||
"trailingComma": "es5", | ||
"useTabs": false, | ||
"tabWidth": 2, | ||
"semi": true, | ||
"singleQuote": true, | ||
"overrides": [ | ||
{ | ||
"files": "*.sol", | ||
"options": { | ||
"semi": true, | ||
"printWidth": 100, | ||
"useTabs": false, | ||
"tabWidth": 2 | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const accounts = require(`./test-wallets.ts`).accounts; | ||
|
||
module.exports = { | ||
skipFiles: ['open-zeppelin/', 'mocks/'], | ||
mocha: { | ||
enableTimeouts: false, | ||
}, | ||
providerOptions: { | ||
accounts, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
FROM ethereum/solc:0.7.5 as build-deps | ||
|
||
FROM node:14 | ||
COPY --from=build-deps /usr/bin/solc /usr/bin/solc | ||
|
||
RUN npm config set @aave-tech:registry https://gitlab.com/api/v4/projects/19392283/packages/npm/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM node:14 | ||
ARG GITLAB_ACCESS_TOKEN | ||
|
||
WORKDIR /app | ||
|
||
ADD ./package-lock.json ./package.json /app/ | ||
|
||
RUN npm config set @aave-tech:registry https://gitlab.com/api/v4/packages/npm/ | ||
|
||
RUN npm run load:npm | ||
RUN npm ci | ||
|
||
ADD ./ /app/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Staked Aave | ||
|
||
Copyright (C) 2020 Aave | ||
|
||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. | ||
|
||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Aave Incentives contracts (v1 and v2) | ||
|
||
Sets of smart contracts to enable stake of Aave-related assets and rewards distribution based on them. | ||
|
||
## Specification | ||
|
||
### Architecture | ||
|
||
![General architecture](./stake-architecture.jpg) | ||
|
||
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 v1 | ||
|
||
The Solidity code in this repository has undergone 2 traditional smart contracts' audits by Consensys Diligence and Certik. The reports are: | ||
|
||
- Consensys Diligence | ||
- Certik | ||
|
||
## Audits v2 | ||
|
||
The new StakedAaveV2 implementation has been audited by Peckshield and property checked by Certora. | ||
|
||
## Credits | ||
|
||
For the proxy-related contracts, we have used the implementation of our friend from [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-sdk/). | ||
|
||
## License | ||
|
||
The contents of this repository are under the AGPLv3 license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pragma solidity ^0.7.5; | ||
|
||
interface IAToken { | ||
function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: agpl-3.0 | ||
pragma solidity 0.7.5; | ||
pragma experimental ABIEncoderV2; | ||
|
||
import {DistributionTypes} from '../lib/DistributionTypes.sol'; | ||
|
||
interface IAaveDistributionManager { | ||
function configureAssets(DistributionTypes.AssetConfigInput[] calldata assetsConfigInput) | ||
external; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier: agpl-3.0 | ||
pragma solidity 0.7.5; | ||
pragma experimental ABIEncoderV2; | ||
|
||
interface IAaveIncentivesController { | ||
function handleAction( | ||
address asset, | ||
uint256 userBalance, | ||
uint256 totalSupply | ||
) external; | ||
|
||
function getRewardsBalance(address[] calldata assets, address user) | ||
external | ||
view | ||
returns (uint256); | ||
|
||
function claimRewards( | ||
address[] calldata assets, | ||
uint256 amount, | ||
address to, | ||
bool stake | ||
) external returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// SPDX-License-Identifier: agpl-3.0 | ||
pragma solidity 0.7.5; | ||
|
||
interface IDelegationAwareToken { | ||
enum DelegationType {VOTING_POWER, PROPOSITION_POWER} | ||
|
||
/** | ||
* @dev emitted when a user delegates to another | ||
* @param delegator the delegator | ||
* @param delegatee the delegatee | ||
* @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER) | ||
**/ | ||
event DelegateChanged( | ||
address indexed delegator, | ||
address indexed delegatee, | ||
DelegationType delegationType | ||
); | ||
|
||
/** | ||
* @dev emitted when an action changes the delegated power of a user | ||
* @param user the user which delegated power has changed | ||
* @param amount the amount of delegated power for the user | ||
* @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER) | ||
**/ | ||
event DelegatedPowerChanged(address indexed user, uint256 amount, DelegationType delegationType); | ||
|
||
/** | ||
* @dev delegates the specific power to a delegatee | ||
* @param delegatee the user which delegated power has changed | ||
* @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER) | ||
**/ | ||
function delegate(address delegatee, DelegationType delegationType) external virtual; | ||
|
||
/** | ||
* @dev delegates all the powers to a specific user | ||
* @param delegatee the user to which the power will be delegated | ||
**/ | ||
function delegateAll(address delegatee) external virtual; | ||
|
||
/** | ||
* @dev returns the delegatee of an user | ||
* @param delegator the address of the delegator | ||
**/ | ||
function getDelegatee(address delegator, DelegationType delegationType) | ||
external | ||
view | ||
virtual | ||
returns (address); | ||
|
||
/** | ||
* @dev returns the current delegated power of a user. The current power is the | ||
* power delegated at the time of the last snapshot | ||
* @param user the user | ||
**/ | ||
function getPowerCurrent(address user, DelegationType delegationType) | ||
external | ||
view | ||
virtual | ||
returns (uint256); | ||
|
||
/** | ||
* @dev returns the delegated power of a user at a certain block | ||
* @param user the user | ||
**/ | ||
function getPowerAtBlock( | ||
address user, | ||
uint256 blockNumber, | ||
DelegationType delegationType | ||
) external view virtual returns (uint256); | ||
|
||
/** | ||
* @dev returns the total supply at a certain block number | ||
**/ | ||
function totalSupplyAt(uint256 blockNumber) external view virtual returns (uint256); | ||
} |
Oops, something went wrong.