@@ -412,7 +412,6 @@ impl<T: Config> Pallet<T> {
412412 let mut refund: u64 = 0 ;
413413 let mut iteration_counter: u16 = 0 ;
414414 let mut in_acc: u64 = 0 ;
415- let liquidity_before = CurrentLiquidity :: < T > :: get ( netuid) ;
416415
417416 // Swap one tick at a time until we reach one of the stop conditions
418417 while amount_remaining > 0 {
@@ -431,6 +430,11 @@ impl<T: Config> Pallet<T> {
431430 amount_remaining = 0 ;
432431 }
433432
433+ // The swap step didn't exchange anything
434+ if swap_result. amount_to_take == 0 {
435+ amount_remaining = 0 ;
436+ }
437+
434438 iteration_counter = iteration_counter. saturating_add ( 1 ) ;
435439
436440 ensure ! (
@@ -882,7 +886,7 @@ impl<T: Config> Pallet<T> {
882886 } )
883887 }
884888
885- fn modify_position (
889+ pub fn modify_position (
886890 netuid : NetUid ,
887891 coldkey_account_id : & T :: AccountId ,
888892 hotkey_account_id : & T :: AccountId ,
@@ -1019,6 +1023,9 @@ impl<T: Config> Pallet<T> {
10191023 } ) ;
10201024 }
10211025 } ) ;
1026+
1027+ // Update active ticks
1028+ ActiveTickIndexManager :: insert :: < T > ( netuid, tick_index) ;
10221029 }
10231030
10241031 /// Remove liquidity at tick index.
@@ -1043,6 +1050,9 @@ impl<T: Config> Pallet<T> {
10431050 // If no liquidity is left at the tick, remove it
10441051 if tick. liquidity_gross == 0 {
10451052 * maybe_tick = None ;
1053+
1054+ // Update active ticks: Final liquidity is zero, remove this tick from active.
1055+ ActiveTickIndexManager :: remove :: < T > ( netuid, tick_index) ;
10461056 }
10471057 }
10481058 } ) ;
@@ -1157,6 +1167,17 @@ impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
11571167 . map_err ( Into :: into)
11581168 }
11591169
1170+ fn modify_position (
1171+ netuid : u16 ,
1172+ coldkey_account_id : & T :: AccountId ,
1173+ hotkey_account_id : & T :: AccountId ,
1174+ position_id : u128 ,
1175+ liquidity_delta : i64 ,
1176+ ) -> Result < UpdateLiquidityResult , DispatchError > {
1177+ Self :: modify_position ( netuid. into ( ) , coldkey_account_id, hotkey_account_id, position_id. into ( ) , liquidity_delta)
1178+ . map_err ( Into :: into)
1179+ }
1180+
11601181 fn approx_fee_amount ( netuid : u16 , amount : u64 ) -> u64 {
11611182 Self :: calculate_fee_amount ( netuid. into ( ) , amount)
11621183 }
@@ -1206,7 +1227,7 @@ pub enum SwapStepAction {
12061227#[ cfg( test) ]
12071228mod tests {
12081229 use approx:: assert_abs_diff_eq;
1209- use frame_support:: { assert_err, assert_noop , assert_ok} ;
1230+ use frame_support:: { assert_err, assert_ok} ;
12101231 use sp_arithmetic:: helpers_128bit;
12111232
12121233 use super :: * ;
@@ -1647,7 +1668,6 @@ mod tests {
16471668 #[ test]
16481669 fn test_modify_position_basic ( ) {
16491670 new_test_ext ( ) . execute_with ( || {
1650- let min_price = tick_to_price ( TickIndex :: MIN ) ;
16511671 let max_price = tick_to_price ( TickIndex :: MAX ) ;
16521672 let max_tick = price_to_tick ( max_price) ;
16531673 let limit_price = 1000.0_f64 ;
@@ -1667,20 +1687,18 @@ mod tests {
16671687 // 4_000_000_000_u64,
16681688 // ),
16691689 // // Repeat the protocol liquidity at current to max range: Expect the same alpha
1670- ( 0.25 , max_price, 2_000_000_000_u64 , 1_000_000_000 , 4_000_000_000 ) ,
1671- // Repeat the protocol liquidity at min to current range: Expect all the same tao
1672- // (min_price, 0.24999, 2_000_000_000_u64, 1_000_000_000, 0),
1673- // // Half to double price - just some sane wothdraw amounts
1674- // (0.125, 0.5, 2_000_000_000_u64, 293_000_000, 1_171_000_000),
1690+ ( 0.25 , max_price, 2_000_000_000_u64 , 4_000_000_000 ) ,
1691+ // Half to double price - just some sane wothdraw amounts
1692+ // (0.125, 0.5, 2_000_000_000_u64, 1_171_000_000),
16751693 // // Both below price - tao is non-zero, alpha is zero
16761694 // (0.12, 0.13, 2_000_000_000_u64, 28_270_000, 0),
16771695 // // Both above price - tao is zero, alpha is non-zero
16781696 // (0.3, 0.4, 2_000_000_000_u64, 0, 489_200_000),
16791697 ]
16801698 . into_iter ( )
16811699 . enumerate ( )
1682- . map ( |( n, v) | ( NetUid :: from ( n as u16 ) , v. 0 , v. 1 , v. 2 , v. 3 , v . 4 ) )
1683- . for_each ( |( netuid, price_low, price_high, liquidity, tao , alpha) | {
1700+ . map ( |( n, v) | ( NetUid :: from ( n as u16 ) , v. 0 , v. 1 , v. 2 , v. 3 ) )
1701+ . for_each ( |( netuid, price_low, price_high, liquidity, alpha) | {
16841702 // Calculate ticks (assuming tick math is tested separately)
16851703 let tick_low = price_to_tick ( price_low) ;
16861704 let tick_high = price_to_tick ( price_high) ;
@@ -1748,10 +1766,11 @@ mod tests {
17481766 & OK_COLDKEY_ACCOUNT_ID ,
17491767 & OK_HOTKEY_ACCOUNT_ID ,
17501768 position_id,
1751- -1_i64 * ( ( liquidity / 10 ) as i64 ) ,
1769+ -1_i64 * ( ( liquidity / 100 ) as i64 ) ,
17521770 )
17531771 . unwrap ( ) ;
1754- assert_abs_diff_eq ! ( modify_result. alpha, alpha / 10 , epsilon = alpha / 1000 ) ;
1772+
1773+ assert_abs_diff_eq ! ( modify_result. alpha, alpha / 100 , epsilon = alpha / 1000 ) ;
17551774 assert_eq ! ( modify_result. fee_tao, 0 ) ;
17561775 assert_eq ! ( modify_result. fee_alpha, 0 ) ;
17571776 } ) ;
@@ -2015,10 +2034,6 @@ mod tests {
20152034 // Calculate the expected output amount for the cornercase of one step
20162035 let order_liquidity = order_liquidity_fraction * position_liquidity as f64 ;
20172036
2018- let input_amount = match order_type {
2019- OrderType :: Buy => order_liquidity * sqrt_current_price. to_num :: < f64 > ( ) ,
2020- OrderType :: Sell => order_liquidity / sqrt_current_price. to_num :: < f64 > ( ) ,
2021- } ;
20222037 let output_amount = match order_type {
20232038 OrderType :: Buy => {
20242039 let denom = sqrt_current_price. to_num :: < f64 > ( )
@@ -2165,7 +2180,6 @@ mod tests {
21652180 let min_price = tick_to_price ( TickIndex :: MIN ) ;
21662181 let max_price = tick_to_price ( TickIndex :: MAX ) ;
21672182 let max_tick = price_to_tick ( max_price) ;
2168- let current_price = 0.25 ;
21692183 let netuid = NetUid ( 1 ) ;
21702184 assert_eq ! ( max_tick, TickIndex :: MAX ) ;
21712185
@@ -2350,22 +2364,12 @@ mod tests {
23502364 let order_type = OrderType :: Sell ;
23512365 let liquidity = 1_000_000_000_000_000_000 ;
23522366 let tick_low = TickIndex :: MIN ;
2353- let tick_high = TickIndex :: MAX ;
23542367
23552368 let sqrt_limit_price: SqrtPrice = tick_low. try_to_sqrt_price ( ) . unwrap ( ) ;
23562369
23572370 // Setup swap
23582371 assert_ok ! ( Pallet :: <Test >:: maybe_initialize_v3( netuid) ) ;
23592372
2360- // Get tick infos before the swap
2361- let tick_low_info_before = Ticks :: < Test > :: get ( netuid, tick_low) . unwrap_or_default ( ) ;
2362- let tick_high_info_before = Ticks :: < Test > :: get ( netuid, tick_high) . unwrap_or_default ( ) ;
2363- let liquidity_before = CurrentLiquidity :: < Test > :: get ( netuid) ;
2364-
2365- // Get current price
2366- let sqrt_current_price = AlphaSqrtPrice :: < Test > :: get ( netuid) ;
2367- let current_price = ( sqrt_current_price * sqrt_current_price) . to_num :: < f64 > ( ) ;
2368-
23692373 // Swap
23702374 let swap_result =
23712375 Pallet :: < Test > :: do_swap ( netuid, order_type, liquidity, sqrt_limit_price, true )
@@ -2374,4 +2378,25 @@ mod tests {
23742378 assert ! ( swap_result. amount_paid_out > 0 ) ;
23752379 } ) ;
23762380 }
2381+
2382+ // cargo test --package pallet-subtensor-swap --lib -- pallet::impls::tests::test_price_tick_price_roundtrip --exact --show-output
2383+ #[ test]
2384+ fn test_price_tick_price_roundtrip ( ) {
2385+ new_test_ext ( ) . execute_with ( || {
2386+ let netuid = NetUid :: from ( 1 ) ;
2387+
2388+ // Setup swap
2389+ assert_ok ! ( Pallet :: <Test >:: maybe_initialize_v3( netuid) ) ;
2390+
2391+ let current_price = SqrtPrice :: from_num ( 0.50000051219212275465 ) ;
2392+ let tick = TickIndex :: try_from_sqrt_price ( current_price) . unwrap ( ) ;
2393+ let round_trip_price = TickIndex :: try_to_sqrt_price ( & tick) . unwrap ( ) ;
2394+ assert ! ( round_trip_price <= current_price) ;
2395+
2396+ let roundtrip_tick = TickIndex :: try_from_sqrt_price ( round_trip_price) . unwrap ( ) ;
2397+ assert ! ( tick == roundtrip_tick) ;
2398+ } ) ;
2399+ }
2400+
2401+
23772402}
0 commit comments