Compare commits

...

27 Commits

Author SHA1 Message Date
Jimmy Debe
eb27ea421a Update linting 2025-12-04 23:11:45 -05:00
Jimmy Debe
9933b7ca74 Merge branch 'main' into vac-Staking1 2025-09-08 20:02:48 -04:00
Jimmy Debe
88e326289a Update staking-streamer.md 2025-07-03 05:56:59 -04:00
Jimmy Debe
78323d890a Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-07-02 07:57:39 -04:00
Jimmy Debe
24fe617c5f Update staking-streamer.md 2025-07-02 07:57:15 -04:00
Jimmy Debe
502d598be3 Update staking-streamer.md 2025-07-01 06:30:29 -04:00
Jimmy Debe
f44fc6eb93 Update staking-streamer.md 2025-06-30 07:38:54 -04:00
Jimmy Debe
36439eb400 Update staking-streamer.md 2025-06-30 07:16:37 -04:00
Jimmy Debe
1258e483fe Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:06:59 -04:00
Jimmy Debe
882177064b Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:06:38 -04:00
Jimmy Debe
4708ef71f3 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:06:07 -04:00
Jimmy Debe
4b333dae16 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:05:24 -04:00
Jimmy Debe
b768883f95 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:05:15 -04:00
Jimmy Debe
624cc8370b Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:05:05 -04:00
Jimmy Debe
966b31d95e Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:04:56 -04:00
Jimmy Debe
78be8ca331 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:04:45 -04:00
Jimmy Debe
860ffe6b11 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:04:31 -04:00
Jimmy Debe
dac06391c5 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:02:03 -04:00
Jimmy Debe
11258ec0b6 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 06:58:58 -04:00
Jimmy Debe
f31f41fec9 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 06:58:41 -04:00
Jimmy Debe
518717f1c6 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 06:58:10 -04:00
Jimmy Debe
711c9e656b Update staking-streamer.md 2025-06-06 07:09:40 -04:00
Jimmy Debe
170ad5dd51 Update staking-streamer.md 2025-06-06 06:58:18 -04:00
Jimmy Debe
97970270b1 Update staking-streamer.md 2025-06-05 10:12:19 -04:00
Jimmy Debe
dc4d1e5d65 Update staking-streamer.md 2025-06-04 21:39:21 -04:00
Jimmy Debe
062d16a02a Update staking-streamer.md 2025-05-30 09:48:23 -04:00
Jimmy Debe
5304b472f4 Create staking-streamer.md 2025-05-20 11:04:36 -04:00

395
vac/raw/staking-streamer.md Normal file
View File

@@ -0,0 +1,395 @@
---
title: SNT-STAKING-STREAMER
name: Status Network Staking Streamer Protocol
status: raw
category: Standards Track
tags: status-network
editor:
contributors:
- Jimmy Debe <jimmy@status.im>
---
## Abstract
This specification describes the components used for the Status Network Staking Streamer protocol.
The protocol is a set of smart contract protocols currently used in [Status Network](https://status.network/).
## Background/Motivation
Traditional layer 2 blockchains generate revenue from gass fees required to make transactions on the network.
This can introduce a barrier of entry for users wanting to build and
interact with that blockchain.
The Status Network is a layer 2 roll up where applications and
users do not blockchain with gasless transactions.
Revenue is derived from a few sources including native yield commission.
Assests bridged to the Status Network are rehypothecated into yield-bearing equivalents and
users earn an [ERC-20 token](https://eips.ethereum.org/EIPS/eip-20) called Karma.
Karma is an goverance token in the Status Network that gives the user access to a certain throughput of free transactions,
votings and other network benefits.
The SNT token can also be staked with the staking streamer protocol to earn Karma.
The goal is to have a staking mechanism that is fair to all participants based on the stake amount and time staked.
Participants will have significant increases in voting power after committing their stake for a longer period,
even if their stake is not the largest among all participants.
## Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”,
“SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and
“OPTIONAL” in this document are to be interpreted as described in [2119](https://www.ietf.org/rfc/rfc2119.txt).
The staking streamer protocol is a set of smart contracts that implements the staking system.
The protocol consists of the following components:
- accounts
- staking operator
- multipler points
- reward mechanism
- staking vaults
The staking system MUST be supported by an `OPERATOR` who will introduce reward amounts,
reward periods, the token defined by its contract address REQUIRED for use in the system and
making updates to the staking smart contracts.
It is the responsibility of the `OPERATOR` to keep accounts informed about the requirements
and intended changes to the staking system.
### Accounts
Accounts are users who contribute a token, ERC-20 standard, to the staking protocol.
Accounts SHOULD interact with the protocol through a layer-1 blockchain smart contract.
To participate,
users MAY use an external owned account (EOA) and/or a smart account to interact with a `stakeVault` contract.
A `stakeVault` is a smart contract that records and
maintains the current amount of tokens transferred by accounts to the protocol.
Each `stakeVault` MUST have one registered as the owner.
Once registered, the user is considered as an account.
Accounts MAY be the owner of one or more `stakeVault`s.
#### Account Staking Flow
When joining a staking system,
accounts MUST use a `stakeVault` to transfer a token amount to the `stakingManager` contract,
which is described [below](#operator-role).
The account MUST use the same token, identitied by the token address,
as registered in the `stakeVault` by the `OPERATOR`.
Accounts MAY set a predefined duration to lock those tokens.
Tokens will not be retrievable by accounts until the set duration expires.
This is designed to improve the rewards accrued by accounts deciding to lock funds.
After tokens have successfully been transferred to the `stakeVault`,
the account responsible will start to accumulate multiper points.
The rewards and multipler points are described in the [Rewards section](#rewards) below.
If staked tokens are not locked, the account MAY withdraw the full amount of tokens at any time.
### Operator Role
The `OPERATOR` is the owner of the staking system by registering an address on the `stakeManager` contract.
The `OPERATOR` MUST deploy a `stakeManager` smart contract and
facilitate the requirements of the system.
Each account MUST use a `stakeVault` to interact with the `stakeManager`.
This includes transferring to and from the staking system.
The operator MAY set a preferred minimum lock duration for all tokens entering the system.
Accounts transaction MUST 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 until the set period is complete.
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 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`.
- The operator decides the amount of rewards that should be awarded to stakers.
- The operator MUST specify the amount of time for rewards to be distributed.
#### Emergency Mode
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 can not register,
- current registered vaults can not stake or stake additional tokens with a lock period,
- operators can not update the global state
- accounts can not claim accrued rewards.
### Rewards
Accounts participate in the staking protocol to earn rewards.
The staking system implements a rewards distribution mechanism,
that works in conjunction with a internal accouting system called multiplier points.
#### Multiplier Points
When accounts have staked for a certain amount of time,
multipler points (MP) are accrued.
The accrued MP is counted toward the account's weight for reward distribution, as described [below](#account-weight).
This ensures that participants are rewarded fairly based on the stake amount
and time staked.
The MP is accumulated over time and MUST not be transferable.
The calculation 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 day 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 tokens until the lock-up period has passed.
##### Accrued 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 is 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 accrued by all accounts in the system.
Accounts are REQUIRED to make an on-chain transaction to claim MP.
At any time, accounts MUST be able to retrieve the total MP accrued 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:
$$
\mathrm{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 a few main factors:
- The amount of tokens staked
- The account's Multiplier Points (MP)
- the account's system weight
- The account's reward index
#### Account Weight
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 MUST track the total weight of all accounts in the system:
$$
\text{Total System Weight} = \sum_{i=1}^{n} \text{Account Weight}_i
$$
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,
divide the account's weight by the total system weight and
multiply it by the total reward amount:
$$
\text{Reward Amount} = \text{Account Weight} \times \frac{\text{Total Reward Amount}}{\text{Total System Weight}}
$$
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.
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} - \text{Account's Last Reward Index} \right)
$$
Rewards are accrued 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 accrue rewards in real-time based on the rate of rewards which is calculated:
$$
\text{Reward Rate} = \frac{\text{Total Reward Amount}}{\text{Reward Duration}}
$$
- When the `rewardEndTime` period has occurred,
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.
#### 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.
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}}
$$
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 is multiplied by the account's
weight determines their unclaimed rewards:
$$
\text{Unclaimed Rewards} = \text{Account Weight} \times (\text{Global Index} - \text{Account Index})
$$
#### Reward Index Updates
The system MUST update indices in the following situations:
- When new rewards are added by the operator
- When accounts stake or unstake tokens
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 the 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
- [Status Network](https://status.network/)
- [ERC-20 token](https://eips.ethereum.org/EIPS/eip-20)