mirror of
https://github.com/vacp2p/rfc-index.git
synced 2026-01-09 13:58:08 -05:00
Update staking-streamer.md
This commit is contained in:
@@ -19,8 +19,8 @@ The staking streamer protocol is currently used in Status Network.
|
||||
The Status Network is a layer 2 blockchain that is gasless.
|
||||
To achieve no gas fees for transactions conducted on the network,
|
||||
users utilize a staking mechanism with native tokens.
|
||||
This mechanism, called the staking streamer,
|
||||
allow users to accumulate a ERC-20 token called Karma.
|
||||
This mechanism, called the staking streamer,
|
||||
allow users to accumulate a [ERC-20 token](https://eips.ethereum.org/EIPS/eip-20) called Karma.
|
||||
With Karma, users can create transactions,
|
||||
have voting rights on the Status Network, and other benefits.
|
||||
The goal is to have a staking mechanism that is fair to all participates based on the stake amount and time staked.
|
||||
@@ -41,12 +41,12 @@ The protocol consists of the following components:
|
||||
- multipler points
|
||||
- reward mechanism
|
||||
|
||||
The staking system MUST be supported by an operator who will introduce reward amounts,
|
||||
reward periods, the REQUIRED tokens to use within the system and updates to the staking smart contract.
|
||||
It is the responsibility of the operator to keep accounts informed about requirements and
|
||||
intended changes to the staking system.
|
||||
The staking system MUST be supported by an operator who will introduce reward amounts,
|
||||
reward periods, the REQUIRED tokens to use within the system and
|
||||
updates to the staking smart contract.
|
||||
It is the responsibility of the operator to keep accounts informed about requirements
|
||||
and intended changes to the staking system.
|
||||
|
||||
emergencyExit, (MigrationFailed, Not Allowed to leave)/ update,update contract or global state/ prefered minium lock period/
|
||||
### Accounts
|
||||
|
||||
Accounts are users who contrbtribute a token, ERC-20 standard, to the staking protocol.
|
||||
@@ -61,16 +61,15 @@ Accounts MAY be the owner of one or more `stakeVault`s.
|
||||
|
||||
#### Account Staking Flow
|
||||
|
||||
To join a staking system,
|
||||
To join a staking system,
|
||||
accounts MUST use a `stakeVault` to transfer a token amount to the staking system.
|
||||
The ERC-20 token address used token address MUST match the token address used bybe identified by the operator as the of the staking system,
|
||||
see [Operator section](#operatorrole).
|
||||
The account MUST use the same token in the `stakeVault` registered by the operator in the staking system.
|
||||
Accounts MAY set a predefined duration to lock tokens in the staking system.
|
||||
Tokens will not be retrievable by accounts until the set duration expires.
|
||||
This is designed to improve the rewards accured by accounts deciding to lock funds.
|
||||
When tokens are successfully transfered to the `stakeVault`,
|
||||
the account responsible will start to accumulate multiper points.
|
||||
The rewards and multipler points are described in further detail in [Rewards section](#rewards).
|
||||
The rewards and multipler points are described in the [Rewards section](#rewards).
|
||||
If staked tokens are not locked, the account MAY withdraw the full amount of tokens at any time.
|
||||
|
||||
### Operator Role
|
||||
@@ -86,80 +85,212 @@ Accounts transaction SHOULD fail if the minimum lock duration is not set.
|
||||
After a minimum lock duration is set,
|
||||
the operator SHOULD NOT be able to update this amount untilt the set period is complete.
|
||||
|
||||
The `stakeManager` is upgradable only by the registered operator.
|
||||
The `stakeManager` SHOULD be upgradable only by the registered operator.
|
||||
Contract upgrades will occur when an operator wants to add and/or
|
||||
change the requirements of the system.
|
||||
When accounts are aware of changes, either by the operator informing them or
|
||||
reading the contract state, accounts SHOULD be able to leave the system if they do not agree with the changes.
|
||||
When accounts are aware of changes, either by the operator informing accounts or
|
||||
accounts reading the blockchain state,
|
||||
accounts MAY leave the system if they do not agree with the changes.
|
||||
Including when the operator enables `emergencyMode`.
|
||||
|
||||
- Operator decide amount of rewards should be awarded to stakers.
|
||||
- The owner MUST specify the amount of time for rewards to be distributed.
|
||||
|
||||
#### Emergency Mode
|
||||
|
||||
Emergency mode MAY be enabled
|
||||
In some cases,
|
||||
an operator may choose to stop the functionality of the staking system.
|
||||
When `emergencyMode` is enabled, the following SHOULD apply:
|
||||
|
||||
- new vaults from registering,
|
||||
- current registered vaults from adding more stake,
|
||||
- staking with lock period,
|
||||
- unstaking tokens,
|
||||
- update the global state
|
||||
- claim accured rewards.
|
||||
- new vaults can not register,
|
||||
- current registered vaults can not stake or stake with lock period additional tokens,
|
||||
- operators can not update the global state
|
||||
- accounts can not claim accured rewards.
|
||||
|
||||
### Rewards
|
||||
|
||||
- The user will be rewarded an ERC-20 token from the `stakeManager` contract, set by the owner of the `stakeManager`.
|
||||
The user will be awarded a non transferable token (NFT). ****
|
||||
Accounts participate in the staking protocol to earn rewards.
|
||||
The staking system implements a rewards distribution mechanism,
|
||||
that works in conjunction with the multiplier points system.
|
||||
|
||||
#### Multiplier Points
|
||||
|
||||
- In the staking streamer protocol, there are multipler points (MP),
|
||||
which are internal contract accounting ensuring users are rewarded based on the amount stake and the time of stake.
|
||||
- The amount are calculated once a user transfers stake to the staking streamer.
|
||||
- The multipler points are accumulated over time and not non transferable.
|
||||
- Calcuation is based on two factors, Inital MP and Accured MP.
|
||||
- Initial MP is the MP that are issued immediately once native tokens are transfered to the `stakingVault` contract.
|
||||
The user MAY opt to lock tokens for a specific time period.
|
||||
- The Initial MP MUST be based on the amount tokens in the `stakingValut` and/or the lock-up duration.
|
||||
- The Accrued MP are accumulated over time as a function of the stake amount, elapsed time, and annual percentage yield (APY).
|
||||
- Those points have a limited duration and will be used by the contract to determine how to reward the ERC20 token.
|
||||
- Contract SHOULD account for all mp accured by all accounts participating
|
||||
-
|
||||
When accounts have staked for a certain amount of time,
|
||||
multipler points, MP, are accured and calculated in the overall reward amount.
|
||||
This ensures that participants are rewarded fairly based on the stake amount
|
||||
and time staked.
|
||||
The MP are acculumated over time and MUST not be transferable.
|
||||
Calcuation is based on two factors, Initial MP and Accured MP.
|
||||
|
||||
##### Initial MP
|
||||
|
||||
Initial MP SHOULD be issued immediately when tokens are staked with or
|
||||
without a lock-up period.
|
||||
It is based on the stake amount and lock-up duration.
|
||||
The formula for Initial MP is derived as follows:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Initial} = \text{Stake} \times \left( 1 + \frac{\text{APY} \times T_ \text{lock}}{100 \times T_ \text{year}} \right)
|
||||
$$
|
||||
|
||||
Where:
|
||||
|
||||
- $Stake$ = The amount of tokens staked.
|
||||
- $APY$ = Annual Percentage Yield, set at 100%.
|
||||
- $T_{lock}$ = Lock-up duration in seconds.
|
||||
- $T_{year}$ = Total seconds in a year.
|
||||
|
||||
This formula calculates the Initial MP issued immediately when tokens are staked with a lock-up period.
|
||||
The longer the lock-up period, the more MP are issued.
|
||||
Accounts locking stake MAY earn bonus MP, which MAY be added to the initial MP amount.
|
||||
For example, Alice stakes 100 tokens with no lock-up time:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Initial} = 100 \times \left( 1 + \frac{100 \times 0}{100 \times 365} \right)
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Initial} = 100 \times \left( 1 + 0\right) = 100
|
||||
$$
|
||||
|
||||
Alice receives 100 MP.
|
||||
|
||||
Another example, Alice stakes 100 tokens with a 30 days lock-up period:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Initial} = 100 \times \left( 1 + \frac{100 \times 30}{100 \times 365} \right)
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Initial} = 100 \times \left( 1 + 0.082 \right) = 108.2
|
||||
$$
|
||||
|
||||
Alice receives 108.2 MP.
|
||||
By locking up the stake for 30 days,
|
||||
Alice receives an additional 8.2 MP.
|
||||
Alice cannot access the toekns until the lock-up period has passed.
|
||||
|
||||
##### Accured MP
|
||||
|
||||
The Accrued MP SHOULD be accumulated over time as a function of the stake amount,
|
||||
elapsed time, and annual percentage yield (APY).
|
||||
The Accrued MP formula is derived as follows:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Accrued} = \text{Stake} \times \frac{\text{APY} \times T_ \text{elapsed}}{100 \times T_ \text{year}}
|
||||
$$
|
||||
|
||||
Where:
|
||||
|
||||
- $T_{elapsed}$: Time elapsed since staking began, measured in seconds.
|
||||
|
||||
This formula adds MP as a function of time,
|
||||
rewarding accounts with locked stake.
|
||||
The Accrued MP are calculated based on the stake amount.
|
||||
Already accrued MP SHOULD not affect the calculation of new accrued MP.
|
||||
For example, Alice stakes 100 tokens for 15 days:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Accrued} = 100 \times \frac{100 \times 15}{100 \times 365} = 4.1
|
||||
$$
|
||||
|
||||
Alice receives 4.1 MP for the 15 days of staked tokens.
|
||||
This is exactly half of the MP that would have been received if tokens were
|
||||
locked for 30 days.
|
||||
Another example, Alice stakes 100 tokens for 30 days:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Accrued} = 100 \times \frac{100 \times 30}{100 \times 365} = 8.2
|
||||
$$
|
||||
|
||||
Alice receives 8.2 MP for the 30 days she has staked.
|
||||
|
||||
The `stakingManager` contract SHOULD account for all MP accured by all accounts in the system.
|
||||
Accounts are REQUIRED to make a on-chain transaction to claim MP.
|
||||
At any time, accounts MUST be able to retrieve the total MP accured by the staking system by reading the contract state.
|
||||
Total MP combines both accrued MP and pending MP.
|
||||
The accrued MP contains the initial MP and the MP accrued over time.
|
||||
Pending MP are MP that have yet to be "claimed" by the accounts:
|
||||
|
||||
$$
|
||||
\text{MP}_ \text{Total} = \text{MP}_ \text{Accrued} + \text{MP}_ \text{Pending}
|
||||
$$
|
||||
|
||||
Accounts SHOULD be limited to a total maximum amount of MP that can accrue.
|
||||
This will prevent accounts from accumulating large amounts of MP over time compared to other accounts.
|
||||
The maximum amount of MP an account can accrue is capped at:
|
||||
|
||||
$$
|
||||
\text{MP}_\text{Maximum} = \text{MP}_ \text{Initial} + \text{MP}_ \text{Potential}
|
||||
$$
|
||||
|
||||
- $\text{MP}_ \text{Initial}$: The initial MP an account receives when staking, \*_including the bonus MP_.
|
||||
- $\text{MP}_ \text{Potential}$: The initial MP amount multiplied by a $MAX\_MULTIPLIER$ factor.
|
||||
- $MAX\_MULTIPLIER$: A constant that determines the multiplier for the maximum amount of MP in the system.
|
||||
|
||||
For example, assuming a $MAX\_MULTIPLIER$ of `4`, an account that stakes 100 tokens would have a maximum of:
|
||||
|
||||
$$
|
||||
\text{MP}_\text{Maximum} = 100 + {100 \times 4} = 500
|
||||
$$
|
||||
|
||||
This means that the account can never have more than 500 MP,
|
||||
no matter how long they stake.
|
||||
|
||||
#### Reward Distribution
|
||||
|
||||
The system distributes rewards based on tree main factors:
|
||||
|
||||
- The amount of tokens staked
|
||||
- The account's Multiplier Points (MP)
|
||||
- The accounts reward index
|
||||
- the account's system weight
|
||||
- The account's reward index
|
||||
|
||||
Every account in the system has a "weight" associated with it. This weight is calculated as the sum of the staked tokens
|
||||
Every account in the system has a weight associated with it.
|
||||
This weight is calculated as the sum of the staked tokens
|
||||
and the MP:
|
||||
|
||||
$$
|
||||
\text{Account Weight} = \text{Staked Balance} + \text{MP Balance}
|
||||
$$
|
||||
|
||||
In addition, the system keeps track of the total weight of all accounts in the system:
|
||||
In addition, the system MUST track of the total weight of all accounts in the system:
|
||||
|
||||
$$
|
||||
\text{Total System Weight} = \sum_{i=1}^{n} \text{Account Weight}_i
|
||||
$$
|
||||
|
||||
account MP grow linearly with time, which means, account weights increase with
|
||||
time, which in turn means, the total weight of the system increases with time as well.
|
||||
|
||||
With the weights in place, the system can now calculate the rewards for each account. For an individual account, it's as
|
||||
simple as dividing the account's weight by the total system weight and multiplying it by the total reward amount:
|
||||
The account's MP grows linearly with time,
|
||||
which means, account weights increase with time, which in turn means,
|
||||
the total weight of the system increases with time as well.
|
||||
With the weights mechanism implemented,
|
||||
the system can now calculate the rewards for each account.
|
||||
For an individual account,
|
||||
dividing the account's weight by the total system weight and
|
||||
multiplying it by the total reward amount:
|
||||
|
||||
$$
|
||||
\text{Reward Amount} = \text{Account Weight} \times \frac{\text{Total Reward Amount}}{\text{Total System Weight}}
|
||||
$$
|
||||
|
||||
rewards are calculated in real-time, they don't actually need to be claimed by any account. whenever an
|
||||
account performs **state changing** actions, such as staking or unstaking funds, the rewards that have been accrued up
|
||||
to this point are updated in the account's storage.
|
||||
The rewards are calculated in real-time,
|
||||
they don't actually need to be claimed by any account.
|
||||
However, whenever an account performs blockchain state change,
|
||||
such as staking or unstaking funds,
|
||||
the rewards that have been accrued up to this point are updated in the account's storage.
|
||||
|
||||
- Operator decide amount of rewards should be awarded to stakers.
|
||||
- The owner MUST specify the amount of time for rewards to be distributed.
|
||||
- Rewards are accured by accounts over time and are only withdrawal at the end of each reward period
|
||||
- Based on the reward duration and amount of rewards, stakers will accure rewards in real time based on the rate of rewards which is calculated:
|
||||
Any real-time rewards are considered as pending rewards,
|
||||
until the account interacts with the system.
|
||||
Pending rewards are calculated as:
|
||||
|
||||
$$
|
||||
\text{Pending Rewards} = \text{Account Weight} \times \left( \text{Current Reward Index} \minus \text{Account's Last Reward Index} \right)
|
||||
$$
|
||||
|
||||
Rewards are accured by accounts over time and
|
||||
SHOULD be available for withdrawal at the end of each reward period.
|
||||
Based on the reward duration and amount of rewards,
|
||||
stakers will accure rewards in real time based on the rate of rewards which is calculated:
|
||||
|
||||
$$
|
||||
\text{Reward Rate} = \frac{\text{Total Reward Amount}}{\text{Reward Duration}}
|
||||
@@ -168,12 +299,20 @@ $$
|
||||
- When the `rewardEndTime` period has occured,
|
||||
the operator MUST set the new reward ratio.
|
||||
- account weights increase with
|
||||
time, which in turn means, the total weight of the system increases with time as well.
|
||||
time, which in turn means,
|
||||
the total weight of the system increases with time as well.
|
||||
|
||||
#### Reward Index
|
||||
#### Reward Indices
|
||||
|
||||
The reward system uses an accounting mechanism based on indices to track and
|
||||
distribute rewards accurately.
|
||||
This approach ensures fair distribution even as accounts enter and
|
||||
exit the system or change their stakes over time.
|
||||
|
||||
##### Global Reward Index
|
||||
|
||||
The global reward index represents the cumulative rewards per unit of weight since the system's inception.
|
||||
This index increases whenever new rewards are added to the system.
|
||||
It increases whenever new rewards are added to the system:
|
||||
|
||||
$
|
||||
\text{New Index} = \text{Current Index} + \frac{\text{New Rewards} \times \text{Scale Factor}}{\text{Total System Weight}}
|
||||
@@ -184,9 +323,12 @@ Where:
|
||||
- `Scale Factor` is 1e18 (used for precision)
|
||||
- `Total System Weight` is the sum of all staked tokens and MP in the system
|
||||
|
||||
##### Account Reward Indices
|
||||
|
||||
Each account maintains its own reward index,
|
||||
which represents the point at which they last claimed rewards.
|
||||
The difference between the global index and an account's index, multiplied by the account's
|
||||
which represents the point at which they last "claimed" rewards.
|
||||
The difference between the global index and
|
||||
an account's index is multiplied by the account's
|
||||
weight, determines their unclaimed rewards:
|
||||
|
||||
$$
|
||||
@@ -202,10 +344,39 @@ The system MUST update indices in the following situations:
|
||||
|
||||
This mechanism ensures that, historical rewards are preserved accurately and
|
||||
accounts receive their fair share based on their weight over time.
|
||||
Also, accounts MUST NOT receive the rewards that were accounted for in system at the time the account entered the system.
|
||||
Also, accounts MUST NOT receive the rewards that were accounted for in system
|
||||
at the time the account entered the system.
|
||||
|
||||
##### Index Adjustment Example
|
||||
|
||||
For example, the system has:
|
||||
|
||||
- Total Weight: 1000 units
|
||||
- Current Index: 0.5
|
||||
- New Rewards: 100 tokens
|
||||
|
||||
The index would increase by:
|
||||
|
||||
```text
|
||||
Increase = (100 × 1e18) / 1000 = 0.1e18
|
||||
New Index = 0.5e18 + 0.1e18 = 0.6e18
|
||||
```
|
||||
|
||||
If an account has:
|
||||
|
||||
- Weight: 200 units
|
||||
- Last Index: 0.5e18
|
||||
|
||||
Their unclaimed rewards would be:
|
||||
|
||||
```text
|
||||
Unclaimed = 200 × (0.6e18 - 0.5e18) / 1e18 = 20 tokens
|
||||
```
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
## References
|
||||
|
||||
- [ERC-20 token](https://eips.ethereum.org/EIPS/eip-20)
|
||||
|
||||
Reference in New Issue
Block a user