1
1
use super :: * ;
2
- use safe_math:: * ;
3
2
use sp_core:: Get ;
4
- use substrate_fixed:: types:: U96F32 ;
5
3
6
4
impl < T : Config > Pallet < T > {
7
5
/// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey.
@@ -343,14 +341,14 @@ impl<T: Config> Pallet<T> {
343
341
if alpha_in == 0 {
344
342
return 0 ;
345
343
}
346
- let alpha_in_float : U96F32 = U96F32 :: saturating_from_num ( alpha_in) ;
344
+ let alpha_in_u128 = alpha_in as u128 ;
347
345
348
346
// Corner case: SubnetTAO is zero. Staking can't happen, so max amount is zero.
349
347
let tao_reserve = SubnetTAO :: < T > :: get ( netuid) ;
350
348
if tao_reserve == 0 {
351
349
return 0 ;
352
350
}
353
- let tao_reserve_float : U96F32 = U96F32 :: saturating_from_num ( tao_reserve) ;
351
+ let tao_reserve_u128 = tao_reserve as u128 ;
354
352
355
353
// Corner case: limit_price == 0 (because there's division by limit price)
356
354
// => can sell all
@@ -359,25 +357,32 @@ impl<T: Config> Pallet<T> {
359
357
}
360
358
361
359
// Corner case: limit_price >= current_price (price cannot increase with unstaking)
362
- let limit_price_float: U96F32 = U96F32 :: saturating_from_num ( limit_price)
363
- . checked_div ( U96F32 :: saturating_from_num ( 1_000_000_000 ) )
364
- . unwrap_or ( U96F32 :: saturating_from_num ( 0 ) ) ;
365
- if limit_price_float >= Self :: get_alpha_price ( netuid) {
360
+ // No overflows: alpha_price * tao <= u64::MAX * u64::MAX
361
+ // Alpha price is U96F32 size, but it is calculated as u64/u64, so it never uses all 96 bits.
362
+ let limit_price_u128 = limit_price as u128 ;
363
+ let tao = 1_000_000_000_u128 ;
364
+ if limit_price_u128
365
+ >= tao_reserve_u128
366
+ . saturating_mul ( tao)
367
+ . checked_div ( alpha_in_u128)
368
+ . unwrap_or ( 0 )
369
+ {
366
370
return 0 ;
367
371
}
368
372
369
- // Main case: return SQRT(SubnetTAO * SubnetAlphaIn / limit_price) - SubnetAlphaIn
370
- // This is the positive solution of quare equation for finding Alpha amount from
371
- // limit_price.
372
- let zero: U96F32 = U96F32 :: saturating_from_num ( 0.0 ) ;
373
- let epsilon: U96F32 = U96F32 :: saturating_from_num ( 0.1 ) ;
374
- let sqrt: U96F32 = checked_sqrt ( tao_reserve_float, epsilon)
375
- . unwrap_or ( zero)
376
- . saturating_mul (
377
- checked_sqrt ( alpha_in_float. safe_div ( limit_price_float) , epsilon) . unwrap_or ( zero) ,
378
- ) ;
379
-
380
- sqrt. saturating_sub ( U96F32 :: saturating_from_num ( alpha_in_float) )
381
- . saturating_to_num :: < u64 > ( )
373
+ // Main case: SubnetTAO / limit_price - SubnetAlphaIn
374
+ // Non overflowing calculation: tao_reserve * tao <= u64::MAX * u64::MAX <= u128::MAX
375
+ // May overflow result, then it will be capped at u64::MAX, which is OK because that matches Alpha u64 size.
376
+ let result = tao_reserve_u128
377
+ . saturating_mul ( tao)
378
+ . checked_div ( limit_price_u128)
379
+ . unwrap_or ( 0 )
380
+ . saturating_sub ( alpha_in_u128) ;
381
+
382
+ if result < u64:: MAX as u128 {
383
+ result as u64
384
+ } else {
385
+ u64:: MAX
386
+ }
382
387
}
383
388
}
0 commit comments