diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index d3f3a87086c0..bc70e47732e7 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -14,8 +14,7 @@ use crate::{ HeapGovernanceData, XdrConversionRate, initialize_governance, reassemble_governance_proto, split_governance_proto, }, - is_comprehensive_neuron_list_enabled, is_mission_70_voting_rewards_enabled, - is_neuron_follow_restrictions_enabled, + is_comprehensive_neuron_list_enabled, is_neuron_follow_restrictions_enabled, neuron::{DissolveStateAndAge, Neuron, NeuronBuilder, Visibility}, neuron_data_validation::{NeuronDataValidationSummary, NeuronDataValidator}, neuron_store::{ @@ -305,15 +304,9 @@ pub const RELAXED_EIGHT_YEAR_GANG_MIN_DISSOLVE_DELAY_SECONDS: u64 = // its ICP must not be newly staked. This defines "sufficiently old staked ICP". pub const RELAXED_EIGHT_YEAR_GANG_MAX_AGING_SINCE_TIMESTAMP_SECONDS: u64 = 1_774_828_800; -/// Returns the maximum dissolve delay allowed for a neuron. After the flag is enabled, we can -/// replace `max_dissolve_delay_seconds()` with `MAX_DISSOLVE_DELAY_SECONDS` and set -/// `MAX_DISSOLVE_DELAY_SECONDS` to `MAX_DISSOLVE_DELAY_SECONDS_POST_MISSION_70`. +/// Returns the maximum dissolve delay allowed for a neuron. pub fn max_dissolve_delay_seconds() -> u64 { - if is_mission_70_voting_rewards_enabled() { - MAX_DISSOLVE_DELAY_SECONDS_POST_MISSION_70 - } else { - MAX_DISSOLVE_DELAY_SECONDS_PRE_MISSION_70 - } + MAX_DISSOLVE_DELAY_SECONDS_POST_MISSION_70 } impl GovernanceError { @@ -1368,11 +1361,10 @@ impl Governance { // Clamp all neuron dissolve delays to the Mission 70 maximum exactly once. // The snapshot serves as the idempotency guard: if it's already populated, // clamping has already run and we must not overwrite the pre-clamp record. - if is_mission_70_voting_rewards_enabled() - && governance - .heap_data - .neuron_id_to_pre_clamp_dissolve_state - .is_empty() + if governance + .heap_data + .neuron_id_to_pre_clamp_dissolve_state + .is_empty() { let now = governance.env.now(); governance.heap_data.neuron_id_to_pre_clamp_dissolve_state = governance @@ -4818,14 +4810,11 @@ impl Governance { } pub fn neuron_minimum_dissolve_delay_to_vote_seconds(&self) -> u64 { - let default = if is_mission_70_voting_rewards_enabled() { - VotingPowerEconomics::MISSION_70_DEFAULT_NEURON_MINIMUM_DISSOLVE_DELAY_TO_VOTE_SECONDS - } else { - VotingPowerEconomics::DEFAULT_NEURON_MINIMUM_DISSOLVE_DELAY_TO_VOTE_SECONDS - }; self.voting_power_economics() .neuron_minimum_dissolve_delay_to_vote_seconds - .unwrap_or(default) + .unwrap_or( + VotingPowerEconomics::MISSION_70_DEFAULT_NEURON_MINIMUM_DISSOLVE_DELAY_TO_VOTE_SECONDS, + ) } /// Reduces `neuron_minimum_dissolve_delay_to_vote_seconds` to 2 weeks if it is currently @@ -4834,10 +4823,6 @@ impl Governance { fn maybe_reduce_neuron_minimum_dissolve_delay_to_vote_seconds( heap_data: &mut HeapGovernanceData, ) { - if !is_mission_70_voting_rewards_enabled() { - return; - } - let Some(voting_power_economics) = heap_data .economics .as_mut() diff --git a/rs/nns/governance/src/governance/tests/mod.rs b/rs/nns/governance/src/governance/tests/mod.rs index b0f678c563f8..4b96b8448f81 100644 --- a/rs/nns/governance/src/governance/tests/mod.rs +++ b/rs/nns/governance/src/governance/tests/mod.rs @@ -1896,7 +1896,6 @@ fn test_maybe_set_relaxed_eight_year_gang_bonus_base() { #[test] fn test_post_upgrade_migrates_neuron_minimum_dissolve_delay_to_vote_seconds() { - let _mission70 = crate::temporarily_enable_mission_70_voting_rewards(); // Simulate the old production state: 6 months. let mut heap_data = HeapGovernanceData { economics: Some(NetworkEconomics { @@ -1930,7 +1929,6 @@ fn test_post_upgrade_migrates_neuron_minimum_dissolve_delay_to_vote_seconds() { #[test] #[should_panic(expected = "unexpectedly below 2 weeks")] fn test_post_upgrade_panics_if_neuron_minimum_dissolve_delay_to_vote_seconds_below_two_weeks() { - let _mission70 = crate::temporarily_enable_mission_70_voting_rewards(); let one_week_seconds = 7 * ONE_DAY_SECONDS; let mut heap_data = HeapGovernanceData { diff --git a/rs/nns/governance/src/lib.rs b/rs/nns/governance/src/lib.rs index 2aef49af163d..b98c7edc68c7 100644 --- a/rs/nns/governance/src/lib.rs +++ b/rs/nns/governance/src/lib.rs @@ -215,15 +215,6 @@ thread_local! { static ENABLE_SUBNET_SPLITTING_PROPOSALS: Cell = const { Cell::new(false) }; - - // The planned effects of enabling this flag include - // 1. Reduce max dissolve delay from 8 years to 2 years. This includes capping existing neurons via data migration. - // 2. Reduce voting rewards pool by approximately 36.71% (equivalently, scale by 0.6329 times). - // 3. Dissolve delay bonus: quadratic instead of linear, with a maximum of 3x instead of 2x. - // 4. Reduce the minimum dissolve delay needed to vote to 2 weeks instead of 6 months. - // 5. 8 year gang 10% bonus. - static ENABLE_MISSION_70_VOTING_REWARDS: Cell - = const { Cell::new(true) }; } thread_local! { @@ -308,20 +299,6 @@ pub fn are_subnet_splitting_proposals_enabled() -> bool { ENABLE_SUBNET_SPLITTING_PROPOSALS.get() } -pub fn is_mission_70_voting_rewards_enabled() -> bool { - ENABLE_MISSION_70_VOTING_REWARDS.get() -} - -#[cfg(any(test, feature = "canbench-rs", feature = "test"))] -pub fn temporarily_enable_mission_70_voting_rewards() -> Temporary { - Temporary::new(&ENABLE_MISSION_70_VOTING_REWARDS, true) -} - -#[cfg(any(test, feature = "canbench-rs", feature = "test"))] -pub fn temporarily_disable_mission_70_voting_rewards() -> Temporary { - Temporary::new(&ENABLE_MISSION_70_VOTING_REWARDS, false) -} - pub fn decoder_config() -> DecoderConfig { let mut config = DecoderConfig::new(); config.set_skipping_quota(DEFAULT_SKIPPING_QUOTA); diff --git a/rs/nns/governance/src/neuron/types.rs b/rs/nns/governance/src/neuron/types.rs index 2568d5118124..7d4ace8a9e82 100644 --- a/rs/nns/governance/src/neuron/types.rs +++ b/rs/nns/governance/src/neuron/types.rs @@ -1,7 +1,6 @@ use crate::{ DEFAULT_VOTING_POWER_REFRESHED_TIMESTAMP_SECONDS, governance::{LOG_PREFIX, MAX_NUM_HOT_KEYS_PER_NEURON, max_dissolve_delay_seconds}, - is_mission_70_voting_rewards_enabled, neuron::{ age_bonus_multiplier, combine_aged_stakes, dissolve_delay_bonus_multiplier, dissolve_state_and_age::DissolveStateAndAge, neuron_stake_e8s, @@ -380,11 +379,9 @@ impl Neuron { // 8 Year Gang bonus. Cap the bonus base to the current stake because // rejection fees can cause the bonus base to exceed stake_e8s. - if is_mission_70_voting_rewards_enabled() { - let eight_year_gang_bonus_base_e8s = self.eight_year_gang_bonus_base_e8s.min(stake_e8s); - potential_voting_power += - Decimal::from(eight_year_gang_bonus_base_e8s) / Decimal::from(10) * boost; - } + let eight_year_gang_bonus_base_e8s = self.eight_year_gang_bonus_base_e8s.min(stake_e8s); + potential_voting_power += + Decimal::from(eight_year_gang_bonus_base_e8s) / Decimal::from(10) * boost; // For DECIDING voting power. let adjustment_factor: Decimal = { diff --git a/rs/nns/governance/src/neuron/types/tests.rs b/rs/nns/governance/src/neuron/types/tests.rs index 223e7ea8713c..a46ac46f18af 100644 --- a/rs/nns/governance/src/neuron/types/tests.rs +++ b/rs/nns/governance/src/neuron/types/tests.rs @@ -6,7 +6,6 @@ use crate::{ self as pb, VotingPowerEconomics, manage_neuron::{Configure, SetDissolveTimestamp, StartDissolving, configure::Operation}, }, - temporarily_disable_mission_70_voting_rewards, temporarily_enable_mission_70_voting_rewards, }; use ic_cdk::println; use ic_nervous_system_common::{E8, ONE_MONTH_SECONDS, ONE_YEAR_SECONDS}; @@ -935,8 +934,6 @@ fn test_eight_year_gang_bonus_base_e8s_is_lost_after_dissolving() { #[test] fn test_eight_year_gang_bonus_is_capped_to_stake_e8s() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); - let now = 123_456_789; // 100 ICP stake, 100 ICP bonus base, 50 ICP in fees from rejected proposals. @@ -958,26 +955,3 @@ fn test_eight_year_gang_bonus_is_capped_to_stake_e8s() { assert_eq!(neuron.potential_voting_power(now), 55 * E8); } - -#[test] -fn test_eight_year_gang_bonus_not_applied_when_mission_70_disabled() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - - let now = 123_456_789; - - // 100 ICP stake with a tagged 8y-gang bonus base, but mission 70 is disabled - // so the bonus must not be applied. With 0 dissolve delay and 0 age, both - // multipliers are 1.0, so potential_voting_power = 100 * 1 * 1 = 100 ICP. - let neuron = NeuronBuilder::new_for_test( - 1, - DissolveStateAndAge::NotDissolving { - dissolve_delay_seconds: 0, - aging_since_timestamp_seconds: now, - }, - ) - .with_cached_neuron_stake_e8s(100 * E8) - .with_eight_year_gang_bonus_base_e8s(100 * E8) - .build(); - - assert_eq!(neuron.potential_voting_power(now), 100 * E8); -} diff --git a/rs/nns/governance/src/neuron/voting_power.rs b/rs/nns/governance/src/neuron/voting_power.rs index e407367099f3..bbdcb8610e4d 100644 --- a/rs/nns/governance/src/neuron/voting_power.rs +++ b/rs/nns/governance/src/neuron/voting_power.rs @@ -1,7 +1,4 @@ -use crate::{ - governance::{MAX_NEURON_AGE_FOR_AGE_BONUS, max_dissolve_delay_seconds}, - is_mission_70_voting_rewards_enabled, -}; +use crate::governance::{MAX_NEURON_AGE_FOR_AGE_BONUS, max_dissolve_delay_seconds}; use rust_decimal::Decimal; /// Currently, only used by an integration test. @@ -13,11 +10,7 @@ pub fn dissolve_delay_bonus_multiplier(dissolve_delay_seconds: u64) -> Decimal { // t is (clamped) dissolve delay in units of max dissolve delay, so 0.0 <= t <= 1.0. let t = Decimal::from(dissolve_delay_seconds) / Decimal::from(max_dissolve_delay_seconds); - (if is_mission_70_voting_rewards_enabled() { - Decimal::from(2) * t * t - } else { - t - }) + Decimal::from(1) + Decimal::from(2) * t * t + Decimal::from(1) } pub(crate) fn age_bonus_multiplier(age_seconds: u64) -> Decimal { diff --git a/rs/nns/governance/src/neuron/voting_power_tests.rs b/rs/nns/governance/src/neuron/voting_power_tests.rs index 565d3f2d0ce4..a97335241e05 100644 --- a/rs/nns/governance/src/neuron/voting_power_tests.rs +++ b/rs/nns/governance/src/neuron/voting_power_tests.rs @@ -1,62 +1,8 @@ use super::*; -use crate::{ - temporarily_disable_mission_70_voting_rewards, temporarily_enable_mission_70_voting_rewards, -}; use ic_nervous_system_common::{ONE_MONTH_SECONDS, ONE_YEAR_SECONDS}; #[test] -fn test_dissolve_delay_bonus_multiplier_pre_mission_70() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - - // Test the endpoints. - assert_eq!(dissolve_delay_bonus_multiplier(0), Decimal::from(1)); - assert_eq!( - dissolve_delay_bonus_multiplier(8 * ONE_YEAR_SECONDS), - Decimal::from(2) - ); - - // Test intermediate points. - assert_eq!( - dissolve_delay_bonus_multiplier(ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(1) / Decimal::from(8) - ); - assert_eq!( - dissolve_delay_bonus_multiplier(2 * ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(2) / Decimal::from(8) - ); - assert_eq!( - dissolve_delay_bonus_multiplier(3 * ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(3) / Decimal::from(8) - ); - assert_eq!( - dissolve_delay_bonus_multiplier(4 * ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(4) / Decimal::from(8) - ); - assert_eq!( - dissolve_delay_bonus_multiplier(5 * ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(5) / Decimal::from(8) - ); - assert_eq!( - dissolve_delay_bonus_multiplier(6 * ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(6) / Decimal::from(8) - ); - assert_eq!( - dissolve_delay_bonus_multiplier(7 * ONE_YEAR_SECONDS), - Decimal::from(1) + Decimal::from(7) / Decimal::from(8) - ); - - // Test beyond max dissolve delay. (No neuron should have this, but we can - // and do defend against it by clamping.) - assert_eq!( - dissolve_delay_bonus_multiplier(15 * ONE_YEAR_SECONDS), - Decimal::from(2) - ); -} - -#[test] -fn test_dissolve_delay_bonus_multiplier_while_mission_70_is_engaged() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); - +fn test_dissolve_delay_bonus_multiplier() { // Test the endpoints. assert_eq!(dissolve_delay_bonus_multiplier(0), Decimal::from(1)); assert_eq!( diff --git a/rs/nns/governance/src/neuron_store/metrics/tests.rs b/rs/nns/governance/src/neuron_store/metrics/tests.rs index bb5df00e264f..f163a3fe581d 100644 --- a/rs/nns/governance/src/neuron_store/metrics/tests.rs +++ b/rs/nns/governance/src/neuron_store/metrics/tests.rs @@ -1,7 +1,6 @@ use super::*; use crate::{ governance::max_dissolve_delay_seconds, - is_mission_70_voting_rewards_enabled, neuron::{DissolveStateAndAge, NeuronBuilder, dissolve_delay_bonus_multiplier}, pb::v1::{KnownNeuronData, MaturityDisbursement, NeuronType}, }; @@ -536,20 +535,10 @@ fn test_compute_neuron_metrics_non_self_authenticating() { // Step 3: Inspect results. // - // bucket_for_half_max: neuron_3 has a dissolve delay equal to max_dissolve_delay_seconds() / 2 - // (mapped to bucket 8 when the max is long, 2 when the max is short). - let bucket_for_half_max = if is_mission_70_voting_rewards_enabled() { - 2 - } else { - 8 - }; - // bucket_for_max: neuron_1 has a dissolve delay equal to max_dissolve_delay_seconds() - // (mapped to bucket 16 when the max is long, 4 when the max is short). - let bucket_for_max = if is_mission_70_voting_rewards_enabled() { - 4 - } else { - 16 - }; + // bucket_for_half_max: neuron_3 has a dissolve delay equal to max_dissolve_delay_seconds() / 2. + let bucket_for_half_max = 2; + // bucket_for_max: neuron_1 has a dissolve delay equal to max_dissolve_delay_seconds(). + let bucket_for_max = 4; assert_eq!( non_self_authenticating_controller_neuron_subset_metrics, @@ -720,20 +709,10 @@ fn test_compute_neuron_metrics_public_neurons() { // Step 3: Inspect results. // - // bucket_for_half_max: neuron_3 has a dissolve delay equal to max_dissolve_delay_seconds() / 2 - // (mapped to bucket 8 when the max is long, 2 when the max is short). - let bucket_for_half_max = if is_mission_70_voting_rewards_enabled() { - 2 - } else { - 8 - }; - // bucket_for_max: neuron_1 has a dissolve delay equal to max_dissolve_delay_seconds() - // (mapped to bucket 16 when the max is long, 4 when the max is short). - let bucket_for_max = if is_mission_70_voting_rewards_enabled() { - 4 - } else { - 16 - }; + // bucket_for_half_max: neuron_3 has a dissolve delay equal to max_dissolve_delay_seconds() / 2. + let bucket_for_half_max = 2; + // bucket_for_max: neuron_1 has a dissolve delay equal to max_dissolve_delay_seconds(). + let bucket_for_max = 4; assert_eq!( public_neuron_subset_metrics, @@ -895,15 +874,9 @@ fn test_compute_neuron_metrics_stale_and_expired_voting_power_neurons() { // Step 3: Inspect results. // - // All neurons are created with the maximum dissolve delay, and we bucket by - // that effective maximum: - // - Pre-mission-70: max dissolve delay is 8 years -> bucket 16 - // - Post-mission-70: max dissolve delay is clamped to 2 years -> bucket 4 - let bucket_for_max = if is_mission_70_voting_rewards_enabled() { - 4 - } else { - 16 - }; + // All neurons are created with the maximum dissolve delay (2 years), which + // maps to bucket 4. + let bucket_for_max = 4; assert_eq!( declining_voting_power_neuron_subset_metrics, diff --git a/rs/nns/governance/src/neuron_store/voting_power.rs b/rs/nns/governance/src/neuron_store/voting_power.rs index e4d7e6686fb2..e00d4d4184ad 100644 --- a/rs/nns/governance/src/neuron_store/voting_power.rs +++ b/rs/nns/governance/src/neuron_store/voting_power.rs @@ -3,7 +3,6 @@ use ic_nns_governance_api::Vote; use super::{NeuronStore, NeuronStoreError}; use crate::{ - is_mission_70_voting_rewards_enabled, neuron::Neuron, pb::v1::{Ballot, NeuronIdToVotingPowerMap, VotingPowerEconomics, VotingPowerTotal}, storage::neurons::NeuronSections, @@ -132,14 +131,11 @@ impl NeuronStore { let mut total_deciding_voting_power: u128 = 0; let mut total_potential_voting_power: u128 = 0; - let default_min_dissolve_delay = if is_mission_70_voting_rewards_enabled() { - VotingPowerEconomics::MISSION_70_DEFAULT_NEURON_MINIMUM_DISSOLVE_DELAY_TO_VOTE_SECONDS - } else { - VotingPowerEconomics::DEFAULT_NEURON_MINIMUM_DISSOLVE_DELAY_TO_VOTE_SECONDS - }; let min_dissolve_delay_seconds = voting_power_economics .neuron_minimum_dissolve_delay_to_vote_seconds - .unwrap_or(default_min_dissolve_delay); + .unwrap_or( + VotingPowerEconomics::MISSION_70_DEFAULT_NEURON_MINIMUM_DISSOLVE_DELAY_TO_VOTE_SECONDS, + ); let mut process_neuron = |neuron: &Neuron| { if neuron.is_inactive(now_seconds) diff --git a/rs/nns/governance/src/reward/calculation.rs b/rs/nns/governance/src/reward/calculation.rs index b71114eb542e..771bcad23d19 100644 --- a/rs/nns/governance/src/reward/calculation.rs +++ b/rs/nns/governance/src/reward/calculation.rs @@ -14,7 +14,7 @@ //! * Floating point makes code easier since the reward pool is specified as a //! fraction of the total ICP supply. -use crate::{is_mission_70_voting_rewards_enabled, pb::v1::RewardEvent}; +use crate::pb::v1::RewardEvent; use std::ops::{Add, Div, Mul, Sub}; // ---- NON-BOILERPLATE CODE STARTS HERE ---------------------------------- @@ -72,7 +72,7 @@ const REWARD_FLATTENING_DATE: IcTimestamp = IcTimestamp { }; // See https://x.com/dominic_w/status/2011156143796781481 . -const MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR: f64 = 0.6329; +const VOTING_REWARDS_ADJUSTMENT_FACTOR: f64 = 0.6329; /// Computes the reward to distribute, as a fraction of the ICP supply, for one /// day. @@ -97,15 +97,7 @@ pub fn rewards_pool_to_distribute_in_supply_fraction_for_one_day( let rate = FINAL_VOTING_REWARD_RELATIVE_RATE + variable_rate; - voting_rewards_adjustment_factor() * rate * ONE_DAY -} - -fn voting_rewards_adjustment_factor() -> f64 { - if is_mission_70_voting_rewards_enabled() { - MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR - } else { - 1.0 - } + VOTING_REWARDS_ADJUSTMENT_FACTOR * rate * ONE_DAY } impl RewardEvent { @@ -268,146 +260,61 @@ mod test { }}; } - mod mission_70_disabled { - use super::*; - use crate::temporarily_disable_mission_70_voting_rewards; - - #[test] - fn days_fully_after_flattening_produce_linear_reward() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(8 * 366), - 0.05 / 365.25 - ); - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(8 * 366 + 5), - 0.05 / 365.25 - ); - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(123456), - 0.05 / 365.25 - ); - } - - #[test] - fn reward_for_first_day() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(0), - 0.10 / 365.25 - ); - } - - #[test] - fn reward_for_entire_pre_flattening_interval_can_be_lower_and_upper_bounded() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - - let lower_bound = - (REWARD_FLATTENING_DATE - GENESIS) * FINAL_VOTING_REWARD_RELATIVE_RATE; - let upper_bound = - (REWARD_FLATTENING_DATE - GENESIS) * INITIAL_VOTING_REWARD_RELATIVE_RATE; - let actual = (0..(REWARD_FLATTENING_DATE.days_since_ic_genesis as u64)) - .map(rewards_pool_to_distribute_in_supply_fraction_for_one_day) - .sum(); - assert!(lower_bound < actual); - assert!(actual < upper_bound); - } - - #[test] - fn reward_is_convex_and_decreasing() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - - // Here we verify the convex inequality for all 3 consecutive days during the - // parabolic rate period. - for day in 0..(REWARD_FLATTENING_DATE.days_since_ic_genesis as u64) - 2 { - let a = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day); - let b = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day + 1); - let c = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day + 2); - - let d1 = b - a; - let d2 = c - b; - - // Decreasing. - assert!(d1 < 0.0, "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); - assert!(d2 < 0.0, "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); - - // Convex. That is, the second decrease is not as large as the first. - assert!(d1.abs() > d2.abs(), "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); - } - } - } // mod mission_70_disabled - - mod mission_70_enabled { - use super::*; - use crate::temporarily_enable_mission_70_voting_rewards; - - #[test] - fn days_fully_after_flattening_produce_linear_reward() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); - - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(8 * 366), - MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.05 / 365.25 - ); - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(8 * 366 + 5), - MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.05 / 365.25 - ); - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(123456), - MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.05 / 365.25 - ); - } - - #[test] - fn reward_for_first_day() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); - - assert_approx_eq!( - rewards_pool_to_distribute_in_supply_fraction_for_one_day(0), - MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.10 / 365.25 - ); - } - - #[test] - fn reward_for_entire_pre_flattening_interval_can_be_lower_and_upper_bounded() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); + #[test] + fn days_fully_after_flattening_produce_linear_reward() { + assert_approx_eq!( + rewards_pool_to_distribute_in_supply_fraction_for_one_day(8 * 366), + VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.05 / 365.25 + ); + assert_approx_eq!( + rewards_pool_to_distribute_in_supply_fraction_for_one_day(8 * 366 + 5), + VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.05 / 365.25 + ); + assert_approx_eq!( + rewards_pool_to_distribute_in_supply_fraction_for_one_day(123456), + VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.05 / 365.25 + ); + } - let lower_bound = MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR - * ((REWARD_FLATTENING_DATE - GENESIS) * FINAL_VOTING_REWARD_RELATIVE_RATE); - let upper_bound = MISSION_70_VOTING_REWARDS_ADJUSTMENT_FACTOR - * ((REWARD_FLATTENING_DATE - GENESIS) * INITIAL_VOTING_REWARD_RELATIVE_RATE); - let actual = (0..(REWARD_FLATTENING_DATE.days_since_ic_genesis as u64)) - .map(rewards_pool_to_distribute_in_supply_fraction_for_one_day) - .sum(); - assert!(lower_bound < actual); - assert!(actual < upper_bound); - } + #[test] + fn reward_for_first_day() { + assert_approx_eq!( + rewards_pool_to_distribute_in_supply_fraction_for_one_day(0), + VOTING_REWARDS_ADJUSTMENT_FACTOR * 0.10 / 365.25 + ); + } - /// This is a copy & paste of the test in the sibling mission_70_disabled module. - #[test] - fn reward_is_convex_and_decreasing() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); + #[test] + fn reward_for_entire_pre_flattening_interval_can_be_lower_and_upper_bounded() { + let lower_bound = VOTING_REWARDS_ADJUSTMENT_FACTOR + * ((REWARD_FLATTENING_DATE - GENESIS) * FINAL_VOTING_REWARD_RELATIVE_RATE); + let upper_bound = VOTING_REWARDS_ADJUSTMENT_FACTOR + * ((REWARD_FLATTENING_DATE - GENESIS) * INITIAL_VOTING_REWARD_RELATIVE_RATE); + let actual = (0..(REWARD_FLATTENING_DATE.days_since_ic_genesis as u64)) + .map(rewards_pool_to_distribute_in_supply_fraction_for_one_day) + .sum(); + assert!(lower_bound < actual); + assert!(actual < upper_bound); + } - // Here we verify the convex inequality for all 3 consecutive days during the - // parabolic rate period. - for day in 0..(REWARD_FLATTENING_DATE.days_since_ic_genesis as u64) - 2 { - let a = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day); - let b = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day + 1); - let c = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day + 2); + #[test] + fn reward_is_convex_and_decreasing() { + // Here we verify the convex inequality for all 3 consecutive days during the + // parabolic rate period. + for day in 0..(REWARD_FLATTENING_DATE.days_since_ic_genesis as u64) - 2 { + let a = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day); + let b = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day + 1); + let c = rewards_pool_to_distribute_in_supply_fraction_for_one_day(day + 2); - let d1 = b - a; - let d2 = c - b; + let d1 = b - a; + let d2 = c - b; - // Decreasing. - assert!(d1 < 0.0, "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); - assert!(d2 < 0.0, "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); + // Decreasing. + assert!(d1 < 0.0, "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); + assert!(d2 < 0.0, "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); - // Convex. That is, the second decrease is not as large as the first. - assert!(d1.abs() > d2.abs(), "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); - } + // Convex. That is, the second decrease is not as large as the first. + assert!(d1.abs() > d2.abs(), "{day}: {a}, {b}, {c} ({d1} vs. {d2}"); } - } // mod mission_70_enabled + } } diff --git a/rs/nns/governance/src/voting.rs b/rs/nns/governance/src/voting.rs index 99c467cdbbd8..bea0c44a56fc 100644 --- a/rs/nns/governance/src/voting.rs +++ b/rs/nns/governance/src/voting.rs @@ -602,8 +602,6 @@ mod test { VotingPowerEconomics, WaitForQuietState, proposal::Action, }, storage::with_voting_state_machines_mut, - temporarily_disable_mission_70_voting_rewards, - temporarily_enable_mission_70_voting_rewards, test_utils::{ ExpectedCallCanisterMethodCallArguments, MockEnvironment, StubCMC, StubIcpLedger, }, @@ -785,17 +783,6 @@ mod test { /// d. Neuron 7 does not have a ballot for proposal 1. All the other /// neurons do have ballots. #[test] - fn test_cast_vote_and_cascade_works_pre_mission_70() { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - test_cast_vote_and_cascade_works(); - } - - #[test] - fn test_cast_vote_and_cascade_works_with_mission_70() { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); - test_cast_vote_and_cascade_works(); - } - fn test_cast_vote_and_cascade_works() { // Step 1: Prepare the world. @@ -1455,22 +1442,8 @@ mod test { } #[tokio::test] - async fn test_rewards_distribution_is_blocked_on_votes_not_cast_in_state_machine_pre_mission_70() - { - let _restore_on_drop = temporarily_disable_mission_70_voting_rewards(); - test_rewards_distribution_is_blocked_on_votes_not_cast_in_state_machine(5474).await; - } - - #[tokio::test] - async fn test_rewards_distribution_is_blocked_on_votes_not_cast_in_state_machine_with_mission_70() - { - let _restore_on_drop = temporarily_enable_mission_70_voting_rewards(); - test_rewards_distribution_is_blocked_on_votes_not_cast_in_state_machine(3464).await; - } - - async fn test_rewards_distribution_is_blocked_on_votes_not_cast_in_state_machine( - expected_neuron_1_maturity: u64, - ) { + async fn test_rewards_distribution_is_blocked_on_votes_not_cast_in_state_machine() { + let expected_neuron_1_maturity = 3464; let now = 1733433219; let topic = Topic::Governance; let environment = MockEnvironment::new( diff --git a/rs/nns/governance/tests/governance.rs b/rs/nns/governance/tests/governance.rs index b6b5212a04cd..3eafec2bec73 100644 --- a/rs/nns/governance/tests/governance.rs +++ b/rs/nns/governance/tests/governance.rs @@ -55,7 +55,6 @@ use ic_nns_governance::{ }, }, governance_proto_builder::GovernanceProtoBuilder, - is_mission_70_voting_rewards_enabled, pb::v1::{ AddOrRemoveNodeProvider, Ballot, BallotInfo, CreateServiceNervousSystem, Empty, ExecuteNnsFunction, Followees, GovernanceError, IdealMatchedParticipationFunction, @@ -2752,15 +2751,8 @@ async fn test_reward_event_proposals_last_longer_than_reward_period() { }); let expected_distributed_e8s_equivalent = (expected_available_e8s_equivalent as f64 * neuron_share) as u64; - // The value depends on the dissolve delay bonus: - // - With 2-year max (mission 70): 1 year → 50% bonus → higher voting power ratio → 16 - // - With 8-year max (pre mission 70): 1 year → 12.5% bonus → lower voting power ratio → 15 - let expected_value = if is_mission_70_voting_rewards_enabled() { - 16 - } else { - 15 - }; - assert_eq!(expected_distributed_e8s_equivalent, expected_value); + // 2-year max dissolve delay: 1 year → 50% dissolve delay bonus → expected 16. + assert_eq!(expected_distributed_e8s_equivalent, 16); assert_eq!( *gov.latest_reward_event(), RewardEvent { @@ -9482,15 +9474,7 @@ fn test_deciding_and_potential_voting_power() { neuron.potential_voting_power(START_TIMESTAMP_SECONDS) }) .unwrap(); - assert_eq!( - original_potential_voting_power, - cached_neuron_stake_e8s - * if is_mission_70_voting_rewards_enabled() { - 3 - } else { - 2 - }, - ); + assert_eq!(original_potential_voting_power, cached_neuron_stake_e8s * 3,); // Step 2: Call the code under test. let mut previous_timestamp_seconds = START_TIMESTAMP_SECONDS