Skip to content
2 changes: 1 addition & 1 deletion pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1714,7 +1714,7 @@ pub mod pallet {
}

/// Ensure subtoken enalbed
pub fn ensure_subtoken_enabled(subnet: u16) -> DispatchResult {
pub fn ensure_subtoken_enabled(subnet: u16) -> Result<(), Error<T>> {
ensure!(
SubtokenEnabled::<T>::get(subnet),
Error::<T>::SubtokenDisabled
Expand Down
12 changes: 6 additions & 6 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,11 +551,11 @@ mod dispatches {
Self::do_increase_take(origin, hotkey, take)
}

/// --- Adds stake to a hotkey. The call is made from the
/// coldkey account linked in the hotkey.
/// Only the associated coldkey is allowed to make staking and
/// unstaking requests. This protects the neuron against
/// attacks on its hotkey running in production code.
/// --- Adds stake to a hotkey. The call is made from a coldkey account.
/// This delegates stake to the hotkey.
///
/// Note: the coldkey account may own the hotkey, in which case they are
/// delegating to themselves.
///
/// # Args:
/// * 'origin': (<T as frame_system::Config>Origin):
Expand Down Expand Up @@ -1786,7 +1786,7 @@ mod dispatches {
///
#[pallet::call_index(88)]
#[pallet::weight((Weight::from_parts(159_200_000, 0)
.saturating_add(T::DbWeight::get().reads(13))
.saturating_add(T::DbWeight::get().reads(14))
.saturating_add(T::DbWeight::get().writes(10)), DispatchClass::Normal, Pays::No))]
pub fn add_stake_limit(
origin: OriginFor<T>,
Expand Down
6 changes: 6 additions & 0 deletions pallets/subtensor/src/staking/stake_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,9 @@ impl<T: Config> Pallet<T> {
// Ensure that the subnet exists.
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);

// Ensure that the subnet is enabled.
Self::ensure_subtoken_enabled(netuid)?;

// Get the minimum balance (and amount) that satisfies the transaction
let min_amount = DefaultMinStake::<T>::get().saturating_add(DefaultStakingFee::<T>::get());

Expand Down Expand Up @@ -962,6 +965,9 @@ impl<T: Config> Pallet<T> {
// Ensure that the subnet exists.
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);

// Ensure that the subnet is enabled.
// Self::ensure_subtoken_enabled(netuid)?;

// Ensure that the stake amount to be removed is above the minimum in tao equivalent.
if let Some(tao_equivalent) = Self::sim_swap_alpha_for_tao(netuid, alpha_unstaked) {
ensure!(
Expand Down
81 changes: 80 additions & 1 deletion pallets/subtensor/src/tests/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ fn test_subtoken_enable() {
});
}

// cargo test --package pallet-subtensor --lib -- tests::subnet::test_subtoken_enable_reject_trading_before_enable --exact --show-output
// cargo test --package pallet-subtensor --lib --
// tests::subnet::test_subtoken_enable_reject_trading_before_enable --exact --show-output
#[allow(clippy::unwrap_used)]
#[test]
fn test_subtoken_enable_reject_trading_before_enable() {
// ensure_subtoken_enabled
Expand All @@ -251,9 +253,20 @@ fn test_subtoken_enable_reject_trading_before_enable() {
let hotkey_account_2_id: U256 = U256::from(3);
let amount = DefaultMinStake::<Test>::get() * 10;

let stake_bal = 10_000_000_000; // 10 Alpha

let limit_price = 1_000_000_000; // not important

add_network_disable_subtoken(netuid, 10, 0);
add_network_disable_subtoken(netuid2, 10, 0);

assert!(!SubtokenEnabled::<Test>::get(netuid));
assert!(!SubtokenEnabled::<Test>::get(netuid2));

// Set liq high enough to not trigger other errors
SubnetTAO::<Test>::set(netuid, 20_000_000_000);
SubnetAlphaIn::<Test>::set(netuid, 20_000_000_000);

// Register so staking *could* work
register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 0);
register_ok_neuron(netuid2, hotkey_account_id, coldkey_account_id, 100);
Expand All @@ -262,6 +275,14 @@ fn test_subtoken_enable_reject_trading_before_enable() {

SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10_000);

// Give some stake
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_account_id,
&coldkey_account_id,
netuid,
stake_bal,
);

// all trading extrinsic should be rejected.
assert_noop!(
SubtensorModule::add_stake(
Expand All @@ -273,6 +294,64 @@ fn test_subtoken_enable_reject_trading_before_enable() {
Error::<Test>::SubtokenDisabled
);

assert_noop!(
SubtensorModule::add_stake_limit(
RuntimeOrigin::signed(coldkey_account_id),
hotkey_account_id,
netuid,
amount,
limit_price,
false
),
Error::<Test>::SubtokenDisabled
);

// For unstake_all and unstake_all_alpha, the result is Ok, but the
// operation is not performed.
assert_ok!(
SubtensorModule::unstake_all(
RuntimeOrigin::signed(coldkey_account_id),
hotkey_account_id
),
()
);
// Check that the stake is still the same
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_account_id,
&coldkey_account_id,
netuid
),
stake_bal
);

assert_ok!(
SubtensorModule::unstake_all_alpha(
RuntimeOrigin::signed(coldkey_account_id),
hotkey_account_id
),
()
);
// Check that the stake is still the same
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_account_id,
&coldkey_account_id,
netuid
),
stake_bal
);

SubtensorModule::remove_stake_limit(
RuntimeOrigin::signed(coldkey_account_id),
hotkey_account_id,
netuid,
amount,
limit_price,
false,
)
.unwrap();

assert_noop!(
SubtensorModule::remove_stake(
RuntimeOrigin::signed(coldkey_account_id),
Expand Down
Loading