Skip to content

feat: dAppStaking revamp#1586

Merged
ipapandinas merged 16 commits intomasterfrom
feat/dapp-staking-revamp
Feb 12, 2026
Merged

feat: dAppStaking revamp#1586
ipapandinas merged 16 commits intomasterfrom
feat/dapp-staking-revamp

Conversation

@ipapandinas
Copy link
Contributor

@ipapandinas ipapandinas commented Jan 30, 2026

Pull Request Summary

Closes #1585

This PR implements the technical foundation for Tokenomics 3.0 dApp Staking simplification,
as outlined in this forum post.

The goal is a minimal, predictable upgrade that:

  • Removes bonus mechanics
  • Eliminates reward unpredictability
  • Preserves all historical rewards and claim logic
  • Reuses existing structures wherever possible

Problem (Current Design)

Rank rewards currently depend on empty_slots:

let remaining_reward = tier_reward * empty_slots;
let reward_per_rank = min(tier_reward / MAX_RANK, remaining_reward / ranks_sum);

This causes:

  • Zero rank rewards when tiers are full
  • Rewards that depend on ranks_sum
  • Unpredictable outcomes based on how many dApps qualify

Design Choice: Rank Multiplier Model

The empty_slots dependency is replaced with a single rank multiplier per tier, producing deterministic rewards.

Core Idea

Each tier defines one value:

“Rank 10 earns X% of the rank-0 reward.”

From this:

  • Rank increments are derived linearly
  • Rewards scale by rank weight
  • Total distribution is capped to prevent overflow

Reward Model (High Level)

increment = (multiplier - 100%) / MAX_RANK
weight = 100% + rank × increment

target_weight = max_slots × avg_weight
denominator = max(actual_weight, target_weight)

reward = weight × (tier_allocation / denominator)

Why This Works

  • Predictable: Fixed % per rank when a tier is normally filled
  • Overflow-safe: Rank collisions (e.g. all rank 10) are capped
  • Permissionless-safe: Partial tiers distribute proportionally
  • Simple config: One intuitive parameter per tier

Unfilled slots remain unminted (never redistributed).


Configuration Change

Add a single field to tier parameters:

pub struct TierParameters<NT> {
    // existing fields…

    /// Rank 10 reward as % of rank 0 reward (express in bips)
    pub tier_rank_multipliers: BoundedVec<u32, NT>,
}

Example production values:

  • Tier 0: 10_000bips (default, no rank rewards)
  • Tier 1: 24_000bips (rank 10 earns 2.4× rank 0)
  • Tier 2: 46_700bips (rank 10 earns 4.67× rank 0)
  • Tier 3: 0bips (no rewards)

This replaces multiple interacting parameters with one clear control.


What’s Preserved (Intentionally)

  • MAX_RANK = 10
  • find_rank() logic
  • RankedTier encoding
  • Claim formula and storage (DAppTierRewards)
  • Backward-compatible reward claims (no migration)

Why MaxNumberOfContractsLegacy = 500

Historical reward entries were bounded by 500 contracts.
This is preserved only to allow post-migration claims and can be removed once all legacy rewards are exhausted.

Alternatively we can claim all historical rewards ourselves and start fresh, preserving only the 16 desired dApps, so no need of the MaxNumberOfContractsLegacy config parameter. This is extra operational complexity, maybe unnecessary.


Rollout suggestion:

  1. Call to update inflation parameters before current B&E subperiods ends to use new params during the inflation recalculation (expected March 7th).
  2. Runtime upgrade during Voting subperiod. The storage migration sets new tiers params and the runtime configs are updated.
  3. Monitor first B&E eras for correct tier assignment and reward distribution.

Check list

  • added or updated unit tests
  • updated Astar official documentation
  • rerun benchmark to update weights

Follow up task

@ipapandinas ipapandinas added shiden related to shiden runtime dapps-staking Dapps Staking astar Related to Astar shibuya related to shibuya runtime This PR/Issue is related to the topic “runtime”. labels Jan 30, 2026
@ipapandinas ipapandinas marked this pull request as draft February 2, 2026 05:37
@ipapandinas ipapandinas marked this pull request as ready for review February 2, 2026 14:21
@ipapandinas
Copy link
Contributor Author

/bench astar,shibuya,shiden pallet_inflation,pallet_dapp_staking

@ipapandinas ipapandinas requested a review from Dinonard February 2, 2026 14:24
@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Benchmarks job is scheduled at https://github.com/AstarNetwork/Astar/actions/runs/21593812398.
Please wait for a while.
Branch: feat/dapp-staking-revamp
SHA: 1a6d9de

@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Benchmarks have been finished.
You can download artifacts if exists https://github.com/AstarNetwork/Astar/actions/runs/21593812398.

@ipapandinas ipapandinas marked this pull request as draft February 6, 2026 16:25
@ipapandinas ipapandinas marked this pull request as ready for review February 9, 2026 06:09
@ipapandinas
Copy link
Contributor Author

/bench astar,shibuya,shiden pallet_inflation,pallet_dapp_staking

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Benchmarks job is scheduled at https://github.com/AstarNetwork/Astar/actions/runs/21824706764.
Please wait for a while.
Branch: feat/dapp-staking-revamp
SHA: 79cd9d5

Comment on lines 507 to 509
fn eras_per_voting_subperiod() -> u32 {
11
1
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be zero?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This integrity check prevents it. Also, I'm not sure how the protocol will behave if we set it to 0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to explore this more after this PR is merged.
Not urgent since it's ok to change this before the next cycle starts in 2027.

I don't see why we shouldn't allow stake-and-forget, since we don't really need cycles anymore.
Only the reward expiration will need adjustment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, actually the stake-and-forget is what we want to achieve. The inflation recalculation needs to be decoupled as well, particularly here. Otherwise, with eras_per_cycle() saturated to EraNumber::MAX, the next recalculation era is unreachable. Inflation parameters are frozen at their values forever.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Benchmarks have been finished.
You can download artifacts if exists https://github.com/AstarNetwork/Astar/actions/runs/21824706764.

Copy link
Contributor

@Dinonard Dinonard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to post comments yesterday, sorry.

Dinonard
Dinonard previously approved these changes Feb 10, 2026
Copy link
Contributor

@Dinonard Dinonard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Given the magnitude of the change, I'd prefer to do another review of the code, but I don't have capacity ATM.

Dinonard
Dinonard previously approved these changes Feb 11, 2026
ashutoshvarma
ashutoshvarma previously approved these changes Feb 11, 2026
@ipapandinas ipapandinas dismissed stale reviews from ashutoshvarma and Dinonard via 0a7ab85 February 11, 2026 18:53
@github-actions
Copy link

Code Coverage

Package Line Rate Branch Rate Health
chain-extensions/types/unified-accounts/src 0% 0%
pallets/dynamic-evm-base-fee/src 85% 0%
pallets/xc-asset-config/src 57% 0%
chain-extensions/types/assets/src 0% 0%
pallets/collective-proxy/src 94% 0%
primitives/src/xcm 66% 0%
precompiles/substrate-ecdsa/src 74% 0%
pallets/dapp-staking/src/benchmarking 94% 0%
pallets/dapp-staking/src 77% 0%
pallets/democracy-mbm/src 30% 0%
precompiles/sr25519/src 69% 0%
pallets/collator-selection/src 82% 0%
precompiles/xcm/src 69% 0%
primitives/src 55% 0%
pallets/ethereum-checked/src 76% 0%
pallets/astar-xcm-benchmarks/src 86% 0%
pallets/dapp-staking/src/test 0% 0%
pallets/vesting-mbm/src 87% 0%
precompiles/dapp-staking/src/test 0% 0%
pallets/unified-accounts/src 80% 0%
pallets/inflation/src 58% 0%
chain-extensions/pallet-assets/src 55% 0%
pallets/static-price-provider/src 91% 0%
pallets/dapp-staking/rpc/runtime-api/src 0% 0%
precompiles/assets-erc20/src 77% 0%
precompiles/dispatch-lockdrop/src 89% 0%
precompiles/dapp-staking/src 89% 0%
chain-extensions/unified-accounts/src 0% 0%
pallets/astar-xcm-benchmarks/src/fungible 100% 0%
pallets/price-aggregator/src 75% 0%
precompiles/unified-accounts/src 100% 0%
pallets/astar-xcm-benchmarks/src/generic 100% 0%
Summary 71% (3864 / 5433) 0% (0 / 0)

Minimum allowed line rate is 50%

@ipapandinas ipapandinas merged commit a746049 into master Feb 12, 2026
8 checks passed
@ipapandinas ipapandinas deleted the feat/dapp-staking-revamp branch February 12, 2026 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

astar Related to Astar dapps-staking Dapps Staking runtime This PR/Issue is related to the topic “runtime”. shibuya related to shibuya shiden related to shiden runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dApp Staking Revamp

3 participants