From 904d7f51a9b10394a86a49ef88c67edd370b055d Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 11:07:17 -0400 Subject: [PATCH 1/8] Reduce staking fees to 0.05%, waive fees for all intra-subnet stake moving --- pallets/subtensor/src/staking/move_stake.rs | 69 ++++++----- pallets/subtensor/src/staking/stake_utils.rs | 118 ++++++++++++++++--- pallets/subtensor/src/tests/move_stake.rs | 81 +++++++++++-- pallets/subtensor/src/tests/staking.rs | 16 +-- pallets/swap/src/pallet/mod.rs | 2 +- 5 files changed, 219 insertions(+), 67 deletions(-) diff --git a/pallets/subtensor/src/staking/move_stake.rs b/pallets/subtensor/src/staking/move_stake.rs index 9a4d515276..3245bf2b54 100644 --- a/pallets/subtensor/src/staking/move_stake.rs +++ b/pallets/subtensor/src/staking/move_stake.rs @@ -329,8 +329,12 @@ impl Pallet { set_limit: bool, ) -> Result { // Calculate the maximum amount that can be executed - let max_amount = if let Some(limit_price) = maybe_limit_price { - Self::get_max_amount_move(origin_netuid, destination_netuid, limit_price)? + let max_amount = if origin_netuid != destination_netuid { + if let Some(limit_price) = maybe_limit_price { + Self::get_max_amount_move(origin_netuid, destination_netuid, limit_price)? + } else { + alpha_amount + } } else { alpha_amount }; @@ -356,36 +360,47 @@ impl Pallet { max_amount }; - // do not pay fees to avoid double fees in moves transactions - let tao_unstaked = Self::unstake_from_subnet( - origin_hotkey, - origin_coldkey, - origin_netuid, - move_amount, - T::SwapInterface::min_price(), - true, - )?; + if origin_netuid != destination_netuid { + // do not pay remove fees to avoid double fees in moves transactions + let tao_unstaked = Self::unstake_from_subnet( + origin_hotkey, + origin_coldkey, + origin_netuid, + move_amount, + T::SwapInterface::min_price(), + true, + )?; - // Stake the unstaked amount into the destination. - // Because of the fee, the tao_unstaked may be too low if initial stake is low. In that case, - // do not restake. - if tao_unstaked >= DefaultMinStake::::get() { - // If the coldkey is not the owner, make the hotkey a delegate. - if Self::get_owning_coldkey_for_hotkey(destination_hotkey) != *destination_coldkey { - Self::maybe_become_delegate(destination_hotkey); + // Stake the unstaked amount into the destination. + // Because of the fee, the tao_unstaked may be too low if initial stake is low. In that case, + // do not restake. + if tao_unstaked >= DefaultMinStake::::get() { + // If the coldkey is not the owner, make the hotkey a delegate. + if Self::get_owning_coldkey_for_hotkey(destination_hotkey) != *destination_coldkey { + Self::maybe_become_delegate(destination_hotkey); + } + + Self::stake_into_subnet( + destination_hotkey, + destination_coldkey, + destination_netuid, + tao_unstaked, + T::SwapInterface::max_price(), + set_limit, + )?; } - Self::stake_into_subnet( - destination_hotkey, + Ok(tao_unstaked) + } else { + Self::transfer_stake_within_subnet( + origin_coldkey, + origin_hotkey, destination_coldkey, - destination_netuid, - tao_unstaked, - T::SwapInterface::max_price(), - set_limit, - )?; + destination_hotkey, + origin_netuid, + move_amount, + ) } - - Ok(tao_unstaked) } /// Returns the maximum amount of origin netuid Alpha that can be executed before we cross diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 8dce6f9f7c..b7af6b7070 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -876,6 +876,83 @@ impl Pallet { Ok(swap_result.amount_paid_out) } + /// Transfers stake between coldkeys and/or hotkey within one subnet without running it + /// through swap. + /// + /// Does not incur any swapping nor fees + pub fn transfer_stake_within_subnet( + origin_coldkey: &T::AccountId, + origin_hotkey: &T::AccountId, + destination_coldkey: &T::AccountId, + destination_hotkey: &T::AccountId, + netuid: NetUid, + alpha: u64, + ) -> Result { + // Decrease alpha on origin keys + let actual_alpha_decrease = Self::decrease_stake_for_hotkey_and_coldkey_on_subnet( + origin_hotkey, + origin_coldkey, + netuid, + alpha, + ); + + // Increase alpha on destination keys + let actual_alpha_moved = Self::increase_stake_for_hotkey_and_coldkey_on_subnet( + destination_hotkey, + destination_coldkey, + netuid, + actual_alpha_decrease, + ); + + // Calculate TAO equivalent based on current price (it is accurate because + // there's no slippage in this move) + let current_price = + ::SwapInterface::current_alpha_price(netuid.into()); + let tao_equivalent = current_price + .saturating_mul(U96F32::saturating_from_num(actual_alpha_moved)) + .saturating_to_num::(); + + // Ensure tao_equivalent is above DefaultMinStake + ensure!( + tao_equivalent >= DefaultMinStake::::get(), + Error::::AmountTooLow + ); + + // Step 3: Update StakingHotkeys if the hotkey's total alpha, across all subnets, is zero + // TODO: fix. + // if Self::get_stake(hotkey, coldkey) == 0 { + // StakingHotkeys::::mutate(coldkey, |hotkeys| { + // hotkeys.retain(|k| k != hotkey); + // }); + // } + + LastColdkeyHotkeyStakeBlock::::insert( + destination_coldkey, + destination_hotkey, + Self::get_current_block_as_u64(), + ); + + // Deposit and log the unstaking event. + Self::deposit_event(Event::StakeRemoved( + origin_coldkey.clone(), + origin_hotkey.clone(), + tao_equivalent, + actual_alpha_decrease, + netuid, + 0_u64, // 0 fee + )); + Self::deposit_event(Event::StakeAdded( + destination_coldkey.clone(), + destination_hotkey.clone(), + tao_equivalent, + actual_alpha_moved, + netuid, + 0_u64, // 0 fee + )); + + Ok(tao_equivalent) + } + pub fn get_alpha_share_pool( hotkey: ::AccountId, netuid: NetUid, @@ -1119,21 +1196,24 @@ impl Pallet { Error::::NotEnoughStakeToWithdraw ); - // Ensure that the stake amount to be removed is above the minimum in tao equivalent. - let tao_equivalent = - T::SwapInterface::sim_swap(origin_netuid.into(), OrderType::Sell, alpha_amount) - .map(|res| res.amount_paid_out) - .map_err(|_| Error::::InsufficientLiquidity)?; - ensure!( - tao_equivalent > DefaultMinStake::::get(), - Error::::AmountTooLow - ); + // If origin and destination netuid are different, do the swap-related checks + if origin_netuid != destination_netuid { + // Ensure that the stake amount to be removed is above the minimum in tao equivalent. + let tao_equivalent = + T::SwapInterface::sim_swap(origin_netuid.into(), OrderType::Sell, alpha_amount) + .map(|res| res.amount_paid_out) + .map_err(|_| Error::::InsufficientLiquidity)?; + ensure!( + tao_equivalent > DefaultMinStake::::get(), + Error::::AmountTooLow + ); - // Ensure that if partial execution is not allowed, the amount will not cause - // slippage over desired - if let Some(allow_partial) = maybe_allow_partial { - if !allow_partial { - ensure!(alpha_amount <= max_amount, Error::::SlippageTooHigh); + // Ensure that if partial execution is not allowed, the amount will not cause + // slippage over desired + if let Some(allow_partial) = maybe_allow_partial { + if !allow_partial { + ensure!(alpha_amount <= max_amount, Error::::SlippageTooHigh); + } } } @@ -1143,10 +1223,12 @@ impl Pallet { TransferToggle::::get(origin_netuid), Error::::TransferDisallowed ); - ensure!( - TransferToggle::::get(destination_netuid), - Error::::TransferDisallowed - ); + if origin_netuid != destination_netuid { + ensure!( + TransferToggle::::get(destination_netuid), + Error::::TransferDisallowed + ); + } } Ok(()) diff --git a/pallets/subtensor/src/tests/move_stake.rs b/pallets/subtensor/src/tests/move_stake.rs index 375f43e345..674505329f 100644 --- a/pallets/subtensor/src/tests/move_stake.rs +++ b/pallets/subtensor/src/tests/move_stake.rs @@ -45,7 +45,7 @@ fn test_do_move_success() { ); // Perform the move - let expected_alpha = alpha * 997 / 1000; + let expected_alpha = alpha; assert_ok!(SubtensorModule::do_move_stake( RuntimeOrigin::signed(coldkey), origin_hotkey, @@ -375,7 +375,7 @@ fn test_do_move_partial_stake() { &coldkey, netuid ), - alpha_moved * 997 / 1000, + alpha_moved, epsilon = 10_000 ); }); @@ -412,7 +412,7 @@ fn test_do_move_multiple_times() { SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &coldkey, netuid); // Move stake multiple times - let mut expected_alpha: u64 = alpha; + let expected_alpha: u64 = alpha; for _ in 0..3 { let alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, &coldkey, netuid, @@ -438,9 +438,6 @@ fn test_do_move_multiple_times() { netuid, alpha2, )); - - // Reduce expected_alpha by fees x2 - expected_alpha -= expected_alpha * 6 / 1000; } // Check final stake distribution @@ -606,7 +603,9 @@ fn test_do_move_event_emission() { // Move stake and capture events System::reset_events(); - let (tao_equivalent, _) = mock::swap_alpha_to_tao_ext(netuid, alpha, true); + let current_price = + ::SwapInterface::current_alpha_price(netuid.into()); + let tao_equivalent = (current_price * U96F32::from_num(alpha)).to_num::(); // no fee conversion assert_ok!(SubtensorModule::do_move_stake( RuntimeOrigin::signed(coldkey), origin_hotkey, @@ -699,6 +698,65 @@ fn test_do_move_storage_updates() { }); } +#[test] +fn test_move_full_amount_same_netuid() { + new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let coldkey = U256::from(1); + let origin_hotkey = U256::from(2); + let destination_hotkey = U256::from(3); + let stake_amount = DefaultMinStake::::get() * 10; + SubtensorModule::create_account_if_non_existent(&coldkey, &origin_hotkey); + SubtensorModule::create_account_if_non_existent(&coldkey, &destination_hotkey); + + // Set up initial stake + SubtensorModule::stake_into_subnet( + &origin_hotkey, + &coldkey, + netuid, + stake_amount, + ::SwapInterface::max_price(), + false, + ) + .unwrap(); + + // Move all stake + let alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &origin_hotkey, + &coldkey, + netuid, + ); + assert_ok!(SubtensorModule::do_move_stake( + RuntimeOrigin::signed(coldkey), + origin_hotkey, + destination_hotkey, + netuid, + netuid, + alpha, + )); + + // Verify storage updates + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &origin_hotkey, + &coldkey, + netuid + ), + 0 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &destination_hotkey, + &coldkey, + netuid + ), + alpha + ); + }); +} + // 18. test_do_move_max_values // Description: Test moving the maximum possible stake values to check for overflows // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::move_stake::test_do_move_max_values --exact --show-output @@ -737,7 +795,6 @@ fn test_do_move_max_values() { ); // Move maximum stake - let (_, fee) = mock::swap_alpha_to_tao_ext(netuid, alpha, true); assert_ok!(SubtensorModule::do_move_stake( RuntimeOrigin::signed(coldkey), origin_hotkey, @@ -756,15 +813,13 @@ fn test_do_move_max_values() { ), 0 ); - let alpha_after_fee = alpha - fee; - assert_abs_diff_eq!( + assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &destination_hotkey, &coldkey, netuid ), - alpha_after_fee, - epsilon = alpha_after_fee / 100_000 + alpha ); }); } @@ -842,7 +897,7 @@ fn test_do_transfer_success() { ); // 4. Transfer the entire stake to the destination coldkey on the same subnet (netuid, netuid). - let expected_alpha = alpha * 997 / 1000; + let expected_alpha = alpha; assert_ok!(SubtensorModule::do_transfer_stake( RuntimeOrigin::signed(origin_coldkey), destination_coldkey, diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 54a4ecd6f9..c138dd5bd0 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -3464,12 +3464,10 @@ fn test_max_amount_remove_dynamic() { Error::::ZeroMaxStakeAmount ), Ok(v) => { - let expected = v.saturating_add((*v as f64 * 0.003) as u64); - assert_abs_diff_eq!( SubtensorModule::get_max_amount_remove(netuid, limit_price).unwrap(), - expected, - epsilon = expected / 100 + v, + epsilon = v / 100 ); } } @@ -3700,7 +3698,7 @@ fn test_max_amount_move_dynamic_stable() { assert_abs_diff_eq!( SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 375_000_000) .unwrap(), - alpha_in_u64 + (alpha_in_u64 as f64 * 0.003) as u64, + alpha_in_u64, epsilon = alpha_in_u64 / 1000, ); @@ -4731,7 +4729,9 @@ fn test_stake_into_subnet_ok() { u64::MAX, false, )); - let expected_stake = (amount as f64) * 0.997 / current_price; + let fee_rate = pallet_subtensor_swap::FeeRate::::get(NetUid::from(netuid)) as f64 + / u16::MAX as f64; + let expected_stake = (amount as f64) * (1. - fee_rate) / current_price; // Check if stake has increased assert_abs_diff_eq!( @@ -5269,7 +5269,7 @@ fn test_remove_stake_full_limit_ok() { ); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_abs_diff_eq!(new_balance, 9_066_000_000, epsilon = 1_000_000); + assert_abs_diff_eq!(new_balance, 9_086_000_000, epsilon = 1_000_000); }); } @@ -5353,7 +5353,7 @@ fn test_remove_stake_full_limit_ok_with_no_limit_price() { ); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_abs_diff_eq!(new_balance, 9_066_000_000, epsilon = 1_000_000); + assert_abs_diff_eq!(new_balance, 9_086_000_000, epsilon = 1_000_000); }); } /// This test verifies that minimum stake amount is sufficient to move price and apply diff --git a/pallets/swap/src/pallet/mod.rs b/pallets/swap/src/pallet/mod.rs index e5fdec045f..8ed1bc91bc 100644 --- a/pallets/swap/src/pallet/mod.rs +++ b/pallets/swap/src/pallet/mod.rs @@ -68,7 +68,7 @@ mod pallet { /// Default fee rate if not set #[pallet::type_value] pub fn DefaultFeeRate() -> u16 { - 196 // 0.3 % + 33 // ~0.05 % } /// The fee rate applied to swaps per subnet, normalized value between 0 and u16::MAX From e13a3e70e997d7a9e6314ea48968f94b03c0aacb Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 11:09:29 -0400 Subject: [PATCH 2/8] Spec version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 384e841072..19b44a6e0b 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -218,7 +218,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 292, + spec_version: 293, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From c47ae2bdb62486f25ff3fe49cdd1af30c95d46a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 11 Jul 2025 17:19:30 +0000 Subject: [PATCH 3/8] auto-update benchmark weights --- pallets/subtensor/src/macros/dispatches.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 95028a36d5..2bc5ced1ee 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1637,9 +1637,9 @@ mod dispatches { /// - The alpha stake amount to move. /// #[pallet::call_index(85)] - #[pallet::weight((Weight::from_parts(419_500_000, 0) - .saturating_add(T::DbWeight::get().reads(32)) - .saturating_add(T::DbWeight::get().writes(20)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(157_100_000, 0) + .saturating_add(T::DbWeight::get().reads(15_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)), DispatchClass::Operational, Pays::No))] pub fn move_stake( origin: T::RuntimeOrigin, origin_hotkey: T::AccountId, @@ -1680,9 +1680,9 @@ mod dispatches { /// # Events /// May emit a `StakeTransferred` event on success. #[pallet::call_index(86)] - #[pallet::weight((Weight::from_parts(432_600_000, 0) - .saturating_add(T::DbWeight::get().reads(31)) - .saturating_add(T::DbWeight::get().writes(19)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(154_800_000, 0) + .saturating_add(T::DbWeight::get().reads(13_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)), DispatchClass::Operational, Pays::No))] pub fn transfer_stake( origin: T::RuntimeOrigin, destination_coldkey: T::AccountId, From 21f538bf6881ecbe3041b991847ba11627cefa52 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 16:50:38 -0400 Subject: [PATCH 4/8] Fix get_stake_fee for inter-subnet transfers (needs to return 0) --- pallets/subtensor/src/rpc_info/stake_info.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/rpc_info/stake_info.rs b/pallets/subtensor/src/rpc_info/stake_info.rs index 5fd9f6f7b8..a0056e108e 100644 --- a/pallets/subtensor/src/rpc_info/stake_info.rs +++ b/pallets/subtensor/src/rpc_info/stake_info.rs @@ -124,7 +124,11 @@ impl Pallet { _destination_coldkey_account: T::AccountId, amount: u64, ) -> u64 { - let netuid = destination.or(origin).map(|v| v.1).unwrap_or_default(); - T::SwapInterface::approx_fee_amount(netuid.into(), amount) + if destination == origin { + 0_u64 + } else { + let netuid = destination.or(origin).map(|v| v.1).unwrap_or_default(); + T::SwapInterface::approx_fee_amount(netuid.into(), amount) + } } } From 18f283aff3bb98beb8fe9c9c51e8d9fb8e63eaec Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 17:51:36 -0400 Subject: [PATCH 5/8] Add pays::yes to all stake movements --- pallets/subtensor/src/macros/dispatches.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 2bc5ced1ee..ef4ad3e160 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1639,7 +1639,7 @@ mod dispatches { #[pallet::call_index(85)] #[pallet::weight((Weight::from_parts(157_100_000, 0) .saturating_add(T::DbWeight::get().reads(15_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)), DispatchClass::Operational, Pays::No))] + .saturating_add(T::DbWeight::get().writes(7_u64)), DispatchClass::Operational, Pays::Yes))] pub fn move_stake( origin: T::RuntimeOrigin, origin_hotkey: T::AccountId, @@ -1682,7 +1682,7 @@ mod dispatches { #[pallet::call_index(86)] #[pallet::weight((Weight::from_parts(154_800_000, 0) .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)), DispatchClass::Operational, Pays::No))] + .saturating_add(T::DbWeight::get().writes(6_u64)), DispatchClass::Operational, Pays::Yes))] pub fn transfer_stake( origin: T::RuntimeOrigin, destination_coldkey: T::AccountId, @@ -1726,7 +1726,7 @@ mod dispatches { .saturating_add(T::DbWeight::get().reads(32)) .saturating_add(T::DbWeight::get().writes(17)), DispatchClass::Operational, - Pays::No + Pays::Yes ))] pub fn swap_stake( origin: T::RuntimeOrigin, From 7d33bd26ad36331c703ea352c808d351cec96c49 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 17:56:30 -0400 Subject: [PATCH 6/8] Add Pays::Yes for all staking transactions to prevent spam --- pallets/subtensor/src/macros/dispatches.rs | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index ef4ad3e160..f1a0881f00 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -456,7 +456,7 @@ mod dispatches { #[pallet::call_index(1)] #[pallet::weight((Weight::from_parts(3_657_000, 0) .saturating_add(T::DbWeight::get().reads(0)) - .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::Yes))] pub fn become_delegate(_origin: OriginFor, _hotkey: T::AccountId) -> DispatchResult { // DEPRECATED // Self::do_become_delegate(origin, hotkey, Self::get_default_delegate_take()) @@ -587,7 +587,7 @@ mod dispatches { #[pallet::call_index(2)] #[pallet::weight((Weight::from_parts(345_500_000, 0) .saturating_add(T::DbWeight::get().reads(26)) - .saturating_add(T::DbWeight::get().writes(15)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(15)), DispatchClass::Normal, Pays::Yes))] pub fn add_stake( origin: OriginFor, hotkey: T::AccountId, @@ -631,7 +631,7 @@ mod dispatches { #[pallet::call_index(3)] #[pallet::weight((Weight::from_parts(196_800_000, 0) .saturating_add(T::DbWeight::get().reads(19)) - .saturating_add(T::DbWeight::get().writes(10)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(10)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake( origin: OriginFor, hotkey: T::AccountId, @@ -1046,11 +1046,11 @@ mod dispatches { #[pallet::call_index(69)] #[pallet::weight(( Weight::from_parts(5_760_000, 0) - .saturating_add(T::DbWeight::get().reads(0)) - .saturating_add(T::DbWeight::get().writes(1)), - DispatchClass::Operational, - Pays::No -))] + .saturating_add(T::DbWeight::get().reads(0)) + .saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Operational, + Pays::No + ))] pub fn sudo_set_tx_childkey_take_rate_limit( origin: OriginFor, tx_rate_limit: u64, @@ -1577,7 +1577,7 @@ mod dispatches { #[pallet::call_index(83)] #[pallet::weight((Weight::from_parts(30_190_000, 0) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Operational, Pays::No))] + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Operational, Pays::Yes))] pub fn unstake_all(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_unstake_all(origin, hotkey) } @@ -1610,7 +1610,7 @@ mod dispatches { #[pallet::call_index(84)] #[pallet::weight((Weight::from_parts(369_500_000, 0) .saturating_add(T::DbWeight::get().reads(33)) - .saturating_add(T::DbWeight::get().writes(16)), DispatchClass::Operational, Pays::No))] + .saturating_add(T::DbWeight::get().writes(16)), DispatchClass::Operational, Pays::Yes))] pub fn unstake_all_alpha(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_unstake_all_alpha(origin, hotkey) } @@ -1789,7 +1789,7 @@ mod dispatches { #[pallet::call_index(88)] #[pallet::weight((Weight::from_parts(402_800_000, 0) .saturating_add(T::DbWeight::get().reads(26)) - .saturating_add(T::DbWeight::get().writes(15)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(15)), DispatchClass::Normal, Pays::Yes))] pub fn add_stake_limit( origin: OriginFor, hotkey: T::AccountId, @@ -1853,7 +1853,7 @@ mod dispatches { #[pallet::call_index(89)] #[pallet::weight((Weight::from_parts(403_800_000, 0) .saturating_add(T::DbWeight::get().reads(30)) - .saturating_add(T::DbWeight::get().writes(14)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(14)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_limit( origin: OriginFor, hotkey: T::AccountId, @@ -1899,7 +1899,7 @@ mod dispatches { .saturating_add(T::DbWeight::get().reads(32)) .saturating_add(T::DbWeight::get().writes(17)), DispatchClass::Operational, - Pays::No + Pays::Yes ))] pub fn swap_stake_limit( origin: T::RuntimeOrigin, @@ -2077,7 +2077,7 @@ mod dispatches { #[pallet::call_index(103)] #[pallet::weight((Weight::from_parts(398_000_000, 10142) .saturating_add(T::DbWeight::get().reads(30_u64)) - .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_full_limit( origin: T::RuntimeOrigin, hotkey: T::AccountId, From 7748eb25264f9eb47a90f3ecd872762b628f637b Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 18:57:59 -0400 Subject: [PATCH 7/8] Add pays::yes for associate_evm_key --- pallets/subtensor/src/macros/dispatches.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index f1a0881f00..60e3109746 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1996,7 +1996,7 @@ mod dispatches { #[pallet::weight(( Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(2, 1)), DispatchClass::Operational, - Pays::No + Pays::Yes ))] pub fn associate_evm_key( origin: T::RuntimeOrigin, From e3dab17ada85a566f6b673de084e70d7afec89f6 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 11 Jul 2025 19:00:16 -0400 Subject: [PATCH 8/8] Fiux pays::yes tests --- pallets/subtensor/src/tests/staking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index c138dd5bd0..bb3654bf7b 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -42,7 +42,7 @@ fn test_add_stake_dispatch_info_ok() { call_weight: frame_support::weights::Weight::from_parts(2_495_500_000, 0), extension_weight: frame_support::weights::Weight::zero(), class: DispatchClass::Normal, - pays_fee: Pays::No + pays_fee: Pays::Yes } ); }); @@ -370,7 +370,7 @@ fn test_remove_stake_dispatch_info_ok() { .add_proof_size(0), extension_weight: frame_support::weights::Weight::zero(), class: DispatchClass::Normal, - pays_fee: Pays::No + pays_fee: Pays::Yes } ); });