Skip to main content

Reward Mechanism



The Reward Mechanism is currently at version 2.0. This page serves as both an informational resource about its current status and a how we got here.

The Reward Mechanism has undergone a progressive evolution across its versions, each iteration introducing refinements to bolster fairness and transparency in the rewarding process for weather station owners contributing data to the network.

  • In its inaugural version (v1.0), the mechanism primarily gauged a station's eligibility based on its connection status to the network and the requirement for active wallet ownership, resulting in a somewhat simplistic reward calculation. In this version, the users received in a daily basis the WXM testnet rewards at their wallets.
  • The subsequent release, v1.5, marked a significant advancement by expanding the criteria for reward eligibility. This version incorporated additional factors such as the Quality-of-Data (QoD), Proof-of-Location (PoL), Hardware-Classes (HC) and the Cell-Capacity (CP). These additions contributed to a more sophisticated and equitable system, ensuring that rewards were allocated based on data quality, accurate location proof, and user engagement.
  • The third iteration, v2.0, will introduce substantial enhancements, including the incorporation of Business Boost rewards and the implementation of a Merkle Tree structure for transparent reward distribution. The utilization of Merkle Tree will lead users in withdrawing, whenever they choose to do, their rewards from the smart contract. Business Boost rewards added an additional layer of fairness by incorporating predefined criteria, while the Merkle Tree structure facilitated a verifiable and transparent mechanism for users to validate the distribution of their rewards. This evolutionary trajectory underscores a commitment to refining the Reward Mechanism, making it more inclusive, nuanced, and transparent to build trust among weather station owners participating in the network.

Reward mechanism v2.0

The Reward Mechanism v2.0 is the latest iteration of the rewarding mechanism. It is a significant advancement over the previous version, v1.5, and it introduces the following enhancements:

High-level flow

Every day, the reward algorithm assesses the performance of all weather stations, calculates additional rewards originating from Business Boost use cases, bundles them together with the users' wallet addresses, and creates a Merkle Tree, the root hash of which is submitted to the RewardPool.

Users have the option to withdraw their rewards either by accessing the Merkle proof on the WeatherXM Platform or by retrieving the Merkle proof from IPFS and programmatically initiating the procedure. At any given time users have the flexibility to withdraw any amount they desire, provided it does not exceed the total allocated amount.

Daily Rewards Calculation Process

The Reward Mechanism calculates the amount of tokens that will be allocated to users by completing the following phases:

  1. Base Rewards calculation
  2. Business Boost Rewards calculation
  3. Cumulative Rewards calculation
  4. Merkle Tree creation

Let's take a deep dive into each one of these.

1. Base Rewards calculation

Base rewards calculation follows the Actual Rewards Calculation already introduced in Reward Mechanism v1.5.

2. Business Boost rewards calculation

The business boost use cases reward specific devices with a predefined amount of tokens from the Business Development Pool for a period of time. In this phase, all business boost rewards are calculated for each active business boost use case and they are assigned to the eligible devices.

3. Cumulative Rewards Calculation

In the third phase of the rewarding mechanism, the cumulative rewards per user are calculated. The cumulative rewards are the sum of all base and business boost rewards that each user's weather station owns.

cumulative_rewards_per_customer = sum(base_reward[i] + business_boost_reward[i]), i = 1..n where n = total number of devices per user

4. Merkle Tree Creation

In the final phase, the cumulative rewards coupled with the users' wallet addresses are utilised to create the Merkle tree. The root hash of the Merkle tree is submitted daily in the smart contract to enable $WXM rewards withdrawal by the users.


To sum up all of the above in pseudocode:

// base reward
rewardable = {
'Helium': {
count: 0,
weight: 0.9,
devices: []
'M5': {
count: 0,
weight: 1.1,
devices: []

for cell in cells:
cell_devices = []
for device in cell:
if isEmpty(device.owner.wallet):
device.reward_score = 0
device.reward_reason = 'NO_WALLET'
device.base_reward = 0
if qod_score < qod_threshold:
device.reward_score = 0
device.reward_reason = 'QOD_THRESHOLD'
device.base_reward = 0
if pol_score < pol_threshold:
device.reward_score = 0
device.reward_reason = 'POL_THRESHOLD'
device.base_reward = 0
device.reward_score = reward_algorithm(device.pol_score, device.qod_score)
rewardable[device.hardware_class].count += 1

cell_devices.sort( (x, y):
if x.reward_score == y.reward_score:
return x.claimedAt - y.claimedAt
return y.reward_score - x.reward_score

for (device, i) in cell_devices:
device.bb_reward = 0
if i >= cell.capacity:
device.reward_score = 0
device.reward_reason = 'MAX_CAPACITY_REACHED'
device.base_reward = 0

total_weights = 0
for key in rewardable.keys:
hc = rewardable[key]
total_weights += hc.count * hc.weight

for key in rewardable.keys:
hc = rewardable[key]
hc.max_rewards = daily_emission * hc.weight / total_weights
for device in hc.devices:
device.base_reward = device.reward_score * hc.max_rewards

// business boost
for bb in business_boosts:
for device in bb.devices:
device.bb_reward += bb.daily_reward

// cumulative calculation
for user in users:
daily_cumulative_rewards = 0
for device in user.devices:
daily_cumulative_rewards = device.bb_reward + device.base_reward
if not user.active_wallet:
user.wallets[user.active_wallet] = daily_cumulative_rewards

// merkle tree
tree = []
for user in users:
for wallet in wallets:
tree.push([wallet, user[wallet].cumulative])

// blockchain tx

Withdrawing Rewards

Station owners have the freedom to withdraw their rewards at their discretion, without any time restrictions or other limitations.

Each owner may initiate the withdrawal process by signing a transaction using the private key that corresponds to the blockchain address they have connected to their station. A user-friendly front-end that can be used in conjunction with a wallet like Metamask will be provided, but station owners can also interact programmatically with the RewardPool smart contract to withdraw their rewards directly.

Smart Contracts and Rewarding Mechanism

The smart contracts and wallets associated with the rewarding mechanism are the following:

  • WeatherXM: ERC20 token
  • RewardPool: smart contract holding users' allocated $WXM rewards
  • RewardVault: smart contract holding the total amount of $WXM rewards to be allocated
  • BusinessDevelopmentPool: wallet holding all $WXM leftovers from daily rewards

The lifecycle of rewards from the rewarding mechanism to the users' wallets:

  • The Reward Mechanism calculates all rewards and allocates them to RewardPool
  • The RewardPool holds all allocated rewards
  • The RewardVault funds the RewardPool with the daily emission of $WXM
  • The Business Development Pool funds daily the RewardPool with the business boost of $WXM
  • The station owners withdraw their rewards programmatically or through the WeatherXM Platform by interacting with the RewardPool

Reward mechanism v1.5

This section describes the updated Reward Mechanism that will be used to allocate $WXM rewards to station owners for contributing weather data to the network. (deprecated)

Important Notes
  • Connecting a wallet is mandatory to receive rewards. If a user has not connected a wallet, the rewards will be lost.
  • Criteria that should be met for a weather station to be rewardable:
    • QoD over qod_threshold
    • PoL over pol_threshold
    • weather station’s owner should have an active wallet

Daily Rewards Calculation Process

The Reward Mechanism calculates the amount of tokens that will be distributed to users by completing the following phase:

Actual Rewards calculation

Actual rewards are calculated taking into account the performance of the weather station for the previous day.

This is a short summary of the criteria used:

  • Proof-of-Location (PoL): An algorithm that evaluates the data about the location of the weather station, its accuracy, consistency, and unison with the location the owner registered on the weather station claiming. It generates a score that denotes confidence about the weather station's location. WeatherXM places great importance on station continuity, necessitating that a station remains stationed at a single location. When a weather station undergoes relocation, its PoL score reduces to 0 and its seniority in the Cell is reset, aiming to discourage frequent movements and sustain a stable Network. Read more about the Proof of Location (PoL) mechanism.

  • Quality-of-Data (QoD): An algorithm that evaluates the quality of weather data provided by a weather station. It generates a score that denotes the confidence about the quality of the weather data for each weather station. WeatherXM values weather stations that produce meaningful and usable data and the QoD score is an attempt to quantify this metric. The end goal is to encourage weather station owners to do their best to comply with WeatherXM's guidelines in order to consistently achieve the best QoD score possible. Read more about the Quality of Data (QoD) mechanism.

  • Hardware-Class (HC): Each type of approved hardware (weather station) belongs to a specific Hardware Class. Hardware Classes are used to award more tokens to weather stations that have special capabilities, increased sensor accuracy or range, new sensor types, or other capabilities that make them more valuable to the network. For the time being all Hardware Classes are considered equal. Read more about the Hardware class.

  • Cell Capacity (CC): Each cell has a pre-defined cell capacity that depends on its geospatial characteristics. The cell's capacity is the maximum number of stations that may receive rewards in a specific cell. If N weather stations are active in a cell with a capacity X during a specific day, with N > X, only the first N stations (ordered first by reward_score, then by seniority) will receive rewards. Read more about the Cell Capacity (CC).

We will split the process into 5 distinct steps in an attempt to make everything as clear as possible.

a. The following variables have known values at the start of each day:

  • daily_emission: the amount of tokens that are available for allocation on the given day
  • weight_per_hardware_class: the number denoting how important an HC is compared to all the other HC
  • pol_threshold: the number denoting the cut-off threshold for PoL: weather stations with pol_score`` < pol_threshold are excluded from rewarding
  • qod_threshold: the number denoting the cut-off threshold for QoD: weather stations with qod_score < qod_threshold are excluded from rewarding
  • capacity per cell: the maximum number of weather stations that will be rewarded in a cell - the rest are excluded from rewarding

b. To calculate the rewardable count of devices per HC:

  • we exclude weather stations that are owned by users with no wallet address specified
  • we count the weather stations with qod_score and pol_score over the respected specified thresholds, qod_threshold, pol_threshold The number of stations that pass this evaluation are eligible for rewards.

c. To calculate the max_reward_per_hardware_class (MRPHC):

total_weights = sum(rewardable_count_per_hardware_class[i] * weight_per_hardware_class[i]), i = 1..n, where n = total number of HC

For every HC:

tokens_per_hardware_class = daily_emission * (rewardable_count_per_hardware_class * weight_per_hardware_class) / total_weights

max_reward_per_hardware_class = tokens_per_hardware_class / rewardable_count_per_hardware_class

d. To calculate the reward_score and actual_reward:

reward_score = pol_score * qod_score

actual_reward = reward_score * max_reward_per_hardware_class

e. To identify overcrowded cells and decide which of the weather stations will be excluded from rewarding:

  • we iterate over available cells and check whether it is overcrowded
  • in case it is indeed overcrowded, we sort the neighbouring weather stations first by reward_score and then by seniority (claimed_time). Only the N first will be rewarded, where N = capacity

Reward mechanism v1.0

The first iteration of Reward Mechanism operates in the following way: only taking into account whether or not a station is connected to the network. (deprecated)

The reward distribution mechanism has two parts:

  • The reward algorithm which calculates the actual_reward for each weather station by evaluating its weather data for the previous day
  • The daily reward distribution of rewards to the station owners

Connecting a wallet is mandatory to receive rewards. If a user has not connected a wallet, the rewards will be lost.

How Often does the Reward Algorithm run?

The algorithm runs every day to reward weather stations that were actively sending data to the network for the previous day.

Calculation of the Reward Score

reward_score = array_of_hourly_weather_data / 24


In the calculation of the reward_score step, the algorithm takes into account the weather data for each hour of the previous day for any given weather station.

  • If the weather station has successfully sent data for each hour of the previous day, then the algorithm's input is an array of 24 objects, with each object being the station's weather data.
  • If the weather station hasn't sent any weather data for 1 or more hours the previous day, then the algorithm's input is an array of (24 - X) objects, with each object being the station's weather data and X being the number of hours that the station hasn't communicated with our system.

That input is then being used by dividing its length by 24 (the maximum hours per day) to get a reward_score of 0.0 to 1.0.

After the calculation of the reward_score step, the algorithm takes the reward_score for any given weather station in our network, multiplies it with the max_daily_reward that the weather station can get, and the result is the amount of WXM tokens that the algorithm distributes to the user who owns that weather station.

The formulas which are used to calculate the daily reward per weather station is the following:

rewardable_count = Count(all_provisioned_weather_stations)
max_daily_reward = daily_emission / rewardable_count
weather_station_reward = reward_score * max_daily_reward

Reward Distribution Mechanism

All daily actual_reward per weather station are transferred to the wallet address already set by the user. This is a bulk transfer operations which happens once in a daily schedule and as a result the users get their daily rewards to their wallets. Due to blockchain limitations on the number of atomic transfer transactions that may take place with each bulk transfer, as many as needed bulk transfers can be executed for the purpose of everyone getting the daily rewards.