-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #268 from eosnetworkfoundation/staking-docs
Staking docs
- Loading branch information
Showing
11 changed files
with
450 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,41 @@ | ||
--- | ||
title: Overview | ||
--- | ||
|
||
<head> | ||
<title>Staking Overview</title> | ||
</head> | ||
|
||
EOS Staking is a system-level contract that allows users to stake their EOS tokens to | ||
receive rewards from the network. | ||
|
||
## Lockup periods | ||
|
||
When you stake your EOS tokens you lock them up for a certain period of time. | ||
|
||
The minimum lockup period is 21 days, but that period could be longer depending on when | ||
you as the user decide to unstake your tokens, as the lockup period only starts when you unstake. | ||
|
||
Otherwise, the lockup period is indefinite. | ||
|
||
## Accounting token | ||
|
||
When you stake your EOS tokens you get a token called REX in return. | ||
REX is a non-transferable token that represents the amount of value you have staked. | ||
The conversion rate between EOS and REX is dynamic and goes up as more staking rewards are | ||
distributed into the rewards pool. | ||
|
||
The value of REX never decreases, only increases. | ||
|
||
## Rewards | ||
|
||
The rewards from staking originate from a pre-allocated bucket of EOS tokens that are | ||
designated for staking rewards and aimed at incentivizing users to stake their tokens, | ||
growing and securing the network. | ||
|
||
## Liquid Staking | ||
|
||
EOS Staking is **not** a liquid staking protocol, meaning that you cannot trade your REX tokens or restake them | ||
in other protocols. Once you stake your EOS tokens and receive REX tokens in return, you cannot trade them or | ||
use them in any other way than to unstake them and receive EOS tokens back directly from the EOS Staking protocol. | ||
|
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,249 @@ | ||
--- | ||
title: Contracts | ||
--- | ||
|
||
<head> | ||
<title>Staking Contracts</title> | ||
</head> | ||
|
||
There are a few different contracts involved in EOS staking. | ||
|
||
1. `eosio.system` - The system and staking contract. | ||
2. `eosio.reward` - An intermediate reward dispersal contract. | ||
3. `eosio.rex` - Account that holds all funds in the staking protocol. | ||
|
||
## eosio.system | ||
|
||
The system contract is wider than just staking and controls the entire EOS network with | ||
capabilities like account creation, chain governance, and resource management. | ||
|
||
The staking portions of the system contract are responsible for managing the staking | ||
and unstaking of EOS tokens, as well as the distribution of rewards from the pre-allocated | ||
staking rewards pool. | ||
|
||
![Staking Contract Flow](/images/diagram_staking_contract_flow.png) | ||
|
||
### Depositing Funds | ||
|
||
In order to use EOS inside the staking portion of the system contract, you need to deposit them first. | ||
|
||
```cpp | ||
void deposit( const name& owner, const asset& amount ) | ||
``` | ||
This will transfer your funds to the `eosio.rex` account and register them as deposited into the staking protocol. | ||
This will **not** stake them for you yet though, they are simply held within the protocol. | ||
> **Parameters** | ||
> The parameter `owner` is the account that is depositing the funds. | ||
### Staking Deposited Funds | ||
Once you have deposited funds into the staking protocol, you can stake them to receive rewards. | ||
```cpp | ||
void buyrex( const name& from, const asset& amount ) | ||
``` | ||
|
||
This will stake the funds that you have deposited into the staking protocol and issue you REX tokens in return. | ||
|
||
|
||
### Staking Funds From Voting Rights | ||
|
||
On EOS you can have your EOS staked as voting rights. You may also use those funds as a source for staking. | ||
|
||
```cpp | ||
void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ) | ||
``` | ||
This will move your voting rights staked funds into rewards staked funds, and issue you REX tokens in return. | ||
You will still retain your voting rights. | ||
> **Note** | ||
> All staked funds within the staking protocol have voting rights attached to them. | ||
### Unstaking Funds | ||
```cpp | ||
void mvfrsavings( const name& owner, const asset& rex ) | ||
``` | ||
|
||
This will move funds out of eternally locked "savings" account and begin the 21 day unstaking period. Any funds you | ||
move out of that savings account within the same day will be attributed to the same unstaking bucket and mature within | ||
the same 21-day period. | ||
|
||
### Withdrawing Funds | ||
|
||
Once the 21-day unstaking/maturation period has finished, you can sell your position and withdraw your funds. | ||
You will need to do this in two steps. | ||
|
||
```cpp | ||
void sellrex( const name& from, const asset& rex ) | ||
``` | ||
This action will convert your REX tokens back into EOS and register them as available to withdraw. | ||
```cpp | ||
void withdraw( const name& owner, const asset& amount ) | ||
``` | ||
|
||
This action will withdraw your EOS tokens from the staking protocol and transfer them to your account. | ||
|
||
|
||
> **Note** | ||
> Any action you take within the staking protocol once a 21-day unstaking period has finished will trigger an | ||
> automatic `sellrex` on your fully matured REX tokens. This will convert them back into EOS and register them as | ||
> available to withdraw. | ||
### Tables | ||
|
||
The system contract has a few tables that are relevant to staking. | ||
|
||
#### rexbal | ||
|
||
[The `rexbal` table](https://eosauthority.com/account/eosio?network=eos&scope=eosio&table=rexbal&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables) holds information about staked balances for users. | ||
|
||
- `version` | ||
- `owner` | ||
- `vote_stake` | ||
- `rex_balance` - the amount of REX owned | ||
- `matured_rex` - matured REX available for selling | ||
- `rex_maturities` - An array of maturity dates and amounts | ||
|
||
#### rexfund | ||
|
||
[The `rexfund` table](https://eosauthority.com/account/eosio?network=eos&scope=eosio&table=rexfund&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables&lower_bound=) | ||
holds information about the deposited but unstaked EOS funds for users. | ||
|
||
- `version` | ||
- `owner` | ||
- `balance` - the amount of EOS deposited | ||
|
||
#### rexmaturity | ||
|
||
[The `rexmaturity` table](https://eosauthority.com/account/eosio?network=eos&scope=eosio&table=rexmaturity&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables) | ||
holds information about the maturity dates of REX tokens for users. | ||
|
||
- `num_of_maturity_buckets` - The number of days until a position fully matures | ||
- `sell_matured_rex` - A flag that indicates if to sell matured positions on any action | ||
- `buy_rex_to_savings` - A flag that indicates if staked funds go directly to savings or not | ||
|
||
#### rexpool | ||
|
||
[The `rexpool` table](https://eosauthority.com/account/eosio?network=eos&scope=eosio&table=rexpool&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables) | ||
holds information about the staking pool. | ||
|
||
- `version` | ||
- `total_lent` - total amount of EOS in open rex_loans | ||
- `total_unlent` - total amount of EOS available to be lent (connector) | ||
- `total_rent` - fees received in exchange for lent (connector) | ||
- `total_lendable` - total amount of EOS that have been lent (total_unlent + total_lent) | ||
- `total_rex` - total number of REX shares allocated to contributors to total_lendable | ||
- `namebid_proceeds` the amount of EOS to be transferred from namebids to REX pool | ||
- `loan_num` increments with each new loan | ||
|
||
This is useful if you want to calculate the price of EOS vs REX. | ||
|
||
```typescript | ||
static convertEosToRex(eos:number){ | ||
const pool = get(rexpool); | ||
if(!pool) return 0; | ||
const S0 = parseFloat(pool.total_lendable.split(' ')[0]); | ||
const S1 = S0 + eos; | ||
const R0 = parseFloat(pool.total_rex.split(' ')[0]); | ||
const R1 = (S1 * R0) / S0; | ||
return parseFloat(parseFloat((R1 - R0).toString()).toFixed(4)); | ||
} | ||
|
||
static convertRexToEos(rex:number){ | ||
const pool = get(rexpool); | ||
if(!pool) return 0; | ||
const S0 = parseFloat(pool.total_lendable.split(' ')[0]); | ||
const R0 = parseFloat(pool.total_rex.split(' ')[0]); | ||
const R1 = R0 + rex; | ||
const S1 = (S0 * R1) / R0; | ||
return parseFloat(parseFloat((S1 - S0).toString()).toFixed(4)); | ||
} | ||
``` | ||
|
||
If you'd like to view full code for this example, [see here](https://github.com/eosnetworkfoundation/rex-staking-portal/blob/6f1297bbb5cc5e4d1e39ac5e52e815ea69a29803/src/lib/wharf.ts#L142-L143). | ||
|
||
#### rexretpool | ||
|
||
[The `rexretpool` table](https://eosauthority.com/account/eosio?network=eos&scope=eosio&table=rexretpool&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables) | ||
holds information about the return pool for REX tokens. | ||
|
||
- `version` | ||
- `last_dist_time` - the last time proceeds from renting, ram fees, and name bids were added to the rex pool | ||
- `pending_bucket_time` - timestamp of the pending 12-hour return bucket | ||
- `oldest_bucket_time` - cached timestamp of the oldest 12-hour return bucket | ||
- `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, | ||
- `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool, | ||
- `proceeds` the maximum amount of proceeds that can be added to the rex pool at any given time | ||
|
||
## eosio.reward | ||
|
||
The [reward contract](https://eosauthority.com/account/eosio.reward) ([see contract code](https://github.com/eosnetworkfoundation/eosio.reward)) is an intermediate contract | ||
that is responsible for dispersing the rewards from the staking rewards tokenomics bucket to the various strategies | ||
aimed at rewarding the EOS community. | ||
|
||
It allows the EOS Network to define a [set of receivers](https://eosauthority.com/account/eosio.reward?mode=contract&sub=tables&network=eos&scope=eosio.reward&table=strategies&limit=10&index_position=1&key_type=i64&reverse=0) | ||
that will receive rewards, and a weight for each receiver. | ||
|
||
See the [inflows](./inflows) document for more information on how the reward contract is funded. | ||
|
||
> **Note** | ||
> Modifying strategies is controlled by the block producers and requires a 15/21 multisig to change. | ||
### Adding or Updating Strategies | ||
|
||
```cpp | ||
void setstrategy( const name strategy, const uint16_t weight ) | ||
``` | ||
This action will set or update a strategy with a given weight. The weight is a percentage of the total rewards that | ||
will be allocated to this strategy. For instance, if there are three strategies with weights of 1000, 2000, and 7000, | ||
then the first strategy will receive 10% of the rewards, the second 20%, and the third 70%. | ||
### Removing Strategies | ||
```cpp | ||
void delstrategy( const name strategy ) | ||
``` | ||
|
||
This will remove any strategy from the reward contract. | ||
|
||
|
||
|
||
### Distributing Rewards | ||
|
||
```cpp | ||
void distribute() | ||
``` | ||
|
||
Funds that have flowed into this contract since the last distribution will be distributed to the strategies based on their | ||
weights. It is better to call this at a higher interval to make sure that any small amounts of funds are not lost to | ||
rounding errors. | ||
|
||
> **Note** | ||
> Any account can call this action. | ||
|
||
|
||
|
||
## eosio.rex | ||
|
||
The [contract on the eosio.rex account](https://github.com/eosnetworkfoundation/eos-system-contracts/blob/8ecd1ac6d312085279cafc9c1a5ade6affc886da/contracts/eosio.system/src/rex.results.cpp#L1) is merely a record-keeping contract. Each of the actions | ||
does nothing (no implmentation) and is only there to provide an identifiable record within the transactions stack that | ||
can be tracked and filtered by external tooling such as history solutions or frontend SDKs that want more | ||
information that normally would not be available (like the REX received for an amount of EOS in a `buyrex` action). | ||
|
||
```cpp | ||
void buyresult( const asset& rex_received ) { } | ||
void sellresult( const asset& proceeds ) { } | ||
void orderresult( const name& owner, const asset& proceeds ) { } | ||
void rentresult( const asset& rented_tokens ) { } | ||
``` | ||
As different actions trigger results on the `eosio.rex` account, it will add one of these identifiable records to the | ||
transaction stack based on the calling action. For instance, if you call `buyrex`, you will see a `buyresult` record. |
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,64 @@ | ||
--- | ||
title: Token Flows | ||
--- | ||
|
||
<head> | ||
<title>Staking Token Flows</title> | ||
</head> | ||
|
||
The inflows to the EOS staking protocol travel through a few different contracts, each with their own responsibilities. | ||
We will cover the contracts that are involved in the inflows to the staking protocol, as well as the origins of the funds. | ||
|
||
## Tokenomics Change | ||
|
||
[In May of 2024 the EOS network underwent a tokenomics change](https://eosnetwork.com/blog/eos-network-approves-tokenomics-proposal-ushering-in-a-new-era-for-eos/) that introduced a new bucket | ||
of EOS tokens designated for staking rewards. | ||
|
||
**250 million** EOS was set aside in this bucket to be emitted with a halving schedule every 4 years. Meaning that in | ||
the first 4 years 125,000,000 EOS will be distributed as staking rewards (31,250,000 EOS per year), and in the next 4 years | ||
62,500,000 EOS will be distributed as staking rewards (15,625,000 EOS per year), and so on. | ||
|
||
Inflation for the chain was also shut off during that change, and the various buckets replaced that inflated EOS. | ||
This means that instead of inflating the chain at a set rate of X% per year, the chain now distributes a percentage of the | ||
pre-allocated reserved supply to various parts of the network, like staking rewards. | ||
|
||
## Flow of Staking Rewards | ||
|
||
Every time a block producer claims their rewards, they trigger a chain of events that results in the distribution of | ||
various token allocations to target accounts. | ||
|
||
![Staking Inflows](/images/diagram_rex_inflows.png) | ||
|
||
The block producers claim rewards from the **System Contract**, which then flows EOS into their accounts, and | ||
into the `eosio.saving` account that holds a contract which distributes EOS to **EOS Labs**, the **EOS Network | ||
Foundation**, and the **Staking Rewards** buckets (these are configured in [the `eosio.saving` contract](https://eosauthority.com/account/eosio.saving?network=eos&scope=eosio.saving&table=config&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables&action=claim#transactions)). | ||
|
||
As the rewards flow into the `eosio.saving` account, they are immediately split up according to the distribution | ||
configurations on that contract, which are set by a 15/21 multisig of the block producers and tallied into | ||
[the `claimers` table](https://eosauthority.com/account/eosio.saving?network=eos&scope=eosio.saving&table=claimers&limit=10&index_position=1&key_type=i64&reverse=0&mode=contract&sub=tables&action=claim#transactions). | ||
|
||
Once funds are available, each entity can claim their rewards by calling the `claim` action, which then sends | ||
the funds to the account specified in the configuration. | ||
|
||
In the case of the **Staking Rewards** bucket, the funds are sent to the `eosio.reward` contract, which sit in the | ||
account until they are distributed to the various strategies that are configured there by an account calling the | ||
`distribute` action. | ||
|
||
When the `distribute` action is called, the funds aimed at EOS Staking are used in the [`donatetorex` action](https://github.com/eosnetworkfoundation/eos-system-contracts/blob/8ecd1ac6d312085279cafc9c1a5ade6affc886da/contracts/eosio.system/src/rex.cpp#L389) | ||
back on the System Contract which adds those funds to the REX pools, and then sends the funds to `eosio.rex` for | ||
accounting purposes. | ||
|
||
These pathways and mechanisms allow all participants to clearly see the flow of EOS as it makes its way through the | ||
chain's various contracts and accounts, and ensures that the funds are distributed according to the network's | ||
governance decisions instead of being hardcoded into smart contract logic with low visibility and flexibility. | ||
|
||
## Flow of User Tokens | ||
|
||
![User token flow](/images/diagram_user_token_flow.png) | ||
|
||
When a user stakes their EOS to the protocol staking system they are transferring their EOS tokens to the system | ||
contract which then issues them REX tokens in return and forwards their EOS to the `eosio.rex` account for accounting | ||
purposes. | ||
|
||
Since the value of REX can never go down, the user is guaranteed to receive _at least_ the same amount of EOS back when | ||
they unstake, sell, and withdraw their REX tokens. |
Oops, something went wrong.