diff --git a/images/blocksec_eos_rex_v1.0-signed.pdf b/images/blocksec_eos_rex_v1.0-signed.pdf new file mode 100644 index 00000000..2f833d36 Binary files /dev/null and b/images/blocksec_eos_rex_v1.0-signed.pdf differ diff --git a/images/diagram_bps_multisig.png b/images/diagram_bps_multisig.png new file mode 100644 index 00000000..21ae1a4e Binary files /dev/null and b/images/diagram_bps_multisig.png differ diff --git a/images/diagram_rex_inflows.png b/images/diagram_rex_inflows.png new file mode 100644 index 00000000..3538991c Binary files /dev/null and b/images/diagram_rex_inflows.png differ diff --git a/images/diagram_staking_contract_flow.png b/images/diagram_staking_contract_flow.png new file mode 100644 index 00000000..1788cdaf Binary files /dev/null and b/images/diagram_staking_contract_flow.png differ diff --git a/images/diagram_user_token_flow.png b/images/diagram_user_token_flow.png new file mode 100644 index 00000000..01b7498f Binary files /dev/null and b/images/diagram_user_token_flow.png differ diff --git a/native/60_advanced-topics/30_staking/01_overview.md b/native/60_advanced-topics/30_staking/01_overview.md new file mode 100644 index 00000000..dd2bb9b7 --- /dev/null +++ b/native/60_advanced-topics/30_staking/01_overview.md @@ -0,0 +1,41 @@ +--- +title: Overview +--- + + + Staking Overview + + +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. + diff --git a/native/60_advanced-topics/30_staking/10_contracts.md b/native/60_advanced-topics/30_staking/10_contracts.md new file mode 100644 index 00000000..78a14e86 --- /dev/null +++ b/native/60_advanced-topics/30_staking/10_contracts.md @@ -0,0 +1,249 @@ +--- +title: Contracts +--- + + + Staking Contracts + + +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](https://eosauthority.com/account/eosio) 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. \ No newline at end of file diff --git a/native/60_advanced-topics/30_staking/20_token-flows.md b/native/60_advanced-topics/30_staking/20_token-flows.md new file mode 100644 index 00000000..ce40a2ee --- /dev/null +++ b/native/60_advanced-topics/30_staking/20_token-flows.md @@ -0,0 +1,64 @@ +--- +title: Token Flows +--- + + + Staking Token Flows + + +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. \ No newline at end of file diff --git a/native/60_advanced-topics/30_staking/30_security.md b/native/60_advanced-topics/30_staking/30_security.md new file mode 100644 index 00000000..e2c2e001 --- /dev/null +++ b/native/60_advanced-topics/30_staking/30_security.md @@ -0,0 +1,81 @@ +--- +title: Security +--- + + + Staking Security + + +To understand the security that underpins the EOS network's staking protocol, we need to look at the +various layers of security that are in place to protect the network and its users and how they impact staking, as well +as the additional security measures that apply only to staking. + +## System Level Security + +The staking actions and logic exist within the core system contract on EOS, `eosio.system`. +This contract is responsible for managing the entire EOS network, including account creation, chain governance, and resource management. + +The system contract is designed to be secure and robust, with extensive testing and auditing to ensure that it is free +from vulnerabilities and exploits as it controls the most critical functions of the network. There isn't a single +contract on the EOS network that undergoes more scrutiny or has more eyes on it than the system contract, both +internally and externally. + +The contract account is a "privileged" account, meaning that it has special permissions and access to system-level +capabilities that regular accounts do not have. This is to ensure that the contract can perform its functions without +being hindered by the same restrictions that apply to regular accounts, and also simplifies the general development and +flow of actions that the contract needs to perform, reducing the complexity and potential for errors. + +## Multisig Contract Control + +The system contract is controlled by 15 of the 21 block producers on the network, who must sign off on any changes to +the contract. This is the highest level of security that can be achieved on the EOS network, as it requires a supermajority +of the most trusted and reputable entities on the network. + +This multisig control ensures that no single entity or group can make changes to the system contract without the +on-chain and very public approval of the majority of the block producers, who are elected by the token holders and +have a vested interest in maintaining the security and integrity of the network. + +![BP Multisig](/images/diagram_bps_multisig.png) + +## Token Ownership + +All funds that are staked into the staking protocol are deposited into the [`eosio.rex` account](https://eosauthority.com/account/eosio.rex) +which is also controlled by the same quorum of BPs. When a user first deposits their funds into the staking protocol, +they are effectively transferring ownership of those funds to the system contract in return for the REX token that +represents their staked value. + +In the same way that all tokens work on all blockchains, the contract is the ultimate authority over who owns what, +and the user's ownership of tokens is represented as a row in the on-chain state database that records the user's +balance and other relevant information. + +## Lockup Periods + +When a user stakes EOS into the staking protocol, they are subject to a lockup period that prevents them from +unstaking their tokens for a certain amount of time. This lockup period is infinite as long as a user is not +unstaking their tokens, and once they decide to begin the unstaking period the lockup period is 21 days. + +This provides not only a buffer for the network to react to any malicious or fraudulent activity but also a +mechanism for users to protect their funds from being stolen or misused by bad actors as well as a stable and +predictable environment for the staking protocol to operate in. + +## Comprehensive Testing + +The system contract as a whole has over 10,000 lines of tests, which are run on every PR and release to ensure that +the contract is functioning as expected and that no new vulnerabilities or exploits have been introduced. This +testing is done by both the core development team and external parties who ensure that the contract is secure and +robust. + +Tests relevant to the staking protocol can be found at the following locations: + +- [Core staking tests](https://github.com/eosnetworkfoundation/eos-system-contracts/blob/8ecd1ac6d312085279cafc9c1a5ade6affc886da/tests/eosio.system_tests.cpp#L3948) +- [Maturity tests](https://github.com/eosnetworkfoundation/eos-system-contracts/blob/8ecd1ac6d312085279cafc9c1a5ade6affc886da/tests/eosio.system_rex_matured_tests.cpp#L1) +- [Fees tests](https://github.com/eosnetworkfoundation/eos-system-contracts/blob/8ecd1ac6d312085279cafc9c1a5ade6affc886da/tests/eosio.fees_tests.cpp#L1) +- [Reward contract tests](https://github.com/eosnetworkfoundation/eosio.reward/blob/4a2f3cb9ffcbabb5f1682540636aae02d5d8480c/eosio.reward.spec.ts#L1) + + +## Audits + +We have also conducted an audit with [BlockSec](https://blocksec.com/) to ensure that the staking protocol is secure and +functioning as expected. The audit report can be found [here](/docs/latest/miscellaneous/audits). + + diff --git a/native/60_advanced-topics/30_staking/index.md b/native/60_advanced-topics/30_staking/index.md new file mode 100644 index 00000000..4fb9d669 --- /dev/null +++ b/native/60_advanced-topics/30_staking/index.md @@ -0,0 +1,14 @@ +--- +title: Staking +--- + + + Staking + + +Learn about how EOS Staking works on EOS on a technical level. + +- [Overview](./01_overview.md) +- [Contracts](./10_contracts.md) +- [Token Flows](./20_token-flows.md) +- [Security](./30_security.md) \ No newline at end of file diff --git a/native/999_miscellaneous/20_audits.md b/native/999_miscellaneous/20_audits.md index 172aa3f9..8510c713 100644 --- a/native/999_miscellaneous/20_audits.md +++ b/native/999_miscellaneous/20_audits.md @@ -9,3 +9,4 @@ Here you can find a list of the audits that have been completed on various EOS s | 05-03-2023 | [EOS EVM Fuzzing Audit](/images/05_03_2023_eos_evm_fuzzing_audit_sentnl.pdf) | [sentnl.io](https://sentnl.io/) | | 22-09-2023 | [EOS EVM Bridge Audit](/images/22-09-2023-eos-evm-bridge-blocksec.pdf) | [BlockSec](https://blocksec.com/) | | 22-09-2023 | [EOS EVM Audit](/images/22-09-2023-eos-evm-blocksec.pdf) | [BlockSec](https://blocksec.com/) | +| 07-02-2024 | [EOS REX Audit](/images/blocksec_eos_rex_v1.0-signed.pdf) | [BlockSec](https://blocksec.com/) |