From eb140b5e4a5797f38c8d22e2138a23b96efe077e Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 4 Sep 2025 21:40:07 +0800 Subject: [PATCH 1/8] apply subtoken enable to more extrinsic --- common/src/lib.rs | 1 + pallets/subtensor/src/lib.rs | 4 ++++ pallets/subtensor/src/staking/add_stake.rs | 2 ++ pallets/subtensor/src/staking/remove_stake.rs | 4 ++++ pallets/swap/src/pallet/mod.rs | 18 ++++++++++++++++++ 5 files changed, 29 insertions(+) diff --git a/common/src/lib.rs b/common/src/lib.rs index 67fe4be51b..82f0916894 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -174,6 +174,7 @@ pub trait SubnetInfo { fn exists(netuid: NetUid) -> bool; fn mechanism(netuid: NetUid) -> u16; fn is_owner(account_id: &AccountId, netuid: NetUid) -> bool; + fn is_subtoken_enabled(netuid: NetUid) -> bool; } pub trait BalanceOps { diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index ce4e41e357..1c62a21ae4 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2054,6 +2054,10 @@ impl> fn is_owner(account_id: &T::AccountId, netuid: NetUid) -> bool { SubnetOwner::::get(netuid) == *account_id } + + fn is_subtoken_enabled(netuid: NetUid) -> bool { + SubtokenEnabled::::get(netuid) + } } impl> diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index 740d42d09e..38e00fd93f 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -137,6 +137,8 @@ impl Pallet { "do_add_stake( origin:{coldkey:?} hotkey:{hotkey:?}, netuid:{netuid:?}, stake_to_be_added:{stake_to_be_added:?} )" ); + Self::ensure_subtoken_enabled(netuid)?; + // 2. Calculate the maximum amount that can be executed with price limit let max_amount: TaoCurrency = Self::get_max_amount_add(netuid, limit_price)?.into(); let mut possible_stake = stake_to_be_added; diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index fd9a974645..14ddf8641c 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -343,6 +343,8 @@ impl Pallet { "do_remove_stake( origin:{coldkey:?} hotkey:{hotkey:?}, netuid: {netuid:?}, alpha_unstaked:{alpha_unstaked:?} )" ); + Self::ensure_subtoken_enabled(netuid)?; + // 2. Calculate the maximum amount that can be executed with price limit let max_amount = Self::get_max_amount_remove(netuid, limit_price)?; let mut possible_alpha = alpha_unstaked; @@ -430,6 +432,8 @@ impl Pallet { ) -> DispatchResult { let coldkey = ensure_signed(origin.clone())?; + Self::ensure_subtoken_enabled(netuid)?; + let alpha_unstaked = Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); diff --git a/pallets/swap/src/pallet/mod.rs b/pallets/swap/src/pallet/mod.rs index 894099de7f..116908b401 100644 --- a/pallets/swap/src/pallet/mod.rs +++ b/pallets/swap/src/pallet/mod.rs @@ -269,6 +269,9 @@ mod pallet { /// User liquidity operations are disabled for this subnet UserLiquidityDisabled, + + /// The subnet does not have subtoken enabled + SubtokenDisabled, } #[pallet::call] @@ -366,6 +369,11 @@ mod pallet { Error::::SubNetworkDoesNotExist ); + ensure!( + T::SubnetInfo::is_subtoken_enabled(netuid.into()), + Error::::SubtokenDisabled + ); + let (position_id, tao, alpha) = Self::do_add_liquidity( netuid.into(), &coldkey, @@ -429,6 +437,11 @@ mod pallet { Error::::SubNetworkDoesNotExist ); + ensure!( + T::SubnetInfo::is_subtoken_enabled(netuid.into()), + Error::::SubtokenDisabled + ); + // Remove liquidity let result = Self::do_remove_liquidity(netuid, &coldkey, position_id)?; @@ -489,6 +502,11 @@ mod pallet { Error::::SubNetworkDoesNotExist ); + ensure!( + T::SubnetInfo::is_subtoken_enabled(netuid.into()), + Error::::SubtokenDisabled + ); + // Add or remove liquidity let result = Self::do_modify_position(netuid, &coldkey, &hotkey, position_id, liquidity_delta)?; From 701a5ebd5eddf9177e192ee68393b1ca68ea5884 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 4 Sep 2025 21:42:51 +0800 Subject: [PATCH 2/8] commit Cargo.lock --- pallets/swap/src/mock.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pallets/swap/src/mock.rs b/pallets/swap/src/mock.rs index 78a8f925c8..74f2a30633 100644 --- a/pallets/swap/src/mock.rs +++ b/pallets/swap/src/mock.rs @@ -115,6 +115,10 @@ impl SubnetInfo for MockLiquidityProvider { fn is_owner(account_id: &AccountId, _netuid: NetUid) -> bool { *account_id != NOT_SUBNET_OWNER } + + fn is_subtoken_enabled(_netuid: NetUid) -> bool { + true + } } pub struct MockBalanceOps; From 9d9ef8fef93ad1de1c5d1afa56c08dbb8994326d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Sep 2025 15:59:54 +0000 Subject: [PATCH 3/8] auto-update benchmark weights --- 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 c842709208..e592161e7d 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1682,7 +1682,7 @@ mod dispatches { /// #[pallet::call_index(89)] #[pallet::weight((Weight::from_parts(377_400_000, 0) - .saturating_add(T::DbWeight::get().reads(30)) + .saturating_add(T::DbWeight::get().reads(31_u64)) .saturating_add(T::DbWeight::get().writes(14)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_limit( origin: OriginFor, @@ -1906,7 +1906,7 @@ mod dispatches { /// Without limit_price it remove all the stake similar to `remove_stake` extrinsic #[pallet::call_index(103)] #[pallet::weight((Weight::from_parts(395_300_000, 10142) - .saturating_add(T::DbWeight::get().reads(30_u64)) + .saturating_add(T::DbWeight::get().reads(31_u64)) .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_full_limit( origin: T::RuntimeOrigin, @@ -2031,7 +2031,7 @@ mod dispatches { /// * commit_reveal_version (`u16`): /// - The client (bittensor-drand) version #[pallet::call_index(113)] - #[pallet::weight((Weight::from_parts(64_530_000, 0) + #[pallet::weight((Weight::from_parts(81_510_000, 0) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn commit_timelocked_weights( From 28b2f6fd6bbfecee1a849bed26185c50800e0442 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 5 Sep 2025 22:28:30 +0800 Subject: [PATCH 4/8] add more tests --- pallets/subtensor/src/staking/add_stake.rs | 2 - pallets/subtensor/src/staking/remove_stake.rs | 4 -- pallets/swap/src/mock.rs | 7 +-- pallets/swap/src/pallet/tests.rs | 47 +++++++++++++++++++ 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index 38e00fd93f..740d42d09e 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -137,8 +137,6 @@ impl Pallet { "do_add_stake( origin:{coldkey:?} hotkey:{hotkey:?}, netuid:{netuid:?}, stake_to_be_added:{stake_to_be_added:?} )" ); - Self::ensure_subtoken_enabled(netuid)?; - // 2. Calculate the maximum amount that can be executed with price limit let max_amount: TaoCurrency = Self::get_max_amount_add(netuid, limit_price)?.into(); let mut possible_stake = stake_to_be_added; diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 14ddf8641c..fd9a974645 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -343,8 +343,6 @@ impl Pallet { "do_remove_stake( origin:{coldkey:?} hotkey:{hotkey:?}, netuid: {netuid:?}, alpha_unstaked:{alpha_unstaked:?} )" ); - Self::ensure_subtoken_enabled(netuid)?; - // 2. Calculate the maximum amount that can be executed with price limit let max_amount = Self::get_max_amount_remove(netuid, limit_price)?; let mut possible_alpha = alpha_unstaked; @@ -432,8 +430,6 @@ impl Pallet { ) -> DispatchResult { let coldkey = ensure_signed(origin.clone())?; - Self::ensure_subtoken_enabled(netuid)?; - let alpha_unstaked = Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); diff --git a/pallets/swap/src/mock.rs b/pallets/swap/src/mock.rs index 74f2a30633..7a07cc7007 100644 --- a/pallets/swap/src/mock.rs +++ b/pallets/swap/src/mock.rs @@ -36,7 +36,7 @@ pub const OK_HOTKEY_ACCOUNT_ID_RICH: AccountId = 1005; pub const NOT_SUBNET_OWNER: AccountId = 666; pub const NON_EXISTENT_NETUID: u16 = 999; pub const WRAPPING_FEES_NETUID: u16 = 124; - +pub const SUBTOKEN_DISABLED_NETUID: u16 = 13579; parameter_types! { pub const BlockHashCount: u64 = 250; pub const SS58Prefix: u8 = 42; @@ -116,8 +116,9 @@ impl SubnetInfo for MockLiquidityProvider { *account_id != NOT_SUBNET_OWNER } - fn is_subtoken_enabled(_netuid: NetUid) -> bool { - true + // Only disable one subnet for testing + fn is_subtoken_enabled(netuid: NetUid) -> bool { + netuid.inner() != SUBTOKEN_DISABLED_NETUID } } diff --git a/pallets/swap/src/pallet/tests.rs b/pallets/swap/src/pallet/tests.rs index 845acd957a..6561e6b82b 100644 --- a/pallets/swap/src/pallet/tests.rs +++ b/pallets/swap/src/pallet/tests.rs @@ -1944,3 +1944,50 @@ fn test_less_price_movement() { }); }); } + +#[test] +fn test_swap_subtoken_disabled() { + new_test_ext().execute_with(|| { + let netuid = NetUid::from(SUBTOKEN_DISABLED_NETUID); // Use a netuid not used elsewhere + let price_low = 0.1; + let price_high = 0.2; + let tick_low = price_to_tick(price_low); + let tick_high = price_to_tick(price_high); + let liquidity = 1_000_000_u64; + + assert_ok!(Pallet::::maybe_initialize_v3(netuid)); + + assert_noop!( + Pallet::::add_liquidity( + RuntimeOrigin::signed(OK_COLDKEY_ACCOUNT_ID), + OK_HOTKEY_ACCOUNT_ID, + netuid, + tick_low, + tick_high, + liquidity, + ), + Error::::SubtokenDisabled + ); + + assert_noop!( + Pallet::::remove_liquidity( + RuntimeOrigin::signed(OK_COLDKEY_ACCOUNT_ID), + OK_HOTKEY_ACCOUNT_ID, + netuid, + PositionId::from(0), + ), + Error::::SubtokenDisabled + ); + + assert_noop!( + Pallet::::modify_position( + RuntimeOrigin::signed(OK_COLDKEY_ACCOUNT_ID), + OK_HOTKEY_ACCOUNT_ID, + netuid, + PositionId::from(0), + liquidity as i64, + ), + Error::::SubtokenDisabled + ); + }); +} From 841380ea571eae92c95ff88031ec8567601955bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 5 Sep 2025 16:29:44 +0000 Subject: [PATCH 5/8] auto-update benchmark weights --- pallets/subtensor/src/macros/dispatches.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index a00fb6cef0..136af3f74c 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1682,7 +1682,7 @@ mod dispatches { /// #[pallet::call_index(89)] #[pallet::weight((Weight::from_parts(377_400_000, 0) - .saturating_add(T::DbWeight::get().reads(31_u64)) + .saturating_add(T::DbWeight::get().reads(30_u64)) .saturating_add(T::DbWeight::get().writes(14)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_limit( origin: OriginFor, @@ -1906,7 +1906,7 @@ mod dispatches { /// Without limit_price it remove all the stake similar to `remove_stake` extrinsic #[pallet::call_index(103)] #[pallet::weight((Weight::from_parts(395_300_000, 10142) - .saturating_add(T::DbWeight::get().reads(31_u64)) + .saturating_add(T::DbWeight::get().reads(30_u64)) .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_full_limit( origin: T::RuntimeOrigin, From 416e504964d2087020fc4403051378d1185fbb0e Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 8 Sep 2025 09:45:01 +0800 Subject: [PATCH 6/8] bump 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 644a85ebcd..a25f23482b 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -220,7 +220,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: 310, + spec_version: 311, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 018f6cdd9ecad457362bd7c12aca7c41774fc4c8 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 8 Sep 2025 09:51:23 +0800 Subject: [PATCH 7/8] remove liquidity is allowed --- pallets/swap/src/pallet/mod.rs | 5 ----- pallets/swap/src/pallet/tests.rs | 10 ---------- 2 files changed, 15 deletions(-) diff --git a/pallets/swap/src/pallet/mod.rs b/pallets/swap/src/pallet/mod.rs index 116908b401..442c4852aa 100644 --- a/pallets/swap/src/pallet/mod.rs +++ b/pallets/swap/src/pallet/mod.rs @@ -437,11 +437,6 @@ mod pallet { Error::::SubNetworkDoesNotExist ); - ensure!( - T::SubnetInfo::is_subtoken_enabled(netuid.into()), - Error::::SubtokenDisabled - ); - // Remove liquidity let result = Self::do_remove_liquidity(netuid, &coldkey, position_id)?; diff --git a/pallets/swap/src/pallet/tests.rs b/pallets/swap/src/pallet/tests.rs index 6561e6b82b..396bd656be 100644 --- a/pallets/swap/src/pallet/tests.rs +++ b/pallets/swap/src/pallet/tests.rs @@ -1969,16 +1969,6 @@ fn test_swap_subtoken_disabled() { Error::::SubtokenDisabled ); - assert_noop!( - Pallet::::remove_liquidity( - RuntimeOrigin::signed(OK_COLDKEY_ACCOUNT_ID), - OK_HOTKEY_ACCOUNT_ID, - netuid, - PositionId::from(0), - ), - Error::::SubtokenDisabled - ); - assert_noop!( Pallet::::modify_position( RuntimeOrigin::signed(OK_COLDKEY_ACCOUNT_ID), From 481852c7808efab53aee52a69ef5e1a15f2dd9bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 8 Sep 2025 04:00:25 +0000 Subject: [PATCH 8/8] auto-update benchmark weights --- 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 5e0b3dc7b5..ad7b9fb107 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -761,7 +761,7 @@ mod dispatches { /// Attempt to adjust the senate membership to include a hotkey #[pallet::call_index(63)] - #[pallet::weight((Weight::from_parts(75_430_000, 0) + #[pallet::weight((Weight::from_parts(58_980_000, 0) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)), DispatchClass::Normal, Pays::Yes))] pub fn adjust_senate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult {