Operators
Nym Mixnet Rewards

Nym Operators Rewards

⚠️

Nym Network Rewarded set selection had been upgraded recently. Make sure to read the chapter Rewarded Set Selection below carefully to fully understand all requirements to be rewarded!

ℹ️

The data on this page were last time updated on

Wednesday, April 30th 2025, 12:26:39 UTC

.

We are working on the final architecture of Fair Mixnet tokenomics implementation and its detailed documentation. The current design is called Naive rewarding. It is an intermediate step, allowing operators to migrate to nym-node in Mixnet smart contract and for the first time recieve delegations and earn rewards for any nym-node functionality, in opposite to the past system, where only Mixnodes were able to recieve delegations and rewards.

Please read the roadmap section below to see the planned development.

Overview

This is a quick summary, to understand the full picture, please see detailed Rewards Logic & Calculation chapter below.

  • The operators of nym-node get rewarded from Mixmining pool (opens in a new tab), which emits

    5_278

    NYM per hour.
  • The rewarded set of nym-nodes selected for Nym network routing and mixing is currently 240 nodes in total and it's selected for each new epoch (60 min). The number can be adjusted - look here for the current value: validator.nymtech.net/api/v1/epoch/reward_params (opens in a new tab)
  • nym-nodes can run in mode entry-gateway, exit-gateway and mixnode, which are positioned into layers
  • NymVPN users can chose to route through Nym Network in two ways:
    • Mixnet: 5 layers routing and mixing - full privacy
    • Wireguard: 2 layers routing, skipping 3 mixing layers - fast mode
  • The current reward system is Naive rewarding - an intermediate step - where each layer get's rewarded the same
  • In the final model, nodes will get rewarded based on their layer position and the work they do (collected user tickets), where and the reward distribution per layer will be according to a decision made by the operators (opens in a new tab) as follows:
    • 5-hop: 16%-16%-16%-16%-36%
    • 2-hop: 33%-67%
  • Currently Gateways earn rewards only from taking a part in the rewarded set. The operators can sign up to a grant program as a substitution for 2-hop (Wireguad) routing.
  • To read more about the final design and future implementation, see Roadmap chapter for more details.

Rewards Logic & Calculation

Note that in the current intermediate model we use one active set to reward all nodes and they are asigned same work factor of 1 / 240, whether they work as Mixnode or Gateway of any kind, in both 2-hop and 5-hop mode (hence naive rewarding). In reality it means that all nodes are rewarded within 5-hop reward scheme only.

However NymVPN client can choose any nym-node with --wireguard-enabled true flag (which passed wireguard probing test (opens in a new tab)) to route as dVPN Gateway, both entry and exit.

Nym Network rewarded set distribution

Rewarded Set Selection

For a node to be rewarded, the node must be part of a Rewarded set (opens in a new tab) (which currently = active set) in the first place. The Rewarded set is freshly selected at the start of each epoch (every 60 min), and it consists of 240 Nym nodes that are probabilistically chosen from all the available nodes. These 240 nodes include 120 gateways and 120 mixnodes (40 for each of 3 mixnet layers).

Nodes selected into the rewarded set are chosen probabilisticaly are randomly selected, and their selection chances increase the larger nodes weight is. Weight value is always between 0 and 1 and it's calculated from these parameters:

  1. Performance: This value consists of:
  • Config score: highest (1) when the node is running the latest version of the software, has T&C's accepted and self described API endpoint available
  • Routing : highest (1) when the node is consistently online and correctly processes all the received traffic
  1. Stake saturation: including bond and delegated stake

Node weight is calculated with this formula:

📌

active_set_selection_weight = stake_saturation * ( node_performance ^ 20 )

For the rewarded set selection weight, good performance is much more essential than stake saturation, because it's lifted to 20th power in the selection algorhitm.

For a comparison we made an example with 5 nodes, where first number is node performance and second stake saturation (assuming all of them config_score) = 1 for simplification):


node_1 = 1.00 ^ 20 * 1.0 = 1
node_2 = 1.00 ^ 20 * 0.5 = 0.5
node_3 = 0.99 ^ 20 * 1.0 = 0.818
node_4 = 0.95 ^ 20 * 1.0 = 0.358
node_5 = 0.90 ^ 20 * 1.0 = 0.122

As you can see the performance is much more important during the Rewarded set selection. A node with 100% performance but only 50% stake saturation has much bigger chance to be chosen than a node with 95% performance and 100% stake saturation and incomparably bigger chance than 90% performing node with 100% stake saturation.

The nodes are chosen probababilistically in each epoch (60 min), so even nodes with lower performance will eventually be chosen, just much less often, as their chances decrease. Note that the score helps prioritize some nodes over others. If all available nodes have the same score, then the selection is done uniformly at random. By raising the node performance to 20, values of these parameters that are below one incur a heavy penalization for the node’s selection chances.


Explanation

The nodes are selected probabilistically, that means that even nodes with lower weight have a small chace to get slected. The probabilistic alorithm follows this logic:

  1. Summarize all nodes weight together
  2. Make a random selection roll for the first slot in the active set
  3. If a node is selected, take all its weight away from the draft queue
  4. Repeat points 1. - 3. for each slot in the active set

Example

We know that nodes weight is a float between 0 and 1. For simplification we will use integers in this example and much smaller set.

  • Total nodes: 8
  • Rewarded set: 4
  • Nodes weight:
    • node1 = 5
    • node2 = 5
    • node3 = 10
    • node4 = 10
    • node5 = 20
    • node6 = 40
    • node7 = 50
    • node8 = 60
  1. Summarize all nodes weight together:
weight_total = 5 + 5 + 10 + 10 + 20 + 40 + 50 + 60
weight_total = 200
  1. Roll a dice from 1 to 200:
  • Imagine the nodes are in line each representing the weight like index:
    • node1 = 1-5
    • node2 = 6-10
    • node3 = 11-20
    • node4 = 21-30
    • node5 = 31-50
    • node6 = 51-90
    • node7 = 91-150
    • node8 = 151-200
  • Say the function resulted in number 170
  1. Add node8 to the rewarded set and take it out of the lottery, summarize all the weights again:
weight_total = 5 + 5 + 10 + 10 + 20 + 40 + 50
weight_total = 140
  1. Roll a dice from 1 to 140:
  • Say the function resulted in number 4
  1. Add node1 to the rewarded set and take it out of the lottery, summarize all the weights again:
weight_total = 5 + 10 + 10 + 20 + 40 + 50
weight_total = 135
  1. Roll a dice from 1 to 135:
  • Say the function resulted in number 72
  1. Add node6 to the rewarded set and take it out of the lottery, summarize all the weights again:
weight_total = 5 + 10 + 10 + 20 + 50
weight_total = 95
  1. Roll a dice from 1 to 95:
  • Say the function resulted in number 21
  1. Add node4 to the rewarded set
  2. Rewarded set of 4 nodes is selected with these nodes to be chosen:
    1. node8
    2. node1
    3. node6
    4. node4
  3. After an epoch - 60 minutes - pull all bonded nodes and repeat the exact same process with their current weights

In reality we have mixing nodes selected into 3 layers. To increase security, there is an additional function in place where a node cannot be assigned to the same layer in two following epochs.

Below we break down performance calculation and show examples.

Node Performance Calculation

Performance is a value between 0 and 1. The final performance number is a result of multiplying config score and routing score.

📌

node_performance = config_score * routing_score

Performance value is an average of last 24h.

💡

All parameters regarding performance score can be browsed or pull live from:

https://validator.nymtech.net/api/v1/nym-nodes/annotation/<NODE_ID>

In case you don't know your nodes NODE_ID, it's easy to find as long as your node is bonded. Visit validator.nymtech.net/api/v1/nym-nodes/bonded (opens in a new tab) and search your node using identity_key or bonding Nyx account address (denoted as owner).

Config Score Calculation

Config score is in place to ensure that the node configuration is done properly so the node is eligible for taking part in Nym network. The API looks into these paramteres:

  1. If the node binary is nym-node (not legacy nym-mixnode or nym-gateway): 1 if True, 0 if False
  2. If Terms & Conditions are accepted: 1 if True, 0 if False
  3. If the nodes self described endpoint is available: 1 if True, 0 if False
  4. Version of nym-node binary: decreasing weight for outdated versions, as explained below

The config_score calculation formula:

📌

config_score = is_tc_accepted * is_nym-node_binary * self_described_api_available * ( 0.995 ^ ( ( X * versions_behind) ^ 1.65 ) )

First three points have binary values of either 0 or 1, with a following logic:

Run nym-node binaryT&C's acceptedSelf described availableValue
TrueTrueTrue1
TrueFalseFalse0
TrueTrueFalse0
FalseTrueTrue0
FalseFalseTrue0
TrueFalseTrue0
FalseFalseFalse0
FalseTrueFalse0

Only if ALL conditions above are True the node can have any chance to be selected, as otherwise the probability will always be 0.

ℹ️

Besides these values, the API also checks whether the node is bonded in Mixnet smart contract as a Nym Node or legacy node (Mixnode or Gateway). Only nodes bonded as Nym Node in Mixnet smart contract can be selected to the Rewrded set. Thus, if you haven't migrated your node yet, please follow these steps!

Versions Behind Calculation

From release 2024.14-crunch (nym-node v1.2.0), the config_score parameter takes into account also nodes version (denoted as versions_behind). The "current version" is the one marked as Latest in our repository. The parameter versions_behind indicates the number of versions between the Latest version and the version run by the node, and it is factored into the config score with this formula:

📌

0.995 ^ ( ( X * versions_behind ) ^ 1.65 )

where:
X = 1; for patches
X = 10; for minor versions
X = 100; for major versions

The exact parameters are live accessible on /v1/status/config-score-details (opens in a new tab).

Our versioning convention is: major_version . minor_version . patch

For example nym-node on version 1.2.0 is on 1st major version, 2nd minor and 0 patches.

Note that the X multiplier heavily lowers the config_score when nodes are outdated with respect to more significant updates. See the the table and graph below:

Version behindPatches (X = 1)Minor versions (X = 10)Major versions (X = 100)
0 (current version)1.01.01.0
10.9950.79940.0000
20.98440.49530.0000
30.96980.25360.0000
40.95180.11020.0000
50.93110.04130.0000

As you can see above, the algorithm is designed to give maximum selection score (1) to the latest version, while non-upgraded nodes receive a lower score. The score decreases faster when the node has failed to make a major version upgrade, and slower when the node is behind only with minor updates. This scoring de-prioritizes the selection of outdated nodes, even if their saturation and performance are high. Nodes are selected probabilistically in each epoch (60 min), according to their scores, to be part of the Rewarded set. This scoring mechanism gives priority to the operators running up-to-date nodes, ensuring that the network is as updated as possible.

Routing Score Calculation

Routing score is measured by Nym Network Monitor which sends thousands of packages through different routes every 15 minutes and measures how many were dropped on the way. Test result represents percentage of packets succesfully returned which are then converted into floats bettween 0 and 1.

Stake Saturation

If you want to understand more about NYM supply, read tokenomics page first.

Stake saturation is a node reputation done in a form of self bond or stakers delegation. Optimal stake saturation level is calculated as:

📌

stake_saturation_level = staking_target / rewarded_set_size

rewarded_set_size = active_set_size + standby_set_size

With current circulating supply of

809_964_694

NYM, staking target of

404_982_347

NYM, divided by the sum of nodes in the rewarded set (opens in a new tab), the stake saturation level is

1_031_281

NYM per node.

Node stake saturation is a value between 0 and 1 following this logic.

Node stake saturation formula:

📌

node_stake_saturation = node_total_stake / stake_saturation_level

There is a caveat that the maximum value can be 1. In practice it means that:

  1. If node_total_stake < stake_saturation_level then node_stake_saturation will be a float between 0 and 1

  2. If node_total_stake = stake_saturation_level then node_stake_saturation will be 1

  3. If node_total_stake > stake_saturation_level then node_stake_saturation will be 1 due the capping function working as anti-whale prevention.

  • This results in smaller % APY per every staked (self bond or delegation) NYM token on that node, as the maximum rewards is capped and in this case distributed in between more staked tokens.
  • For example if node_total_stake = 2 * stake_saturation_level then the reward per staked token will be 50% in comparison to a case where node_total_stake = stake_saturation_level, in other words with 100% over-saturation, APY is half the maximum.

Rewards Calculation

Once the rewarded set (currently 120 Mixnodes and 120 Gateways) is selected, the nodes can start to route and mix packets in the Nym Network. Each hour a total of

5_278

NYM is distributed between the layers from Mixmining pool. Currently in our Naive rewarding intermediate design, all layers get a same portion, therefore each node is naively assigned same working factor and therefore earns 1/240 of the rewards per epoch.

If a node is active in the rewarded set, it will receive rewards in the end of the epoch, the size is dependant on stake saturation and performance. This is how rewards get distributed between nodes in the rewarded set.

Rewards distribution formula:

📌

node_epoch_rewards = reward_budget * 1 / active_set_size * (stake_saturation * performance)

In the current state:

node_epoch_rewards =

5_278

* 1 / 240 * (stake_saturation * performance)

Performance and stake saturation play an equally decisive role in the size of rewards earned after the epoch. The closer a node is to maximum value (1) of each of these parameters, the more rewards it will get.

Given that there is a highly unlikely chance of all nodes having maximum stake saturation and performance, in majority of cases there will be some part of the reward budget left undistributed. This "change" is then kept in the Mixmining reserve.

💡

All parameters regarding performance score can be browsed or pull live from:

https://validator.nymtech.net/api/v1/nym-nodes/annotation/<NODE_ID>

In case you don't know your nodes NODE_ID, it's easy to find as long as your node is bonded. Visit validator.nymtech.net/api/v1/nym-nodes/bonded (opens in a new tab) and search your node using identity_key or bonding Nyx account address (denoted as owner).

Rewards are send to the Nyx account used for bonding the node and each delegator automatically by the end of an epoch in which the node was part of the rewarded set, following the logic described below.

Rewards Distribution

Once the rewards are asigned per each node they need to be distributed between the operator of the node and delegators (people who staked their NYM on that node). The distribution is pretty straightforward and it happens in the following order:

  1. Operators Cost (O.C.): How many NYM the operator requests to cover their costs per month, divided by 720 (this value is set by the operator in the bonding wallet node settings)
  2. Profit Margin (P.M.): What's the extra % cut the operator requests (this value is set by the operator in the bonding wallet node settings)
  3. Bond & Stake proportionaly: The remaining rewards are distributed proportionaly to the weight of every stake (including self bond, self delegation and each delegation).
Nyx Epoch vs Interval
📌

1 epoch = 60 min
1 interval = 720 epochs

The logic is that interval is 30 days:
24 epochs * 30 days = 720

The Operators Cost (O.C). is a value denominated in NYM, that a node operator requires to get paid before the rewards get distributed. The cost is estimated per one month. However, it's paid only in epochs when the node is active. To calculate how O.C. works, we use a value called interval which represents 30 days (approximate month), or more precisely 720 epochs. To get covered a full O.C, the node would have to be active for the entire month.

O.C. real revenue formula

Therefore every epoch a node is active, the operator gets:

📌

epoch_operator_cost_revenue = operators_cost / epochs_per_interval

that is:

epoch_operator_cost_revenue = operators_cost / 720

To calculate O.C. per month, multiply it by number of active epochs:

📌

monthly_operator_cost_revenue = ( operator_cost / 720 ) * active_epochs

Roadmap

We are working on the final architecture of Fair Mixnet tokenomics implementation, following the decision made by the node operators (opens in a new tab). The current design is called Naive rewarding. This is an intermediate step, expecting operators to migrate to nym-node in Mixnet smart contract and be able to recieve delegations and earn rewards for any nym-node functionality, in opposite to the past system, where only Mixnodes were able to recieve delegations and rewards.

On November 5th 2024, we presented a release roadmap in live Operators Townhall (opens in a new tab) where we explained in detail the steps of Nym node and tokenomics development and the effect it will have on node operators and put it into a rough timeline.

Naive Rewarding

Naive rewarding is the current tokenomics design. The table below lists features and logic of this design.

Fair Mixnet

Fair Mixnet is the final architecture model that we work towards. The table below lists features and logic of the design once implemented.