Skip to content

Commit 7ca0a02

Browse files
authored
Merge pull request #1211 from opentensor/fix/k-precision
Change type for pool k to I110F18
2 parents ed6ba75 + fd77135 commit 7ca0a02

File tree

2 files changed

+53
-15
lines changed

2 files changed

+53
-15
lines changed

pallets/subtensor/src/staking/stake_utils.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::*;
22
use safe_math::*;
33
use share_pool::{SharePool, SharePoolDataOperations};
44
use sp_std::ops::Neg;
5-
use substrate_fixed::types::{I64F64, I96F32, U64F64};
5+
use substrate_fixed::types::{I110F18, I64F64, I96F32, U64F64};
66

77
impl<T: Config> Pallet<T> {
88
/// Retrieves the total alpha issuance for a given subnet.
@@ -469,16 +469,15 @@ impl<T: Config> Pallet<T> {
469469
// Step 2: Initialized vars.
470470
if mechanism_id == 1 {
471471
// Step 3.a.1: Dynamic mechanism calculations
472-
let tao_reserves: I96F32 = I96F32::saturating_from_num(SubnetTAO::<T>::get(netuid));
473-
let alpha_reserves: I96F32 =
474-
I96F32::saturating_from_num(SubnetAlphaIn::<T>::get(netuid));
472+
let tao_reserves: I110F18 = I110F18::saturating_from_num(SubnetTAO::<T>::get(netuid));
473+
let alpha_reserves: I110F18 =
474+
I110F18::saturating_from_num(SubnetAlphaIn::<T>::get(netuid));
475475
// Step 3.a.2: Compute constant product k = alpha * tao
476-
let k: I96F32 = alpha_reserves.saturating_mul(tao_reserves);
476+
let k: I110F18 = alpha_reserves.saturating_mul(tao_reserves);
477477

478478
// Calculate new alpha reserve
479-
let new_alpha_reserves: I96F32 = k
480-
.checked_div(tao_reserves.saturating_add(I96F32::saturating_from_num(tao)))
481-
.unwrap_or(I96F32::saturating_from_num(0));
479+
let new_alpha_reserves: I110F18 =
480+
k.safe_div(tao_reserves.saturating_add(I110F18::saturating_from_num(tao)));
482481

483482
// Step 3.a.3: Calculate alpha staked using the constant product formula
484483
// alpha_stake_recieved = current_alpha - (k / (current_tao + new_tao))
@@ -509,16 +508,16 @@ impl<T: Config> Pallet<T> {
509508
// Step 2: Swap alpha and attain tao
510509
if mechanism_id == 1 {
511510
// Step 3.a.1: Dynamic mechanism calculations
512-
let tao_reserves: I96F32 = I96F32::saturating_from_num(SubnetTAO::<T>::get(netuid));
513-
let alpha_reserves: I96F32 =
514-
I96F32::saturating_from_num(SubnetAlphaIn::<T>::get(netuid));
511+
let tao_reserves: I110F18 = I110F18::saturating_from_num(SubnetTAO::<T>::get(netuid));
512+
let alpha_reserves: I110F18 =
513+
I110F18::saturating_from_num(SubnetAlphaIn::<T>::get(netuid));
515514
// Step 3.a.2: Compute constant product k = alpha * tao
516-
let k: I96F32 = alpha_reserves.saturating_mul(tao_reserves);
515+
let k: I110F18 = alpha_reserves.saturating_mul(tao_reserves);
517516

518517
// Calculate new tao reserve
519-
let new_tao_reserves: I96F32 = k
520-
.checked_div(alpha_reserves.saturating_add(I96F32::saturating_from_num(alpha)))
521-
.unwrap_or(I96F32::saturating_from_num(0));
518+
let new_tao_reserves: I110F18 = k
519+
.checked_div(alpha_reserves.saturating_add(I110F18::saturating_from_num(alpha)))
520+
.unwrap_or(I110F18::saturating_from_num(0));
522521

523522
// Step 3.a.3: Calculate alpha staked using the constant product formula
524523
// tao_recieved = tao_reserves - (k / (alpha_reserves + new_tao))

pallets/subtensor/src/tests/staking.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,3 +2309,42 @@ fn test_unstake_low_liquidity_validate() {
23092309
);
23102310
});
23112311
}
2312+
2313+
#[test]
2314+
fn test_stake_oveflow() {
2315+
new_test_ext(1).execute_with(|| {
2316+
let subnet_owner_coldkey = U256::from(1001);
2317+
let subnet_owner_hotkey = U256::from(1002);
2318+
let coldkey_account_id = U256::from(435445);
2319+
let hotkey_account_id = U256::from(54544);
2320+
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);
2321+
let amount = 21_000_000_000_000_000; // Max TAO supply
2322+
let fee = DefaultStakingFee::<Test>::get();
2323+
register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123);
2324+
2325+
// Give it some $$$ in his coldkey balance
2326+
SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount);
2327+
2328+
// Setup liquidity with 21M TAO values
2329+
SubnetTAO::<Test>::insert(netuid, amount);
2330+
SubnetAlphaIn::<Test>::insert(netuid, amount);
2331+
2332+
// Stake and check if the result is ok
2333+
assert_ok!(SubtensorModule::add_stake(
2334+
RuntimeOrigin::signed(coldkey_account_id),
2335+
hotkey_account_id,
2336+
netuid,
2337+
amount
2338+
));
2339+
2340+
// Check if stake has increased properly (staking 1:1 to SubnetTAO results in SubnetTAO/2 alpha)
2341+
assert_abs_diff_eq!(
2342+
SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey_account_id, netuid),
2343+
(amount - fee) / 2,
2344+
epsilon = amount / 1_000_000,
2345+
);
2346+
2347+
// Check if total stake has increased accordingly.
2348+
assert_abs_diff_eq!(SubtensorModule::get_total_stake(), amount, epsilon = 10,);
2349+
});
2350+
}

0 commit comments

Comments
 (0)