Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/dyn tier thresholds #1306

Merged
merged 23 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
815ed11
remove number_of_slots from TiersConfiguration
ipapandinas Jul 22, 2024
04ea0df
remove use of TierThreshold enum in TiersConfiguration
ipapandinas Jul 22, 2024
26dd611
percentage variants added to TierThreshold for values derivation from…
ipapandinas Jul 23, 2024
13001f6
dyn tier percentages adjusted
ipapandinas Jul 24, 2024
24a09ae
sanity checks for total issuance percentages customisable via config
ipapandinas Jul 24, 2024
5b5affa
storage migration
ipapandinas Jul 24, 2024
68887d7
storage version checks added
ipapandinas Jul 25, 2024
27a6d32
storage version checks adjusted
ipapandinas Jul 26, 2024
9276ffd
new threshold calculation adjusted
ipapandinas Jul 29, 2024
f735aea
field renamed
ipapandinas Jul 29, 2024
5195002
try-runtime sanity check to ensure same number of slots
ipapandinas Jul 29, 2024
fbb0bda
add small tolerance to try-runtime sanity check
ipapandinas Jul 29, 2024
ce58e5c
README updated
ipapandinas Jul 29, 2024
5fbb35d
remove configurable min/max percentage checks for extra safety
ipapandinas Jul 30, 2024
ca710c8
preserve not applied migrations
ipapandinas Jul 30, 2024
657b658
useless procedural macros removed
ipapandinas Jul 30, 2024
32dd3f0
tvl amount variants removed from TierThreshold
ipapandinas Jul 30, 2024
aa4d147
from conversion
ipapandinas Jul 31, 2024
18725d0
field renamed
ipapandinas Jul 31, 2024
c87cdaa
versioned migration used for static tier params
ipapandinas Aug 1, 2024
853bc6e
PR review fixes
ipapandinas Aug 5, 2024
352eaaf
adjust percentages
ipapandinas Aug 6, 2024
d2d4287
review feedbacks
ipapandinas Aug 6, 2024
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
24 changes: 13 additions & 11 deletions bin/collator/src/local/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use sc_service::ChainType;
use sp_core::{crypto::Ss58Codec, sr25519, Pair, Public};
use sp_runtime::{
traits::{AccountIdConversion, IdentifyAccount, Verify},
Permill,
Perbill, Permill,
};

type AccountPublic = <Signature as Verify>::Signer;
Expand Down Expand Up @@ -163,19 +163,21 @@ fn testnet_genesis(
Permill::from_percent(40),
],
tier_thresholds: vec![
TierThreshold::DynamicTvlAmount {
amount: 100 * AST,
minimum_amount: 80 * AST,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(35_700_000), // 3.57%
minimum_required_percentage: Perbill::from_parts(23_800_000), // 2.38%
},
TierThreshold::DynamicTvlAmount {
amount: 50 * AST,
minimum_amount: 40 * AST,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(8_900_000), // 0.89%
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicTvlAmount {
amount: 20 * AST,
minimum_amount: 20 * AST,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::FixedTvlAmount { amount: 10 * AST },
],
slots_per_tier: vec![10, 20, 30, 40],
safeguard: Some(false),
Expand Down
25 changes: 13 additions & 12 deletions bin/collator/src/parachain/chain_spec/astar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use sc_service::ChainType;
use sp_core::{sr25519, Pair, Public};
use sp_runtime::{
traits::{IdentifyAccount, Verify},
Permill,
Perbill, Permill,
};

const PARA_ID: u32 = 2006;
Expand Down Expand Up @@ -167,21 +167,22 @@ fn make_genesis(
Permill::from_percent(30),
Permill::from_percent(40),
],
// percentages below are calulated based on total issuance at the time when dApp staking v3 was launched (8.4B)
tier_thresholds: vec![
TierThreshold::DynamicTvlAmount {
amount: 30000 * ASTR,
minimum_amount: 20000 * ASTR,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(35_700_000), // 3.57%
minimum_required_percentage: Perbill::from_parts(23_800_000), // 2.38%
},
TierThreshold::DynamicTvlAmount {
amount: 7500 * ASTR,
minimum_amount: 5000 * ASTR,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(8_900_000), // 0.89%
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicTvlAmount {
amount: 20000 * ASTR,
minimum_amount: 15000 * ASTR,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
},
TierThreshold::FixedTvlAmount {
amount: 5000 * ASTR,
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
],
slots_per_tier: vec![10, 20, 30, 40],
Expand Down
25 changes: 14 additions & 11 deletions bin/collator/src/parachain/chain_spec/shibuya.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use sp_core::{sr25519, Pair, Public};
use astar_primitives::oracle::CurrencyAmount;
use sp_runtime::{
traits::{IdentifyAccount, Verify},
Permill,
Perbill, Permill,
};

use super::{get_from_seed, Extensions};
Expand Down Expand Up @@ -179,20 +179,23 @@ fn make_genesis(
Permill::from_percent(30),
Permill::from_percent(40),
],
// percentages below are calulated based on a total issuance at the time when dApp staking v3 was launched (147M)
tier_thresholds: vec![
TierThreshold::DynamicTvlAmount {
amount: 100 * SBY,
minimum_amount: 80 * SBY,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(20_000), // 0.0020%
minimum_required_percentage: Perbill::from_parts(17_000), // 0.0017%
},
TierThreshold::DynamicTvlAmount {
amount: 50 * SBY,
minimum_amount: 40 * SBY,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(10_000), // 0.0010%
minimum_required_percentage: Perbill::from_parts(6_800), // 0.00068%
},
TierThreshold::DynamicTvlAmount {
amount: 20 * SBY,
minimum_amount: 20 * SBY,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(5_400), // 0.00054%
minimum_required_percentage: Perbill::from_parts(3_400), // 0.00034%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(1_400), // 0.00014%
},
TierThreshold::FixedTvlAmount { amount: 10 * SBY },
],
slots_per_tier: vec![10, 20, 30, 40],
safeguard: Some(false),
Expand Down
25 changes: 14 additions & 11 deletions bin/collator/src/parachain/chain_spec/shiden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use sp_core::{sr25519, Pair, Public};
use astar_primitives::oracle::CurrencyAmount;
use sp_runtime::{
traits::{IdentifyAccount, Verify},
Permill,
Perbill, Permill,
};

use super::{get_from_seed, Extensions};
Expand Down Expand Up @@ -169,20 +169,23 @@ fn make_genesis(
Permill::from_percent(30),
Permill::from_percent(40),
],
// percentages below are calulated based on a total issuance at the time when dApp staking v3 was launched (84.3M)
tier_thresholds: vec![
TierThreshold::DynamicTvlAmount {
amount: 30000 * SDN,
minimum_amount: 20000 * SDN,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(35_700_000), // 3.57%
minimum_required_percentage: Perbill::from_parts(23_800_000), // 2.38%
},
TierThreshold::DynamicTvlAmount {
amount: 7500 * SDN,
minimum_amount: 5000 * SDN,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(8_900_000), // 0.89%
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicTvlAmount {
amount: 20000 * SDN,
minimum_amount: 15000 * SDN,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::FixedTvlAmount { amount: 5000 * SDN },
],
slots_per_tier: vec![10, 20, 30, 40],
safeguard: Some(false),
Expand Down
2 changes: 1 addition & 1 deletion pallets/dapp-staking-v3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ At the end of each build&earn subperiod era, dApps are evaluated using a simple
Based on this metric, they are sorted, and assigned to tiers.

There is a limited number of tiers, and each tier has a limited capacity of slots.
Each tier also has a _threshold_ which a dApp must satisfy in order to enter it.
Each tier also has a _threshold_ which a dApp must satisfy in order to enter it. Thresholds for each tier are dynamically calculated as percentages of the total issuance at the time of the dApp staking v3 launch.

Better tiers bring bigger rewards, so dApps are encouraged to compete for higher tiers and attract staker's support.
For each tier, the reward pool and capacity are fixed. Each dApp within a tier always gets the same amount of reward.
Expand Down
3 changes: 1 addition & 2 deletions pallets/dapp-staking-v3/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,10 +704,9 @@ mod benchmarks {
// This is a hacky part to ensure we accommodate max number of contracts.
TierConfig::<T>::mutate(|config| {
let max_number_of_contracts: u16 = T::MaxNumberOfContracts::get().try_into().unwrap();
config.number_of_slots = max_number_of_contracts;
config.slots_per_tier[0] = max_number_of_contracts;
config.slots_per_tier[1..].iter_mut().for_each(|x| *x = 0);
config.tier_thresholds[0] = TierThreshold::FixedTvlAmount { amount: 1 };
config.tier_thresholds[0] = 1;
});
force_advance_to_next_era::<T>();
let claim_era = ActiveProtocolState::<T>::get().era - 1;
Expand Down
30 changes: 17 additions & 13 deletions pallets/dapp-staking-v3/src/benchmarking/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,32 +177,36 @@ pub(super) fn init_tier_settings<T: Config>() {
])
.unwrap(),
tier_thresholds: BoundedVec::try_from(vec![
TierThreshold::DynamicTvlAmount {
amount: 100 * UNIT,
minimum_amount: 80 * UNIT,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(11_112_000), // 1.1112%
minimum_required_percentage: Perbill::from_parts(8_889_000), // 0.8889%
},
TierThreshold::DynamicTvlAmount {
amount: 50 * UNIT,
minimum_amount: 40 * UNIT,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(5_556_000), // 0.5556%
minimum_required_percentage: Perbill::from_parts(4_400_000), // 0.44%
},
TierThreshold::DynamicTvlAmount {
amount: 20 * UNIT,
minimum_amount: 20 * UNIT,
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(2_223_000), // 0.2223%
minimum_required_percentage: Perbill::from_parts(2_223_000), // 0.2223%
},
TierThreshold::FixedTvlAmount {
amount: MIN_TIER_THRESHOLD,
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(1_667_000), // 0.1667%
},
])
.unwrap(),
};

let total_issuance = SEED as u128 * UNIT;
ipapandinas marked this conversation as resolved.
Show resolved Hide resolved
let tier_thresholds_with_issuance = ThresholdsWithIssuance {
thresholds: tier_params.tier_thresholds.clone(),
total_issuance,
};
// Init tier config, based on the initial params
let init_tier_config =
TiersConfiguration::<T::NumberOfTiers, T::TierSlots, T::BaseNativeCurrencyPrice> {
number_of_slots: NUMBER_OF_SLOTS.try_into().unwrap(),
slots_per_tier: BoundedVec::try_from(vec![10, 20, 30, 40]).unwrap(),
reward_portion: tier_params.reward_portion.clone(),
tier_thresholds: tier_params.tier_thresholds.clone(),
tier_thresholds: BoundedVec::from(tier_thresholds_with_issuance),
_phantom: Default::default(),
};

Expand Down
47 changes: 29 additions & 18 deletions pallets/dapp-staking-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub mod pallet {
use super::*;

/// The current storage version.
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(7);
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(8);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
Expand Down Expand Up @@ -520,8 +520,8 @@ pub mod pallet {
reward_portion: vec![Permill::from_percent(100 / num_tiers); num_tiers as usize],
slot_distribution: vec![Permill::from_percent(100 / num_tiers); num_tiers as usize],
tier_thresholds: (0..num_tiers)
.map(|i| TierThreshold::FixedTvlAmount {
amount: (10 * i).into(),
.map(|i| TierThreshold::FixedPercentage {
required_percentage: Perbill::from_percent(i),
ipapandinas marked this conversation as resolved.
Show resolved Hide resolved
})
.collect(),
slots_per_tier: vec![100; num_tiers as usize],
Expand Down Expand Up @@ -554,23 +554,23 @@ pub mod pallet {
"Invalid tier parameters values provided."
);

// Prepare tier configuration and verify its correctness
let number_of_slots = self.slots_per_tier.iter().fold(0_u16, |acc, &slots| {
acc.checked_add(slots).expect("Overflow")
});
let tier_thresholds_with_issuance = ThresholdsWithIssuance {
thresholds: tier_params.tier_thresholds.clone(),
total_issuance: T::Currency::total_issuance(),
};

let tier_config =
TiersConfiguration::<T::NumberOfTiers, T::TierSlots, T::BaseNativeCurrencyPrice> {
number_of_slots,
slots_per_tier: BoundedVec::<u16, T::NumberOfTiers>::try_from(
self.slots_per_tier.clone(),
)
.expect("Invalid number of slots per tier entries provided."),
reward_portion: tier_params.reward_portion.clone(),
tier_thresholds: tier_params.tier_thresholds.clone(),
tier_thresholds: BoundedVec::from(tier_thresholds_with_issuance),
_phantom: Default::default(),
};
assert!(
tier_params.is_valid(),
tier_config.is_valid(),
"Invalid tier config values provided."
);

Expand Down Expand Up @@ -1717,25 +1717,23 @@ pub mod pallet {
let mut upper_bound = Balance::zero();
let mut rank_rewards = Vec::new();

for (tier_id, (tier_capacity, tier_threshold)) in tier_config
for (tier_id, (tier_capacity, lower_bound)) in tier_config
.slots_per_tier
.iter()
.zip(tier_config.tier_thresholds.iter())
.enumerate()
{
let lower_bound = tier_threshold.threshold();

// Iterate over dApps until one of two conditions has been met:
// 1. Tier has no more capacity
// 2. dApp doesn't satisfy the tier threshold (since they're sorted, none of the following dApps will satisfy the condition either)
for (dapp_id, staked_amount) in dapp_stakes
.iter()
.skip(dapp_tiers.len())
.take_while(|(_, amount)| tier_threshold.is_satisfied(*amount))
.take_while(|(_, amount)| amount.ge(lower_bound))
.take(*tier_capacity as usize)
{
let rank = if T::RankingEnabled::get() {
RankedTier::find_rank(lower_bound, upper_bound, *staked_amount)
RankedTier::find_rank(*lower_bound, upper_bound, *staked_amount)
} else {
0
};
Expand Down Expand Up @@ -1765,7 +1763,7 @@ pub mod pallet {

rank_rewards.push(reward_per_rank);
dapp_tiers.append(&mut tier_slots);
upper_bound = lower_bound; // current threshold becomes upper bound for next tier
upper_bound = *lower_bound; // current threshold becomes upper bound for next tier
}

// 5.
Expand Down Expand Up @@ -1954,8 +1952,21 @@ pub mod pallet {
// Re-calculate tier configuration for the upcoming new era
let tier_params = StaticTierParams::<T>::get();
let average_price = T::NativePriceProvider::average_price();
let new_tier_config = TierConfig::<T>::get().calculate_new(average_price, &tier_params);
TierConfig::<T>::put(new_tier_config);
let total_issuance = T::Currency::total_issuance();

let new_tier_config =
TierConfig::<T>::get().calculate_new(&tier_params, average_price, total_issuance);

// Validate new tier configuration
if new_tier_config.is_valid() {
TierConfig::<T>::put(new_tier_config);
} else {
log::warn!(
target: LOG_TARGET,
"New tier configuration is invalid for era {}, preserving old one.",
next_era
);
}

Self::deposit_event(Event::<T>::NewEra { era: next_era });
if let Some(period_event) = maybe_period_event {
Expand Down
Loading
Loading