Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions docs/build/dapp-staking/technical_solution.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,16 @@ The relevant storage map is `DAppTiers` which maps `era` to information about dA

After reading `DappTiers` storage map for a particular `era`, `dapp_tiers_rewards.dapps` _tree map_ must be checked whether it contains the `dapp_id` of the smart contract for which we want to claim rewards. Please note that `dapp_id` is `u16` dApp identifier which can be read from the `DAppInfo` struct in `IntegratedDAppsStorage`.

In case entry for the `dapp_id` exists, it will also contain the `tier_id` value which can be used to read the earned dApp reward from `dapp_tier_info.rewards`.
It’s enough to use `tier_id` it as index in the `rewards` vector to find the reward associated with that tier.
In case entry for the `dapp_id` exists, it will also contain the `tier_id` value (and rank within tier) which can be used to read the earned dApp reward components from `dapp_tier_info`.

With deterministic tier+rank rewards, the claim value is derived from two per-tier components:

- `tier_base_reward0 = dapp_tier_info.rewards[tier_id]` (rank 0 reward)
- `reward_per_rank_step = dapp_tier_info.rank_rewards[tier_id]` (per +1 rank)

Final reward for a dApp with `rank` is:

`dapp_reward = tier_base_reward0 + rank * reward_per_rank_step`

Once reward has been claimed, the associated entry will be removed `dapp_tiers_rewards.dapps` _tree map_.

Expand All @@ -144,6 +152,12 @@ Once we know the oldest period, we can use `PeriodEnd` storage map to find when

### Bonus Rewards

:::warning Attention

Tokenomics 3.0 has **no user-facing bonus rewards**, so indexers and UIs should not surface a "bonus pool", "bonus APR", or "vote-to-earn-bonus" guidance as a user benefit.

:::

When checking whether staker is eligible for any bonus rewards, it is necessary to check all of the `StakerInfo` double storage map entries related to that staker.
The first key of the double map is `staker account` so it can easily be iterated via prefix iteration.

Expand Down Expand Up @@ -179,11 +193,22 @@ However, it is possible that in that very same block, someone calls `claim_dapp_

Reward pools per era can be read from the `Inflation` pallet, by reading the `ActiveInflationConfig` storage value.

Each tier gets a portion of the reward pool (denoted as `reward_portion` in the configuration). These portions are further partitioned per slots.
Each tier gets a portion of the dApp reward pool (denoted as `reward_portion` in the configuration). Tokenomics 3.0 then computes deterministic tier reward components using `tier_rank_multipliers` (bips, `10_000 = 100%`) and a weight-based normalization cap:

```text
MAX_RANK = 10
step_bips = max(0, tier_rank_multipliers[tier] - 10_000) / MAX_RANK

E.g. for tier 1 dApp reward is calculated as:
observed_total_weight = filled_slots * 10_000 + ranks_sum * step_bips
expected_full_weight = max_slots * (10_000 + 5 * step_bips) // avg rank = 5
normalization_weight = max(observed_total_weight, expected_full_weight)

tier_base_reward0 = tier_allocation * 10_000 / normalization_weight
reward_per_rank_step = tier_allocation * step_bips / normalization_weight
dapp_reward(rank) = tier_base_reward0 + rank * reward_per_rank_step
```

`tier_1_dapp_reward = dapp_reward_pool_per_era * reward_portion[0] / slots_per_tier[0]`
This replaces any "empty slots fund rank rewards" interpretation: empty slots only affect `filled_slots` / normalization, and under-filled tiers can leave part of the tier allocation unminted.

### When To Call Expired Entry Cleanup

Expand Down
14 changes: 8 additions & 6 deletions docs/learn/dapp-staking/dapp-staking-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ Once unlocking is complete, you can then withdraw these tokens to your free bala

### Q: When will I start getting rewards after I stake?

If you stake during the dedicated **Voting Subperiod**, you qualify for bonus rewards as long as you maintain or increase your staked amount during the following Build&Earn Subperiod. Bonus rewards can be claimed after the period ends.
No rewards are generated during the **Voting** subperiod.

If you stake during any era of **Build&Earn Subperiod**, the staked amount is only eligible for rewards from the next era onward.
If you stake during the **Voting** subperiod, your stake is set up for the upcoming **Build&Earn** subperiod. Staker rewards are earned only for **Build&Earn** eras in which your stake was active for the entire era.

If you stake (or change your stake) during any era of **Build&Earn** subperiod, the updated amount is eligible for rewards from the **next era** onward.

### Q: When can I claim my rewards?

Expand All @@ -102,15 +104,15 @@ Generally, it’s recommended to claim your rewards once a week.

### Q: What are bonus rewards?

If a staker staked on a dApp during the `Voting` Subperiod and **keeps the same staked amount or higher** on a dApp through the whole `Build&Earn` Subperiod, they are eligible for the bonus rewards.
Tokenomics 3.0 has **no user-facing bonus rewards**. `Voting` and `Build&Earn` remain protocol phases, but integrators should not promote a separate "bonus pool" or "bonus APR" as a user benefit.

Bonus eligibility can be safely transferred between projects, preserving it for a limited number of moves, as defined by `MaxBonusSafeMovesPerPeriod`. Exceeding this limit results in bonus forfeiture for the affected stake.
If you see bonus-related fields in older tooling or runtimes, treat them as **legacy/internal compatibility** only.

### Q: Can my rewards expire?

Unclaimed rewards will eventually expire, so it's important to claim them in time or they'll miss out on earnings.

We encourage stakers engagement. This way, failing to actively revisit dApp staking at the start of each new period to select dApps for staking means missing out on bonus rewards and earnings.
We encourage stakers' engagement. If you don't revisit dApp staking at the start of each new period to select dApps for staking, you won't be earning rewards for expired **Build&Earn** eras.

### Q: What happens to my rewards if the project I'm staking on is unregistered from dApp Staking?

Expand Down Expand Up @@ -182,7 +184,7 @@ The threshold for tier 4 is fixed, while it is dynamic for the other tiers.

Rewards for dApps are **dynamic** (tier-dependent), meaning they change from one tier to another.

The rewards of a tier are split evenly among all its slots, ensuring equal rewards for each dApp within a tier, regardless of whether all slots are filled.
Within a tier, dApp rewards are **deterministic** and can also depend on the dApp's **rank (0..10)** (see the technical overview for the `tier_rank_multipliers` model). If a tier is under-filled, part of that tier allocation can remain **unminted** (lazy minting).

### Q: What happens to my rewards if my project is unregistered from dApp Staking?

Expand Down
Loading