mirror of
https://github.com/vacp2p/rfc-index.git
synced 2026-01-10 08:08:17 -05:00
Compare commits
31 Commits
nescience/
...
vac-Stakin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb27ea421a | ||
|
|
9933b7ca74 | ||
|
|
3505da6bd6 | ||
|
|
3b968ccce3 | ||
|
|
536d31b5b7 | ||
|
|
4361e2958f | ||
|
|
88e326289a | ||
|
|
78323d890a | ||
|
|
24fe617c5f | ||
|
|
502d598be3 | ||
|
|
f44fc6eb93 | ||
|
|
36439eb400 | ||
|
|
1258e483fe | ||
|
|
882177064b | ||
|
|
4708ef71f3 | ||
|
|
4b333dae16 | ||
|
|
b768883f95 | ||
|
|
624cc8370b | ||
|
|
966b31d95e | ||
|
|
78be8ca331 | ||
|
|
860ffe6b11 | ||
|
|
dac06391c5 | ||
|
|
11258ec0b6 | ||
|
|
f31f41fec9 | ||
|
|
518717f1c6 | ||
|
|
711c9e656b | ||
|
|
170ad5dd51 | ||
|
|
97970270b1 | ||
|
|
dc4d1e5d65 | ||
|
|
062d16a02a | ||
|
|
5304b472f4 |
241
vac/raw/eth-mls-offchain.md
Normal file
241
vac/raw/eth-mls-offchain.md
Normal file
@@ -0,0 +1,241 @@
|
||||
---
|
||||
title: ETH-MLS-OFFCHAIN
|
||||
name: Secure channel setup using decentralized MLS and Ethereum accounts
|
||||
status: raw
|
||||
category: Standards Track
|
||||
tags:
|
||||
editor: Ugur Sen [ugur@status.im](mailto:ugur@status.im)
|
||||
contributors: seemenkina [ekaterina@status.im](mailto:ekaterina@status.im)
|
||||
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
The following document specifies Ethereum authenticated scalable
|
||||
and decentralized secure group messaging application by
|
||||
integrating Message Layer Security (MLS) backend.
|
||||
Decentralization refers each user is a node in P2P network and
|
||||
each user has voice for any changes in group.
|
||||
This is achieved by integrating a consensus mechanism.
|
||||
Lastly, this RFC can also be referred to as de-MLS,
|
||||
decentralized MLS, to emphasize its deviation
|
||||
from the centralized trust assumptions of traditional MLS deployments.
|
||||
|
||||
## Motivation
|
||||
|
||||
Group messaging is a fundamental part of digital communication,
|
||||
yet most existing systems depend on centralized servers,
|
||||
which introduce risks around privacy, censorship, and unilateral control.
|
||||
In restrictive settings, servers can be blocked or surveilled;
|
||||
in more open environments, users still face opaque moderation policies,
|
||||
data collection, and exclusion from decision-making processes.
|
||||
To address this, we propose a decentralized, scalable peer-to-peer
|
||||
group messaging system where each participant runs a node, contributes
|
||||
to message propagation, and takes part in governance autonomously.
|
||||
Group membership changes are decided collectively through a lightweight
|
||||
partially synchronous, fault-tolerant consensus protocol without a centralized identity.
|
||||
This design enables truly democratic group communication and is well-suited
|
||||
for use cases like activist collectives, research collaborations, DAOs, support groups,
|
||||
and decentralized social platforms.
|
||||
|
||||
## Format 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).
|
||||
|
||||
### Assumptions
|
||||
|
||||
- The nodes in the P2P network can discover other nodes or will connect to other nodes when subscribing to same topic in a gossipsub.
|
||||
- We MAY have non-reliable (silent) nodes.
|
||||
- We MUST have a consensus that is lightweight, scalable and finalized in a specific time.
|
||||
|
||||
## Roles
|
||||
|
||||
The three roles used in de-MLS is as follows:
|
||||
|
||||
- `node`: Nodes are members of network without being in any secure group messaging.
|
||||
- `member`: Members are special nodes in the secure group messaging who
|
||||
obtains current group key of secure group messaging.
|
||||
- `steward`: Stewards are special and transparent members in secure group
|
||||
messaging who organizes the changes upon the voted-proposals.
|
||||
|
||||
## MLS Background
|
||||
|
||||
The de-MLS consists of MLS backend, so the MLS services and other MLS components
|
||||
are taken from the original [MLS specification](https://datatracker.ietf.org/doc/rfc9420/), with or without modifications.
|
||||
|
||||
### MLS Services
|
||||
|
||||
MLS is operated in two services authentication service (AS) and delivery service (DS).
|
||||
Authentication service enables group members to authenticate the credentials presented by other group members.
|
||||
The delivery service routes MLS messages among the nodes or
|
||||
members in the protocol in the correct order and
|
||||
manage the `keyPackage` of the users where the `keyPackage` is the objects
|
||||
that provide some public information about a user.
|
||||
|
||||
### MLS Objects
|
||||
|
||||
Following section presents the MLS objects and components that used in this RFC:
|
||||
|
||||
`Epoch`: Fixed time intervals that changes the state that is defined by members,
|
||||
section 3.4 in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
|
||||
|
||||
`MLS proposal message:` Members MUST receive the proposal message prior to the
|
||||
corresponding commit message that initiates a new epoch with key changes,
|
||||
in order to ensure the intended security properties, section 12.1 in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
|
||||
Here, the add and remove proposals are used.
|
||||
|
||||
`Application message`: This message type used in arbitrary encrypted communication between group members.
|
||||
This is restricted by [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) as if there is pending proposal,
|
||||
the application message should be cut.
|
||||
Note that: Since the MLS is based on servers, this delay between proposal and commit messages are very small.
|
||||
`Commit message:` After members receive the proposals regarding group changes,
|
||||
the committer, who may be any member of the group, as specified in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/),
|
||||
generates the necessary key material for the next epoch, including the appropriate welcome messages
|
||||
for new joiners and new entropy for removed members. In this RFC, the committers only MUST be stewards.
|
||||
|
||||
### de-MLS Objects
|
||||
|
||||
`Voting proposal` Similar to MLS proposals, but processed only if approved through a voting process.
|
||||
They function as application messages in the MLS group,
|
||||
allowing the steward to collect them without halting the protocol.
|
||||
|
||||
## Flow
|
||||
|
||||
General flow is as follows:
|
||||
|
||||
- A steward initializes a group just once, and then sends out Group Announcements (GA) periodically.
|
||||
|
||||
- Meanwhile, each`node`creates and sends their`credential` includes `keyPackage`.
|
||||
- Each `member`creates `voting proposals` sends them to from MLS group during epoch E.
|
||||
- Meanwhile, the `steward` collects finalized `voting proposals` from MLS group and converts them into
|
||||
`MLS proposals` then sends them with correspondng `commit messages`
|
||||
- Evantually, with the commit messages, all members starts the next epoch E+1.
|
||||
|
||||
## Creating Voting Proposal
|
||||
|
||||
A `member` MAY initializes the voting with the proposal payload
|
||||
which is implemented using [protocol buffers v3](https://protobuf.dev/) as follows:
|
||||
|
||||
```protobuf
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
message Proposal {
|
||||
string name = 10; // Proposal name
|
||||
string payload = 11; // Describes the what is voting fore
|
||||
int32 proposal_id = 12; // Unique identifier of the proposal
|
||||
bytes proposal_owner = 13; // Public key of the creator
|
||||
repeated Vote votes = 14; // Vote list in the proposal
|
||||
int32 expected_voters_count = 15; // Maximum number of distinct voters
|
||||
int32 round = 16; // Number of Votes
|
||||
int64 timestamp = 17; // Creation time of proposal
|
||||
int64 expiration_time = 18; // Time interval that the proposal is active
|
||||
bool liveness_criteria_yes = 19; // Shows how managing the silent peers vote
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
message Vote {
|
||||
int32 vote_id = 20; // Unique identifier of the vote
|
||||
bytes vote_owner = 21; // Voter's public key
|
||||
int64 timestamp = 22; // Time when the vote was cast
|
||||
bool vote = 23; // Vote bool value (true/false)
|
||||
bytes parent_hash = 24; // Hash of previous owner's Vote
|
||||
bytes received_hash = 25; // Hash of previous received Vote
|
||||
bytes vote_hash = 26; // Hash of all previously defined fields in Vote
|
||||
bytes signature = 27; // Signature of vote_hash
|
||||
}
|
||||
```
|
||||
|
||||
The voting proposal MAY include adding a `node` or removing a `member`.
|
||||
After the `member` creates the voting proposal,
|
||||
it is emitted to the network via the MLS `Application message` with a lightweight,
|
||||
epoch based voting such as [hashgraphlike consensus.](https://github.com/vacp2p/rfc-index/blob/consensus-hashgraph-like/vac/raw/consensus-hashgraphlike.md)
|
||||
This consensus result MUST be finalized within the epoch as YES or NO.
|
||||
|
||||
If the voting result is YES, this points out the voting proposal will be converted into
|
||||
the MLS proposal by the `steward` and following commit message that starts the new epoch.
|
||||
|
||||
## Creating welcome message
|
||||
|
||||
When a MLS `MLS proposal message` is created by the `steward`,
|
||||
a `commit message` SHOULD follow,
|
||||
as in section 12.04 [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) to the members.
|
||||
In order for the new `member` joining the group to synchronize with the current members
|
||||
who received the `commit message`,
|
||||
the `steward` sends a welcome message to the node as the new `member`,
|
||||
as in section 12.4.3.1. [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
|
||||
|
||||
## Single steward
|
||||
|
||||
To naive way to create a decentralized secure group messaging is having a single transparent `steward`
|
||||
who only applies the changes regarding the result of the voting.
|
||||
|
||||
This is mostly similar with the general flow and specified in voting proposal and welcome message creation sections.
|
||||
|
||||
1. Each time a single `steward` initializes a group with group parameters with parameters
|
||||
as in section 8.1. Group Context in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
|
||||
2. `steward` creates a group anouncement (GA) according to the previous step and
|
||||
broadcast it to the all network periodically. GA message is visible in network to all `nodes`.
|
||||
3. The each `node` who wants to be a member needs to obtain this anouncement and create `credential`
|
||||
includes `keyPackage` that is specified in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) section 10.
|
||||
4. The `steward` aggregates all `KeyPackages` utilizes them to provision group additions for new members,
|
||||
based on the outcome of the voting process.
|
||||
5. Any `member` start to create `voting proposals` for adding or removing users,
|
||||
and present them to the voting in the MLS group as an application message.
|
||||
|
||||
However, unlimited use of `voting proposals` within the group may be misused by
|
||||
malicious or overly active members.
|
||||
Therefore, an application-level constraint can be introduced to limit the number
|
||||
or frequency of proposals initiated by each member to prevent spam or abuse.
|
||||
6. Meanwhile, the `steward` collects finalized `voting proposals` with in epoch `E`,
|
||||
that have received affirmative votes from members via application messages.
|
||||
Otherwise, the `steward` discards proposals that did not receive a majority of "YES" votes.
|
||||
Since voting proposals are transmitted as application messages, omitting them does not affect
|
||||
the protocol’s correctness or consistency.
|
||||
7. The `steward` converts all approved `voting proposals` into
|
||||
corresponding `MLS proposals` and `commit message`, and
|
||||
transmits both in a single operation as in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) section 12.4,
|
||||
including welcome messages for the new members. Therefore, the `commit message` ends the previous epoch and create new ones.
|
||||
|
||||
## Multi stewards
|
||||
|
||||
Decentralization has already been achieved in the previous section.
|
||||
However, to improve availability and ensure censorship resistance,
|
||||
the single-steward protocol is extended to a multi-steward architecture.
|
||||
In this design, each epoch is coordinated by a designated steward,
|
||||
operating under the same protocol as the single-steward model.
|
||||
Thus, the multi-steward approach primarily defines how steward roles
|
||||
rotate across epochs while preserving the underlying structure and logic of the original protocol.
|
||||
Two variants of the multi-steward design are introduced to address different system requirements.
|
||||
|
||||
### Multi steward with single consensus
|
||||
|
||||
In this model, all group modifications, such as adding or removing members,
|
||||
must be approved through consensus by all participants,
|
||||
including the steward assigned for epoch `E`.
|
||||
A configuration with multiple stewards operating under a shared consensus protocol offers
|
||||
increased decentralization and stronger protection against censorship.
|
||||
However, this benefit comes with reduced operational efficiency.
|
||||
The model is therefore best suited for small groups that value
|
||||
decentralization and censorship resistance more than performance.
|
||||
|
||||
### Multi steward with two consensuses
|
||||
|
||||
The two-consensus model offers improved efficiency with a trade-off in decentralization.
|
||||
In this design, group changes require consensus only among the stewards, rather than all members.
|
||||
Regular members participate by periodically selecting the stewards but do not take part in each decision.
|
||||
This structure enables faster coordination since consensus is achieved within a smaller group of stewards.
|
||||
It is particularly suitable for large user groups, where involving every member in each decision would be impractical.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
|
||||
|
||||
### References
|
||||
|
||||
- [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/)
|
||||
- [Hashgraphlike Consensus](https://github.com/vacp2p/rfc-index/blob/consensus-hashgraph-like/vac/raw/consensus-hashgraphlike.md)
|
||||
- [vacp2p/de-mls](https://github.com/vacp2p/de-mls)
|
||||
@@ -55,6 +55,9 @@ but improves scalability by reducing direct interactions between participants.
|
||||
Each message has a globally unique, immutable ID (or hash).
|
||||
Messages can be requested from the high-availability caches or
|
||||
other participants using the corresponding message ID.
|
||||
* **Participant ID:**
|
||||
Each participant has a globally unique, immutable ID
|
||||
visible to other participants in the communication.
|
||||
|
||||
## Wire protocol
|
||||
|
||||
@@ -75,7 +78,7 @@ message HistoryEntry {
|
||||
}
|
||||
|
||||
message Message {
|
||||
// 1 Reserved for sender/participant id
|
||||
string sender_id = 1; // Participant ID of the message sender
|
||||
string message_id = 2; // Unique identifier of the message
|
||||
string channel_id = 3; // Identifier of the channel to which the message belongs
|
||||
optional int32 lamport_timestamp = 10; // Logical timestamp for causal ordering in channel
|
||||
@@ -85,7 +88,8 @@ message Message {
|
||||
}
|
||||
```
|
||||
|
||||
Each message MUST include its globally unique identifier in the `message_id` field,
|
||||
The sending participant MUST include its own globally unique identifier in the `sender_id` field.
|
||||
In addition, it MUST include a globally unique identifier for the message in the `message_id` field,
|
||||
likely based on a message hash.
|
||||
The `channel_id` field MUST be set to the identifier of the channel of group communication
|
||||
that is being synchronized.
|
||||
@@ -98,6 +102,10 @@ These fields MAY be left unset in the case of [ephemeral messages](#ephemeral-me
|
||||
The message `content` MAY be left empty for [periodic sync messages](#periodic-sync-message),
|
||||
otherwise it MUST contain the application-level content
|
||||
|
||||
> **_Note:_** Close readers may notice that, outside of filtering messages originating from the sender itself,
|
||||
the `sender_id` field is not used for much.
|
||||
Its importance is expected to increase once a p2p retrieval mechanism is added to SDS, as is planned for the protocol.
|
||||
|
||||
### Participant state
|
||||
|
||||
Each participant MUST maintain:
|
||||
@@ -157,6 +165,8 @@ of unacknowledged outgoing messages.
|
||||
|
||||
Upon receiving a message,
|
||||
|
||||
* the participant SHOULD ignore the message if it has a `sender_id` matching its own.
|
||||
* the participant MAY deduplicate the message by comparing its `message_id` to previously received message IDs.
|
||||
* the participant MUST [review the ACK status](#review-ack-status) of messages
|
||||
in its unacknowledged outgoing buffer
|
||||
using the received message's causal history and bloom filter.
|
||||
|
||||
395
vac/raw/staking-streamer.md
Normal file
395
vac/raw/staking-streamer.md
Normal 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)
|
||||
@@ -3,9 +3,10 @@ slug: 66
|
||||
title: 66/WAKU2-METADATA
|
||||
name: Waku Metadata Protocol
|
||||
status: draft
|
||||
editor: Alvaro Revuelta <alrevuelta@status.im>
|
||||
editor: Franck Royer <franck@status.im>
|
||||
contributors:
|
||||
- Filip Dimitrijevic <filip@status.im>
|
||||
- Filip Dimitrijevic <filip@status.im>
|
||||
- Alvaro Revuelta <alrevuelta@status.im>
|
||||
---
|
||||
|
||||
## Abstract
|
||||
@@ -15,16 +16,19 @@ that can be associated with a [10/WAKU2](/waku/standards/core/10/waku2.md) node.
|
||||
|
||||
## Metadata Protocol
|
||||
|
||||
Waku specifies a req/resp protocol that provides information about the node's medatadata.
|
||||
Such metadata is meant to be used by the node to decide if a peer is worth connecting
|
||||
or not.
|
||||
The keywords “MUST”, // List style “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”,
|
||||
“NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
|
||||
|
||||
Waku specifies a req/resp protocol that provides information about the node's capabilities.
|
||||
Such metadata MAY be used by other peers for subsequent actions such as light protocol requests or disconnection.
|
||||
|
||||
The node that makes the request,
|
||||
includes its metadata so that the receiver is aware of it,
|
||||
without requiring an extra interaction.
|
||||
without requiring another round trip.
|
||||
The parameters are the following:
|
||||
|
||||
* `clusterId`: Unique identifier of the cluster that the node is running in.
|
||||
* `shards`: Shard indexes that the node is subscribed to.
|
||||
* `shards`: Shard indexes that the node is subscribed to via [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md).
|
||||
|
||||
***Protocol Identifier***
|
||||
|
||||
@@ -48,6 +52,51 @@ message WakuMetadataResponse {
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Suggestions
|
||||
|
||||
### Triggering Metadata Request
|
||||
|
||||
A node SHOULD proceed with metadata request upon first connection to a remote node.
|
||||
A node SHOULD use the remote node's libp2p peer id as identifier for this heuristic.
|
||||
|
||||
A node MAY proceed with metadata request upon reconnection to a remote peer.
|
||||
|
||||
A node SHOULD store the remote peer's metadata information for future reference.
|
||||
A node MAY implement a TTL regarding a remote peer's metadata, and refresh it upon expiry by initiating another metadata request.
|
||||
It is RECOMMENDED to set the TTL to 6 hours.
|
||||
|
||||
A node MAY trigger a metadata request after receiving an error response from a remote note
|
||||
stating they do not support a specific cluster or shard.
|
||||
For example, when using a request-response service such as [`19/WAKU2-LIGHTPUSH`](/waku/standards/core/19/lightpush.md).
|
||||
|
||||
### Providing Cluster Id
|
||||
|
||||
A node MUST include their cluster id into their metadata payload.
|
||||
It is RECOMMENDED for a node to operate on a single cluster id.
|
||||
|
||||
### Providing Shard Information
|
||||
|
||||
* Nodes that mount [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md) MAY include the shards they are subscribed to in their metadata payload.
|
||||
* Shard-relevant services are message related services,
|
||||
such as [`13/WAKU2-STORE`](/waku/standards/core/13/store.md), [12/WAKU2-FILTER](/waku/standards/core/12/filter.md)
|
||||
and [`19/WAKU2-LIGHTPUSH`](/waku/standards/core/19/lightpush.md)
|
||||
but not [`34/WAKU2-PEER-EXCHANGE`](/waku/standards/core/34/peer-exchange.md)
|
||||
* Nodes that mount [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md) and a shard-relevant service SHOULD include the shards they are subscribed to in their metadata payload.
|
||||
* Nodes that do not mount [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md) SHOULD NOT include any shard information
|
||||
|
||||
### Using Cluster Id
|
||||
|
||||
When reading the cluster id of a remote peer, the local node MAY disconnect if their cluster id is different from the remote peer.
|
||||
|
||||
### Using Shard Information
|
||||
|
||||
It is NOT RECOMMENDED to disconnect from a peer based on the fact that their shard information is different from the local node.
|
||||
|
||||
Ahead of doing a shard-relevant request,
|
||||
a node MAY use the previously received metadata shard information to select a peer that support the targeted shard.
|
||||
|
||||
For non-shard-relevant requests, a node SHOULD NOT discriminate a peer based on medata shard information.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via
|
||||
|
||||
Reference in New Issue
Block a user