Skip to content

Commit df7f567

Browse files
ipapandinasJuminstockGunit2481
authored
feat: dAppStaking revamp (#778)
* feat: dAppStaking revamp * Update inflation distribution percentages * feat: dAppStaking revamp * Update inflation distribution percentages * Update: Add the FAQ folder with content * Replace the H2 for H3 into the questions --------- Co-authored-by: Carlos Rodríguez <juminstock@gmail.com> Co-authored-by: Gaius_sama <85451570+Gunit2481@users.noreply.github.com>
1 parent cea5b75 commit df7f567

17 files changed

Lines changed: 442 additions & 190 deletions

File tree

docs/build/dapp-staking/technical_solution.md

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,16 @@ The relevant storage map is `DAppTiers` which maps `era` to information about dA
122122

123123
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`.
124124

125-
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`.
126-
It’s enough to use `tier_id` it as index in the `rewards` vector to find the reward associated with that tier.
125+
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`.
126+
127+
With deterministic tier+rank rewards, the claim value is derived from two per-tier components:
128+
129+
- `tier_base_reward0 = dapp_tier_info.rewards[tier_id]` (rank 0 reward)
130+
- `reward_per_rank_step = dapp_tier_info.rank_rewards[tier_id]` (per +1 rank)
131+
132+
Final reward for a dApp with `rank` is:
133+
134+
`dapp_reward = tier_base_reward0 + rank * reward_per_rank_step`
127135

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

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

145153
### Bonus Rewards
146154

155+
:::warning Attention
156+
157+
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.
158+
159+
:::
160+
147161
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.
148162
The first key of the double map is `staker account` so it can easily be iterated via prefix iteration.
149163

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

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

182-
Each tier gets a portion of the reward pool (denoted as `reward_portion` in the configuration). These portions are further partitioned per slots.
196+
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:
197+
198+
```text
199+
MAX_RANK = 10
200+
step_bips = max(0, tier_rank_multipliers[tier] - 10_000) / MAX_RANK
183201
184-
E.g. for tier 1 dApp reward is calculated as:
202+
observed_total_weight = filled_slots * 10_000 + ranks_sum * step_bips
203+
expected_full_weight = max_slots * (10_000 + 5 * step_bips) // avg rank = 5
204+
normalization_weight = max(observed_total_weight, expected_full_weight)
205+
206+
tier_base_reward0 = tier_allocation * 10_000 / normalization_weight
207+
reward_per_rank_step = tier_allocation * step_bips / normalization_weight
208+
dapp_reward(rank) = tier_base_reward0 + rank * reward_per_rank_step
209+
```
185210

186-
`tier_1_dapp_reward = dapp_reward_pool_per_era * reward_portion[0] / slots_per_tier[0]`
211+
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.
187212

188213
### When To Call Expired Entry Cleanup
189214

docs/learn/dapp-staking/dapp-staking-faq.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@ Once unlocking is complete, you can then withdraw these tokens to your free bala
8888

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

91-
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.
91+
No rewards are generated during the **Voting** subperiod.
9292

93-
If you stake during any era of **Build&Earn Subperiod**, the staked amount is only eligible for rewards from the next era onward.
93+
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.
94+
95+
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.
9496

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

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

103105
### Q: What are bonus rewards?
104106

105-
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.
107+
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.
106108

107-
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.
109+
If you see bonus-related fields in older tooling or runtimes, treat them as **legacy/internal compatibility** only.
108110

109111
### Q: Can my rewards expire?
110112

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

113-
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.
115+
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.
114116

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

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

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

185-
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.
187+
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).
186188

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

0 commit comments

Comments
 (0)