Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete exchange rate #40

Merged
merged 26 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 32 additions & 30 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,51 @@ Business Source License 1.1
License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
“Business Source License” is a trademark of MariaDB Corporation Ab.

---
-----------------------------------------------------------------------------

Parameters

Licensor: Aave DAO, represented by its governance smart contracts
Licensor: Aave DAO, represented by its governance smart contracts

Licensed Work: Stake Token
The Licensed Work is (c) 2024 Aave DAO, represented by its governance smart contracts

Licensed Work: Aave v3.1
The Licensed Work is (c) 2024 Aave DAO, represented by its governance smart contracts

Additional Use Grant: You are permitted to use, copy, and modify the Licensed Work, subject to
the following conditions:

- Your use of the Licensed Work shall not, directly or indirectly, enable, facilitate,
or assist in any way with the migration of users and/or funds from the Aave ecosystem.
The "Aave ecosystem" is defined in the context of this License as the collection of
software protocols and applications approved by the Aave governance, including all
those produced within compensated service provider engagements with the Aave DAO.
The Aave DAO is able to waive this requirement for one or more third-parties, if and
only if explicitly indicating it on a record 'authorizations' on staketoken.aavelicense.eth.
- You are neither an individual nor a direct or indirect participant in any incorporated
organization, DAO, or identifiable group, that has deployed in production any original
or derived software ("fork") of the Aave ecosystem for purposes competitive to Aave,
within the preceding two years.
The Aave DAO is able to waive this requirement for one or more third-parties, if and
only if explicitly indicating it on a record 'authorizations' on staketoken.aavelicense.eth.
- You must ensure that the usage of the Licensed Work does not result in any direct or
indirect harm to the Aave ecosystem or the Aave brand. This encompasses, but is not limited to,
reputational damage, omission of proper credit/attribution, or utilization for any malicious
intent.

Change Date: The earlier of: - 2028-01-08 - The date specified in the 'change-date' record on staketoken.aavelicense.eth

Change License: MIT

---
the following conditions:
- Your use of the Licensed Work shall not, directly or indirectly, enable, facilitate,
or assist in any way with the migration of users and/or funds from the Aave ecosystem.
The "Aave ecosystem" is defined in the context of this License as the collection of
software protocols and applications approved by the Aave governance, including all
those produced within compensated service provider engagements with the Aave DAO.
The Aave DAO is able to waive this requirement for one or more third-parties, if and
only if explicitly indicating it on a record 'authorizations' on v31.aavelicense.eth.
- You are neither an individual nor a direct or indirect participant in any incorporated
organization, DAO, or identifiable group, that has deployed in production any original
or derived software ("fork") of the Aave ecosystem for purposes competitive to Aave,
within the preceding four years.
The Aave DAO is able to waive this requirement for one or more third-parties, if and
only if explicitly indicating it on a record 'authorizations' on v31.aavelicense.eth.
- You must ensure that the usage of the Licensed Work does not result in any direct or
indirect harm to the Aave ecosystem or the Aave brand. This encompasses, but is not limited to,
reputational damage, omission of proper credit/attribution, or utilization for any malicious
intent.

Change Date: The earlier of:
- 2027-03-06
- If specified, the date in the 'change-date' record on v31.aavelicense.eth
pavelvm5 marked this conversation as resolved.
Show resolved Hide resolved

Change License: MIT

-----------------------------------------------------------------------------

Notice

The Business Source License (this document, or the “License”) is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.

---
-----------------------------------------------------------------------------

Terms

Expand Down
93 changes: 53 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,77 @@
# Stake token
# StakeToken - Vault

New version of the Aave Safety Module stk tokens.
New version of the Aave Safety Module stk tokens. This is an updated version intended for the Umbrella project.

pavelvm5 marked this conversation as resolved.
Show resolved Hide resolved
## Summary of Changes
## About

The `StakeToken` is a token deployed on Ethereum, with the main utility of participating in the Aave safety module.
The `StakeToken` contains an EIP-4626 generic token vault for all non-rebase tokens (especially targeting `static-a-tokens`).

There are currently two proxy contracts which utilize a `StakeToken`:
## Features

- [stkAAVE](https://etherscan.io/token/0x4da27a545c0c5b758a6ba100e3a049001de870f5) with the [StakedAaveV3 implementation](https://etherscan.io/address/0xaa9faa887bce5182c39f68ac46c43f36723c395b#code)
- [stkABPT](https://etherscan.io/address/0xa1116930326D21fB917d5A27F1E9943A9595fb47#code) with the [StakedTokenV3 implementation](https://etherscan.io/address/0x9921c8cea5815364d0f8350e6cbe9042a92448c9#code)
- **Full [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) compatibility.**
- Withdrawal of funds from the storage can be carried out only after activation of cooldown after a certain time.
- The `StakeToken` is designed to cover small `Bad Debt`'s in a semi-automatic mode, but can withdraw almost all funds up to the `getMaxSlashableAssets()` amount in emergencies.
- Providing liquidity in the `StakeToken` includes the risk of slashing and is therefore paid for with additional rewards through `REWARDS_CONTROLLER`.
- **Permit-transactions support.** To enable interfaces to offer gas-less transactions to deposit with a permit.
- **Upgradable by the Aave governance.** Similar to other contracts of the Aave ecosystem, the Level 1 executor (short executor) will be able to add new features to the deployed instances of the `stakeTokens`.

The implementation can be found [here](https://github.com/bgd-labs/aave-stk-gov-v3)
Together with all the standard ERC20 functionalities, the current implementation includes extra logic for:
See [`IERC4626StakeToken.sol`](src/contracts/interfaces/IERC4626StakeToken.sol) for detailed method documentation.

- entering and exiting the safety module
- management & accounting for safety module rewards
- management & accounting of voting and proposition power
- slashing mechanics for slashing in the case of shortfall events
## Deployed Addresses

The new iteration of the generic `StakeToken` is intended for new Deployments **only**.
While it does not alter any core mechanics, the new iteration cleans up numerous historical artifacts.
An up-to-date address can be fetched from the respective [address-book pool library](https://github.com/bgd-labs/aave-address-book/blob/main/src/AaveV3Ethereum.sol).

The main goals here are:
## Limitations

- simpler inheritance chain
- cleaner storage layout
- updated/modernized libraries
The `StakeToken` is not natively integrated into the aave protocol and therefore cannot use multiple sources of additional incentives. Additional incentives included in the `static-a-tokens` are disabled when using the `StakeTokens`.

## Development
Since the `StakeToken` implies a decrease in `totalAssets()` over time (loss of funds), irreversible losses associated with the accuracy of calculations could occur over time.

This project uses [Foundry](https://getfoundry.sh). See the [book](https://book.getfoundry.sh/getting-started/installation.html) for detailed instructions on how to install and use Foundry.
The template ships with sensible default so you can use default `foundry` commands without resorting to `MakeFile`.
Losses do not exceed 1 wei if calculated relative to assets, but they can be more significant when using functions related to calculations through shares (due to OZ roundings). It is recommended to manually check and find more profitable ways to deposit/withdraw liquidity. However, in most cases, the difference should not exceed any significant amount.

### Setup
### Inheritance

```sh
cp .env.example .env
forge install
```
The `StakeToken` is based on [`open-zeppelin-upgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable) contracts.

### Test
The `StakeToken` is separated into 2 different contracts, where `ERC4626StakeTokenUpgradeable` inherits `ERC4626Upgradeable`.

```sh
forge test
```
- `ERC4626StakeTokenUpgradeable` is an abstract contract implementing the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) methods for an underlying asset. It provides basic functionality for the `StakeToken` without any access control or pausability.
- `StataTokenV2` is the main contract stitching things together, while adding `Pausable`, `Rescuable`, `Permit`, and the actual initialization.

#### depositWithPermit

[`ERC20PermitUpgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/9a47a37c4b8ce2ac465e8656f31d32ac6fe26eaa/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol) has been added to the `StakeToken`, which added the ability to make a deposit using a valid signature and 1 tx via `permit()`.

## Advanced features
#### Rescuable

### Diffing
[`Rescuable`](https://github.com/bgd-labs/solidity-utils/blob/main/src/contracts/utils/Rescuable.sol) has been applied to
the `StakeToken` which will allow the `owner()` of the corresponding `StakeToken` to rescue tokens on the contract.

For contracts upgrading implementations it's quite important to diff the implementation code to spot potential issues and ensure only the intended changes are included.
Therefore the `Makefile` includes some commands to streamline the diffing process.
#### Pausable

#### Download
The `StakeToken` implements the [`PausableUpgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/9a47a37c4b8ce2ac465e8656f31d32ac6fe26eaa/contracts/utils/PausableUpgradeable.sol) allowing `owner()` to pause the vault in case of an emergency.
As long as the vault is paused, any non-view actions (deposit/redeem/slash) are impossible.

You can `download` the current contract code of a deployed contract via `make download chain=polygon address=0x00`. This will download the contract source for specified address to `src/etherscan/chain_address`. This command works for all chains with a etherscan compatible block explorer.
## Dependencies

#### Git diff
- Foundry, [how-to install](https://book.getfoundry.sh/getting-started/installation) (we recommend also update to the last version with `foundryup`)
- Lcov
- Optional, only needed for coverage testing
- For Ubuntu, you can install via `apt install lcov`
- For Mac, you can install via `brew install lcov`

### Setup

```sh
cp .env.example .env

forge install

# optional, to install prettier
bun install
```

You can `git-diff` a downloaded contract against your src via `make git-diff before=./etherscan/chain_address after=./src out=filename`. This command will diff the two folders via git patience algorithm and write the output to `diffs/filename.md`.
### Tests

**Caveat**: If the onchain implementation was verified using flatten, for generating the diff you need to flatten the new contract via `forge flatten` and supply the flattened file instead fo the whole `./src` folder.
- To run the full test suite: `make test`
- To re-generate the coverage report: `make coverage`
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ffi = true

[fuzz]
runs = 1024
max_test_rejects = 1_000_000
max_test_rejects = 1000000

[rpc_endpoints]
mainnet = "${RPC_MAINNET}"
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stake-token",
"version": "1.0.0",
"name": "stake-token-v2",
"version": "2.0.0",
"scripts": {
"lint": "prettier ./",
"lint:fix": "npm run lint -- --write"
Expand All @@ -10,7 +10,7 @@
"url": "git+https://github.com/bgd-labs/stake-token.git"
},
"keywords": [],
"author": "BGD labs",
"author": "BGD Labs",
"license": "BUSL-1.1",
"bugs": {
"url": "https://github.com/bgd-labs/stake-token/issues"
Expand All @@ -20,4 +20,4 @@
"prettier": "2.8.7",
"prettier-plugin-solidity": "1.1.3"
}
}
}
65 changes: 50 additions & 15 deletions src/contracts/StakeToken.sol
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import {IERC20Permit} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol';
import {IERC20Metadata} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol';

import {IPoolAddressesProvider} from './interfaces/IPoolAddressesProvider.sol';
import {IRewardsController} from './interfaces/IRewardsController.sol';

import {Initializable} from 'openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol';
import {OwnableUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol';
import {PausableUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol';
import {ERC20Upgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol';
import {ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol';
import {ERC4626Upgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol';

import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import {IERC20Permit} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol';
import {IERC20Metadata} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol';

import {Rescuable, IRescuable} from 'solidity-utils/contracts/utils/Rescuable.sol';

import {IERC4626StakeToken} from './interfaces/IERC4626StakeToken.sol';
import {IRewardsController} from './interfaces/IRewardsController.sol';
import {ERC4626StakeTokenUpgradeable} from './extension/ERC4626StakeTokenUpgradeable.sol';

/**
* @title StakeToken
* @notice StakeToken is an `ERC-4626` contract that aims to supply assets as debt repayment in the event of a `Bad Debt`.
* Stakers will be paid rewards through `REWARDS_CONTROLLER` for providing underlying assets. In a situation where a `Bad Debt`
* exceeds a threshold value, the `slash()` function will be called, which will take the part of the assets
* necessary for repayment from this vault and transfer them to the desired address.
* @author BGD labs
*/
contract StakeToken is
Initializable,
PausableUpgradeable,
ERC20PermitUpgradeable,
ERC4626StakeTokenUpgradeable
ERC4626StakeTokenUpgradeable,
OwnableUpgradeable,
Rescuable
{
constructor(
IRewardsController rewardsController,
IPoolAddressesProvider provider
) ERC4626StakeTokenUpgradeable(rewardsController, provider) {
IRewardsController rewardsController
) ERC4626StakeTokenUpgradeable(rewardsController) {
_disableInitializers();
}

Expand All @@ -34,7 +45,6 @@ contract StakeToken is
string calldata name,
string calldata symbol,
address owner,
address guardian,
uint256 cooldown_,
uint256 unstakeWindow_
) external initializer {
Expand All @@ -44,11 +54,11 @@ contract StakeToken is
__Pausable_init();

__Ownable_init(owner);
__Ownable_With_Guardian_init(guardian);

__StakeTokenUpgradeable_init(stakedToken, cooldown_, unstakeWindow_);
}

/// @inheritdoc IERC4626StakeToken
function depositWithPermit(
uint256 assets,
address receiver,
Expand All @@ -70,14 +80,39 @@ contract StakeToken is
return deposit(assets, receiver);
}

function pause() external onlyOwnerOrGuardian {
/// @inheritdoc IERC4626StakeToken
function pause() external onlyOwner {
_pause();
}

function unpause() external onlyOwnerOrGuardian {
/// @inheritdoc IERC4626StakeToken
function unpause() external onlyOwner {
_unpause();
}

/// @inheritdoc IERC4626StakeToken
function slash(
address destination,
uint256 amount
) external override onlyOwner returns (uint256) {
return _slash(destination, amount);
}

/// @inheritdoc IERC4626StakeToken
function setUnstakeWindow(uint256 newUnstakeWindow) external override onlyOwner {
_setUnstakeWindow(newUnstakeWindow);
}

/// @inheritdoc IERC4626StakeToken
function setCooldown(uint256 newCooldown) external override onlyOwner {
_setCooldown(newCooldown);
}

/// @inheritdoc IRescuable
function whoCanRescue() public view override returns (address) {
return owner();
}

function decimals()
public
view
Expand Down
Loading
Loading