Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
46164e8
High level architecture for palswap in place, everything compiles
gztensor Dec 15, 2025
48866a9
Merge branch 'devnet-ready' into feat/balancer_swap
gztensor Dec 15, 2025
c9aedf6
Use Sam's bigmath crate for exponentiation
gztensor Dec 17, 2025
1bc3092
Adjust fuzzy epsilon
gztensor Dec 17, 2025
81eab8e
Use rayon for fuzzy testing
gztensor Dec 17, 2025
8bdafa7
Cleanup full vs limited range testing
gztensor Dec 17, 2025
b91ca21
Update bigmath, debug current_price, implement adjust_protocol_liquid…
gztensor Dec 18, 2025
f3daa79
Implement delta_in and tests
gztensor Dec 18, 2025
ef71b3c
Merge devnet-ready
gztensor Dec 18, 2025
0fe9842
Update bigmath, add testcases
gztensor Dec 19, 2025
921ace4
Merge branch 'devnet-ready' into feat/balancer_swap
gztensor Dec 22, 2025
9292044
Basic swap works
gztensor Dec 22, 2025
30be6ea
Swap tests in progress
gztensor Dec 22, 2025
22019e3
Fix test_clear_protocol_liquidity_green_path
gztensor Dec 23, 2025
9c9b646
Fix test_claim_root_with_run_coinbase
gztensor Dec 23, 2025
a27f1b5
Add swap initialization to interface
gztensor Dec 23, 2025
afa0d45
Fix test_coinbase_subnet_terms_with_alpha_in_gt_alpha_emission
gztensor Dec 24, 2025
243df1e
Fix test_mining_emission_distribution_with_no_root_sell
gztensor Dec 24, 2025
d2f9e2b
Fix test_mining_emission_distribution_with_root_sell
gztensor Dec 24, 2025
96402fd
Fix test_pending_emission_start_call_not_done
gztensor Dec 24, 2025
6c55c7b
Remove non-zero delta-out requirement for zero delta-in. Fix test_mig…
gztensor Dec 24, 2025
b8d5ffe
Fix test_add_stake_insufficient_liquidity_one_side_ok
gztensor Dec 26, 2025
1c663f1
Fix dissolve_clears_all_per_subnet_storages
gztensor Dec 26, 2025
25a9e5d
Fix test_large_swap, improve error messaging
gztensor Dec 26, 2025
213a984
Fix test_add_stake_limit_fill_or_kill
gztensor Dec 26, 2025
b755f0e
Fix test_max_amount_add_dynamic
gztensor Dec 26, 2025
26cca0b
Fix test_max_amount_move_dynamic_dynamic
gztensor Dec 26, 2025
7c51712
Re-enable balancer math test cases
gztensor Dec 26, 2025
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
231 changes: 221 additions & 10 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pallet-subtensor-swap-runtime-api = { path = "pallets/swap/runtime-api", default
pallet-subtensor-swap-rpc = { path = "pallets/swap/rpc", default-features = false }
procedural-fork = { path = "support/procedural-fork", default-features = false }
safe-math = { path = "primitives/safe-math", default-features = false }
safe-bigmath = { package = "safe-bigmath", git = "https://github.com/sam0x17/safe-math", rev = "fd8e816", default-features = false }
share-pool = { path = "primitives/share-pool", default-features = false }
subtensor-macros = { path = "support/macros", default-features = false }
subtensor-custom-rpc = { default-features = false, path = "pallets/subtensor/rpc" }
Expand Down
4 changes: 2 additions & 2 deletions chain-extensions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use pallet_subtensor_proxy as pallet_proxy;
use pallet_subtensor_proxy::WeightInfo;
use sp_runtime::{DispatchError, Weight, traits::StaticLookup};
use sp_std::marker::PhantomData;
use substrate_fixed::types::U96F32;
use substrate_fixed::types::U64F64;
use subtensor_runtime_common::{AlphaCurrency, NetUid, ProxyType, TaoCurrency};
use subtensor_swap_interface::SwapHandler;

Expand Down Expand Up @@ -520,7 +520,7 @@ where
netuid.into(),
);

let price = current_alpha_price.saturating_mul(U96F32::from_num(1_000_000_000));
let price = current_alpha_price.saturating_mul(U64F64::from_num(1_000_000_000));
let price: u64 = price.saturating_to_num();

let encoded_result = price.encode();
Expand Down
4 changes: 2 additions & 2 deletions chain-extensions/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use pallet_subtensor::DefaultMinStake;
use sp_core::Get;
use sp_core::U256;
use sp_runtime::DispatchError;
use substrate_fixed::types::U96F32;
use substrate_fixed::types::U64F64;
use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyTrait, NetUid, TaoCurrency};
use subtensor_swap_interface::SwapHandler;

Expand Down Expand Up @@ -985,7 +985,7 @@ fn get_alpha_price_returns_encoded_price() {
<pallet_subtensor_swap::Pallet<mock::Test> as SwapHandler>::current_alpha_price(
netuid.into(),
);
let expected_price_scaled = expected_price.saturating_mul(U96F32::from_num(1_000_000_000));
let expected_price_scaled = expected_price.saturating_mul(U64F64::from_num(1_000_000_000));
let expected_price_u64: u64 = expected_price_scaled.saturating_to_num();

let mut env = MockEnv::new(FunctionId::GetAlphaPriceV1, caller, netuid.encode());
Expand Down
18 changes: 9 additions & 9 deletions pallets/subtensor/src/coinbase/block_emission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use frame_support::traits::Get;
use safe_math::*;
use substrate_fixed::{
transcendental::log2,
types::{I96F32, U96F32},
types::{I96F32, U64F64},
};
use subtensor_runtime_common::{NetUid, TaoCurrency};
use subtensor_swap_interface::SwapHandler;
Expand Down Expand Up @@ -36,15 +36,15 @@ impl<T: Config> Pallet<T> {
alpha_block_emission: u64,
) -> (u64, u64, u64) {
// Init terms.
let mut tao_in_emission: U96F32 = U96F32::saturating_from_num(tao_emission);
let float_alpha_block_emission: U96F32 = U96F32::saturating_from_num(alpha_block_emission);
let mut tao_in_emission: U64F64 = U64F64::saturating_from_num(tao_emission);
let float_alpha_block_emission: U64F64 = U64F64::saturating_from_num(alpha_block_emission);

// Get alpha price for subnet.
let alpha_price = T::SwapInterface::current_alpha_price(netuid.into());
log::debug!("{netuid:?} - alpha_price: {alpha_price:?}");

// Get initial alpha_in
let mut alpha_in_emission: U96F32 = U96F32::saturating_from_num(tao_emission)
let mut alpha_in_emission: U64F64 = U64F64::saturating_from_num(tao_emission)
.checked_div(alpha_price)
.unwrap_or(float_alpha_block_emission);

Expand All @@ -62,11 +62,11 @@ impl<T: Config> Pallet<T> {
}

// Avoid rounding errors.
if tao_in_emission < U96F32::saturating_from_num(1)
|| alpha_in_emission < U96F32::saturating_from_num(1)
{
alpha_in_emission = U96F32::saturating_from_num(0);
tao_in_emission = U96F32::saturating_from_num(0);
let zero = U64F64::saturating_from_num(0);
let one = U64F64::saturating_from_num(1);
if tao_in_emission < one || alpha_in_emission < one {
alpha_in_emission = zero;
tao_in_emission = zero;
}

// Set Alpha in emission.
Expand Down
3 changes: 2 additions & 1 deletion pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ impl<T: Config> Pallet<T> {
log::debug!("alpha_emission_i: {alpha_emission_i:?}");

// Get subnet price.
let price_i: U96F32 = T::SwapInterface::current_alpha_price(netuid_i.into());
let price_i: U96F32 =
U96F32::saturating_from_num(T::SwapInterface::current_alpha_price(netuid_i.into()));
log::debug!("price_i: {price_i:?}");

let mut tao_in_i: U96F32 = tao_emission_i;
Expand Down
14 changes: 6 additions & 8 deletions pallets/subtensor/src/staking/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use frame_support::traits::{
},
};
use safe_math::*;
use substrate_fixed::types::U96F32;
use substrate_fixed::types::{U64F64, U96F32};
use subtensor_runtime_common::{NetUid, TaoCurrency};
use subtensor_swap_interface::{Order, SwapHandler};

Expand Down Expand Up @@ -48,15 +48,13 @@ impl<T: Config> Pallet<T> {
Self::get_all_subnet_netuids()
.into_iter()
.map(|netuid| {
let alpha = U96F32::saturating_from_num(Self::get_stake_for_hotkey_on_subnet(
let alpha = U64F64::saturating_from_num(Self::get_stake_for_hotkey_on_subnet(
hotkey, netuid,
));
let alpha_price = U96F32::saturating_from_num(
T::SwapInterface::current_alpha_price(netuid.into()),
);
let alpha_price = T::SwapInterface::current_alpha_price(netuid.into());
alpha.saturating_mul(alpha_price)
})
.sum::<U96F32>()
.sum::<U64F64>()
.saturating_to_num::<u64>()
.into()
}
Expand All @@ -76,7 +74,7 @@ impl<T: Config> Pallet<T> {
let order = GetTaoForAlpha::<T>::with_amount(alpha_stake);
T::SwapInterface::sim_swap(netuid.into(), order)
.map(|r| {
let fee: u64 = U96F32::saturating_from_num(r.fee_paid)
let fee: u64 = U64F64::saturating_from_num(r.fee_paid)
.saturating_mul(T::SwapInterface::current_alpha_price(
netuid.into(),
))
Expand Down Expand Up @@ -186,7 +184,7 @@ impl<T: Config> Pallet<T> {
let alpha_stake =
Self::get_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid);
let min_alpha_stake =
U96F32::saturating_from_num(Self::get_nominator_min_required_stake())
U64F64::saturating_from_num(Self::get_nominator_min_required_stake())
.safe_div(T::SwapInterface::current_alpha_price(netuid))
.saturating_to_num::<u64>();
if alpha_stake > 0.into() && alpha_stake < min_alpha_stake.into() {
Expand Down
4 changes: 3 additions & 1 deletion pallets/subtensor/src/staking/remove_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,9 @@ impl<T: Config> Pallet<T> {
.saturating_to_num::<u64>();

owner_emission_tao = if owner_alpha_u64 > 0 {
let cur_price: U96F32 = T::SwapInterface::current_alpha_price(netuid.into());
let cur_price: U96F32 = U96F32::saturating_from_num(
T::SwapInterface::current_alpha_price(netuid.into()),
);
let val_u64 = U96F32::from_num(owner_alpha_u64)
.saturating_mul(cur_price)
.floor()
Expand Down
40 changes: 26 additions & 14 deletions pallets/subtensor/src/staking/stake_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ impl<T: Config> Pallet<T> {
// Because alpha = b / (b + h), where b and h > 0, alpha < 1, so 1 - alpha > 0.
// We can use unsigned type here: U96F32
let one_minus_alpha: U96F32 = U96F32::saturating_from_num(1.0).saturating_sub(alpha);
let current_price: U96F32 = alpha.saturating_mul(
let current_price: U96F32 = alpha.saturating_mul(U96F32::saturating_from_num(
T::SwapInterface::current_alpha_price(netuid.into())
.min(U96F32::saturating_from_num(1.0)),
);
.min(U64F64::saturating_from_num(1.0)),
));
let current_moving: U96F32 =
one_minus_alpha.saturating_mul(Self::get_moving_alpha_price(netuid));
// Convert batch to signed I96F32 to avoid migration of SubnetMovingPrice for now``
Expand Down Expand Up @@ -876,7 +876,7 @@ impl<T: Config> Pallet<T> {
let current_price =
<T as pallet::Config>::SwapInterface::current_alpha_price(netuid.into());
let tao_equivalent: TaoCurrency = current_price
.saturating_mul(U96F32::saturating_from_num(actual_alpha_moved))
.saturating_mul(U64F64::saturating_from_num(actual_alpha_moved))
.saturating_to_num::<u64>()
.into();

Expand Down Expand Up @@ -1205,9 +1205,11 @@ impl<T: Config> Pallet<T> {
}

pub fn increase_provided_tao_reserve(netuid: NetUid, tao: TaoCurrency) {
SubnetTaoProvided::<T>::mutate(netuid, |total| {
*total = total.saturating_add(tao);
});
if !tao.is_zero() {
SubnetTaoProvided::<T>::mutate(netuid, |total| {
*total = total.saturating_add(tao);
});
}
}

pub fn decrease_provided_tao_reserve(netuid: NetUid, tao: TaoCurrency) {
Expand All @@ -1217,17 +1219,23 @@ impl<T: Config> Pallet<T> {
let remainder = subnet_tao_provided.saturating_sub(tao);
let carry_over = tao.saturating_sub(subnet_tao_provided);
if carry_over.is_zero() {
SubnetTaoProvided::<T>::set(netuid, remainder);
if remainder.is_zero() {
SubnetTaoProvided::<T>::remove(netuid);
} else {
SubnetTaoProvided::<T>::set(netuid, remainder);
}
} else {
SubnetTaoProvided::<T>::set(netuid, TaoCurrency::ZERO);
SubnetTaoProvided::<T>::remove(netuid);
SubnetTAO::<T>::set(netuid, subnet_tao.saturating_sub(carry_over));
}
}

pub fn increase_provided_alpha_reserve(netuid: NetUid, alpha: AlphaCurrency) {
SubnetAlphaInProvided::<T>::mutate(netuid, |total| {
*total = total.saturating_add(alpha);
});
if !alpha.is_zero() {
SubnetAlphaInProvided::<T>::mutate(netuid, |total| {
*total = total.saturating_add(alpha);
});
}
}

pub fn decrease_provided_alpha_reserve(netuid: NetUid, alpha: AlphaCurrency) {
Expand All @@ -1237,9 +1245,13 @@ impl<T: Config> Pallet<T> {
let remainder = subnet_alpha_provided.saturating_sub(alpha);
let carry_over = alpha.saturating_sub(subnet_alpha_provided);
if carry_over.is_zero() {
SubnetAlphaInProvided::<T>::set(netuid, remainder);
if remainder.is_zero() {
SubnetAlphaInProvided::<T>::remove(netuid);
} else {
SubnetAlphaInProvided::<T>::set(netuid, remainder);
}
} else {
SubnetAlphaInProvided::<T>::set(netuid, AlphaCurrency::ZERO);
SubnetAlphaInProvided::<T>::remove(netuid);
SubnetAlphaIn::<T>::set(netuid, subnet_alpha.saturating_sub(carry_over));
}
}
Expand Down
Loading
Loading