Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 0 additions & 9 deletions pallets/subtensor/src/staking/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,15 +303,6 @@ impl<T: Config> Pallet<T> {
maybe_allow_partial: Option<bool>,
check_transfer_toggle: bool,
) -> Result<TaoBalance, DispatchError> {
// Cap the alpha_amount at available Alpha because user might be paying transaxtion fees
// in Alpha and their total is already reduced by now.
let alpha_available = Self::get_stake_for_hotkey_and_coldkey_on_subnet(
origin_hotkey,
origin_coldkey,
origin_netuid,
);
let alpha_amount = alpha_amount.min(alpha_available);

// Calculate the maximum amount that can be executed
let max_amount = if origin_netuid != destination_netuid {
if let Some(limit_price) = maybe_limit_price {
Expand Down
46 changes: 37 additions & 9 deletions pallets/subtensor/src/tests/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,17 +1023,45 @@ fn test_do_transfer_insufficient_stake() {
)
.unwrap();

// Amount over available stake succeeds (because fees can be paid in Alpha,
// this limitation is removed)
let alpha = stake_amount * 2;
assert_ok!(SubtensorModule::do_transfer_stake(
RuntimeOrigin::signed(origin_coldkey),
destination_coldkey,
hotkey,
let origin_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&origin_coldkey,
netuid,
);
let destination_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&destination_coldkey,
netuid,
alpha.into()
));
);

let alpha = stake_amount * 2;
assert_noop!(
SubtensorModule::do_transfer_stake(
RuntimeOrigin::signed(origin_coldkey),
destination_coldkey,
hotkey,
netuid,
netuid,
alpha.into()
),
Error::<Test>::NotEnoughStakeToWithdraw
);
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&origin_coldkey,
netuid
),
origin_alpha_before
);
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&destination_coldkey,
netuid
),
destination_alpha_before
);
});
}

Expand Down
130 changes: 130 additions & 0 deletions pallets/transaction-fee/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use sp_runtime::{
transaction_validity::{InvalidTransaction, TransactionValidityError},
};
use subtensor_runtime_common::AlphaBalance;
use subtensor_swap_interface::SwapHandler;

use mock::*;
mod mock;
Expand Down Expand Up @@ -1258,6 +1259,135 @@ fn test_transfer_stake_fees_alpha() {
});
}

// cargo test --package subtensor-transaction-fee --lib -- tests::test_transfer_stake_full_amount_fails_when_alpha_fee_reduces_available_stake --exact --show-output
#[test]
fn test_transfer_stake_full_amount_fails_when_alpha_fee_reduces_available_stake() {
new_test_ext().execute_with(|| {
let destination_coldkey = U256::from(100000);
let stake_amount = TAO;
let sn = setup_subnets(2, 2);
setup_stake(
sn.subnets[0].netuid,
&sn.coldkey,
&sn.hotkeys[0],
stake_amount,
);

let current_balance = Balances::free_balance(sn.coldkey);
remove_balance_from_coldkey_account(&sn.coldkey, current_balance);
assert_eq!(Balances::free_balance(sn.coldkey), TaoBalance::ZERO);

let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&sn.hotkeys[0],
&sn.coldkey,
sn.subnets[0].netuid,
);
let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake {
destination_coldkey,
hotkey: sn.hotkeys[0],
origin_netuid: sn.subnets[0].netuid,
destination_netuid: sn.subnets[1].netuid,
alpha_amount: alpha_before,
});
let info = call.get_dispatch_info();
let ext = pallet_transaction_payment::ChargeTransactionPayment::<Test>::from(0.into());

let inner = ext
.dispatch_transaction(RuntimeOrigin::signed(sn.coldkey).into(), call, &info, 0, 0)
.expect("alpha fee payment should validate");
assert_eq!(
inner.unwrap_err().error,
Error::<Test>::NotEnoughStakeToWithdraw.into()
);

let alpha_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&sn.hotkeys[0],
&sn.coldkey,
sn.subnets[0].netuid,
);
let actual_alpha_fee = alpha_before - alpha_after;
assert!(actual_alpha_fee > AlphaBalance::ZERO);
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&sn.hotkeys[0],
&destination_coldkey,
sn.subnets[1].netuid,
),
AlphaBalance::ZERO
);
});

new_test_ext().execute_with(|| {
let destination_coldkey = U256::from(100000);
let stake_amount = TAO;
let sn = setup_subnets(2, 2);
setup_stake(
sn.subnets[0].netuid,
&sn.coldkey,
&sn.hotkeys[0],
stake_amount,
);

let current_balance = Balances::free_balance(sn.coldkey);
remove_balance_from_coldkey_account(&sn.coldkey, current_balance);
assert_eq!(Balances::free_balance(sn.coldkey), TaoBalance::ZERO);

let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&sn.hotkeys[0],
&sn.coldkey,
sn.subnets[0].netuid,
);
let full_amount_call =
RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake {
destination_coldkey,
hotkey: sn.hotkeys[0],
origin_netuid: sn.subnets[0].netuid,
destination_netuid: sn.subnets[1].netuid,
alpha_amount: alpha_before,
});
let info = full_amount_call.get_dispatch_info();
let tao_fee = pallet_transaction_payment::Pallet::<Test>::compute_fee(0, &info, 0.into());
let alpha_fee = pallet_subtensor_swap::Pallet::<Test>::get_alpha_amount_for_tao(
sn.subnets[0].netuid,
tao_fee,
);
assert!(alpha_fee > AlphaBalance::ZERO);

let transfer_amount = alpha_before - alpha_fee;
let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake {
destination_coldkey,
hotkey: sn.hotkeys[0],
origin_netuid: sn.subnets[0].netuid,
destination_netuid: sn.subnets[1].netuid,
alpha_amount: transfer_amount,
});
let info = call.get_dispatch_info();
let ext = pallet_transaction_payment::ChargeTransactionPayment::<Test>::from(0.into());

let inner = ext
.dispatch_transaction(RuntimeOrigin::signed(sn.coldkey).into(), call, &info, 0, 0)
.expect("alpha fee payment should validate");
assert_ok!(inner);

assert_eq!(Balances::free_balance(sn.coldkey), TaoBalance::ZERO);
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&sn.hotkeys[0],
&sn.coldkey,
sn.subnets[0].netuid,
),
AlphaBalance::ZERO
);
assert!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&sn.hotkeys[0],
&destination_coldkey,
sn.subnets[1].netuid,
) > AlphaBalance::ZERO
);
});
}

// cargo test --package subtensor-transaction-fee --lib -- tests::test_swap_stake_fees_alpha --exact --show-output
#[test]
fn test_swap_stake_fees_alpha() {
Expand Down
Loading