@@ -2744,3 +2744,172 @@ fn test_clear_protocol_liquidity_green_path() {
27442744 assert ! ( !SwapV3Initialized :: <Test >:: contains_key( netuid) ) ;
27452745 } ) ;
27462746}
2747+
2748+ fn as_tuple (
2749+ ( t_used, a_used, t_rem, a_rem) : ( TaoCurrency , AlphaCurrency , TaoCurrency , AlphaCurrency ) ,
2750+ ) -> ( u64 , u64 , u64 , u64 ) {
2751+ (
2752+ u64:: from ( t_used) ,
2753+ u64:: from ( a_used) ,
2754+ u64:: from ( t_rem) ,
2755+ u64:: from ( a_rem) ,
2756+ )
2757+ }
2758+
2759+ #[ test]
2760+ fn proportional_when_price_is_one_and_tao_is_plenty ( ) {
2761+ // sqrt_price = 1.0 => price = 1.0
2762+ let sqrt = U64F64 :: from_num ( 1u64 ) ;
2763+ let amount_tao: TaoCurrency = 10u64 . into ( ) ;
2764+ let amount_alpha: AlphaCurrency = 3u64 . into ( ) ;
2765+
2766+ // alpha * price = 3 * 1 = 3 <= amount_tao(10)
2767+ let out =
2768+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2769+ assert_eq ! ( as_tuple( out) , ( 3 , 3 , 7 , 0 ) ) ;
2770+ }
2771+
2772+ #[ test]
2773+ fn proportional_when_price_is_one_and_alpha_is_excess ( ) {
2774+ // sqrt_price = 1.0 => price = 1.0
2775+ let sqrt = U64F64 :: from_num ( 1u64 ) ;
2776+ let amount_tao: TaoCurrency = 5u64 . into ( ) ;
2777+ let amount_alpha: AlphaCurrency = 10u64 . into ( ) ;
2778+
2779+ // tao is limiting: alpha_equiv = floor(5 / 1) = 5
2780+ let out =
2781+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2782+ assert_eq ! ( as_tuple( out) , ( 5 , 5 , 0 , 5 ) ) ;
2783+ }
2784+
2785+ #[ test]
2786+ fn proportional_with_higher_price_and_alpha_limiting ( ) {
2787+ // Choose sqrt_price = 2.0 => price = 4.0 (since implementation squares it)
2788+ let sqrt = U64F64 :: from_num ( 2u64 ) ;
2789+ let amount_tao: TaoCurrency = 85u64 . into ( ) ;
2790+ let amount_alpha: AlphaCurrency = 20u64 . into ( ) ;
2791+
2792+ // tao_equivalent = alpha * price = 20 * 4 = 80 < 85 => alpha limits tao
2793+ // remainders: tao 5, alpha 0
2794+ let out =
2795+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2796+ assert_eq ! ( as_tuple( out) , ( 80 , 20 , 5 , 0 ) ) ;
2797+ }
2798+
2799+ #[ test]
2800+ fn proportional_with_higher_price_and_tao_limiting ( ) {
2801+ // Choose sqrt_price = 2.0 => price = 4.0 (since implementation squares it)
2802+ let sqrt = U64F64 :: from_num ( 2u64 ) ;
2803+ let amount_tao: TaoCurrency = 50u64 . into ( ) ;
2804+ let amount_alpha: AlphaCurrency = 20u64 . into ( ) ;
2805+
2806+ // tao_equivalent = alpha * price = 20 * 4 = 80 > 50 => tao limits alpha
2807+ // alpha_equivalent = floor(50 / 4) = 12
2808+ // remainders: tao 0, alpha 20 - 12 = 8
2809+ let out =
2810+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2811+ assert_eq ! ( as_tuple( out) , ( 50 , 12 , 0 , 8 ) ) ;
2812+ }
2813+
2814+ #[ test]
2815+ fn zero_price_uses_no_tao_and_all_alpha ( ) {
2816+ // sqrt_price = 0 => price = 0
2817+ let sqrt = U64F64 :: from_num ( 0u64 ) ;
2818+ let amount_tao: TaoCurrency = 42u64 . into ( ) ;
2819+ let amount_alpha: AlphaCurrency = 17u64 . into ( ) ;
2820+
2821+ // tao_equivalent = 17 * 0 = 0 <= 42
2822+ let out =
2823+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2824+ assert_eq ! ( as_tuple( out) , ( 0 , 17 , 42 , 0 ) ) ;
2825+ }
2826+
2827+ #[ test]
2828+ fn rounding_down_behavior_when_dividing_by_price ( ) {
2829+ // sqrt_price = 2.0 => price = 4.0
2830+ let sqrt = U64F64 :: from_num ( 2u64 ) ;
2831+ let amount_tao: TaoCurrency = 13u64 . into ( ) ;
2832+ let amount_alpha: AlphaCurrency = 100u64 . into ( ) ;
2833+
2834+ // tao is limiting; alpha_equiv = floor(13 / 4) = 3
2835+ // remainders: tao 0, alpha 100 - 3 = 97
2836+ let out =
2837+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2838+ assert_eq ! ( as_tuple( out) , ( 13 , 3 , 0 , 97 ) ) ;
2839+ }
2840+
2841+ #[ test]
2842+ fn exact_fit_when_tao_matches_alpha_times_price ( ) {
2843+ // sqrt_price = 1.0 => price = 1.0
2844+ let sqrt = U64F64 :: from_num ( 1u64 ) ;
2845+ let amount_tao: TaoCurrency = 9u64 . into ( ) ;
2846+ let amount_alpha: AlphaCurrency = 9u64 . into ( ) ;
2847+
2848+ let out =
2849+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, amount_tao, amount_alpha) ;
2850+ assert_eq ! ( as_tuple( out) , ( 9 , 9 , 0 , 0 ) ) ;
2851+ }
2852+
2853+ #[ test]
2854+ fn handles_zero_balances ( ) {
2855+ let sqrt = U64F64 :: from_num ( 1u64 ) ;
2856+
2857+ // Zero TAO, some alpha
2858+ let out =
2859+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, 0u64 . into ( ) , 7u64 . into ( ) ) ;
2860+ // tao limits; alpha_equiv = floor(0 / 1) = 0
2861+ assert_eq ! ( as_tuple( out) , ( 0 , 0 , 0 , 7 ) ) ;
2862+
2863+ // Some TAO, zero alpha
2864+ let out =
2865+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, 7u64 . into ( ) , 0u64 . into ( ) ) ;
2866+ // tao_equiv = 0 * 1 = 0 <= 7
2867+ assert_eq ! ( as_tuple( out) , ( 0 , 0 , 7 , 0 ) ) ;
2868+
2869+ // Both zero
2870+ let out =
2871+ Pallet :: < Test > :: get_proportional_alpha_tao_and_remainders ( sqrt, 0u64 . into ( ) , 0u64 . into ( ) ) ;
2872+ assert_eq ! ( as_tuple( out) , ( 0 , 0 , 0 , 0 ) ) ;
2873+ }
2874+
2875+ #[ test]
2876+ fn adjust_protocol_liquidity_uses_and_sets_scrap_reservoirs ( ) {
2877+ new_test_ext ( ) . execute_with ( || {
2878+ // --- Arrange
2879+ let netuid: NetUid = 1u16 . into ( ) ;
2880+ // Price = 1.0 (since sqrt_price^2 = 1), so proportional match is 1:1
2881+ AlphaSqrtPrice :: < Test > :: insert ( netuid, U64F64 :: saturating_from_num ( 1u64 ) ) ;
2882+
2883+ // Start with some non-zero scrap reservoirs
2884+ ScrapReservoirTao :: < Test > :: insert ( netuid, TaoCurrency :: from ( 7u64 ) ) ;
2885+ ScrapReservoirAlpha :: < Test > :: insert ( netuid, AlphaCurrency :: from ( 5u64 ) ) ;
2886+
2887+ // Create a minimal protocol position so the function’s body executes.
2888+ let protocol = Pallet :: < Test > :: protocol_account_id ( ) ;
2889+ let position = Position :: new (
2890+ PositionId :: from ( 0 ) ,
2891+ netuid,
2892+ TickIndex :: MIN ,
2893+ TickIndex :: MAX ,
2894+ 0 ,
2895+ ) ;
2896+ // Ensure collect_fees() returns (0,0) via zeroed fees in `position` (default).
2897+ Positions :: < Test > :: insert ( ( netuid, protocol, position. id ) , position. clone ( ) ) ;
2898+
2899+ // --- Act
2900+ // No external deltas or fees; only reservoirs should be considered.
2901+ // With price=1, the exact proportional pair uses 5 alpha and 5 tao,
2902+ // leaving tao scrap = 7 - 5 = 2, alpha scrap = 5 - 5 = 0.
2903+ Pallet :: < Test > :: adjust_protocol_liquidity ( netuid, 0u64 . into ( ) , 0u64 . into ( ) ) ;
2904+
2905+ // --- Assert: reservoirs were READ (used in proportional calc) and then SET (updated)
2906+ assert_eq ! (
2907+ ScrapReservoirTao :: <Test >:: get( netuid) ,
2908+ TaoCurrency :: from( 2u64 )
2909+ ) ;
2910+ assert_eq ! (
2911+ ScrapReservoirAlpha :: <Test >:: get( netuid) ,
2912+ AlphaCurrency :: from( 0u64 )
2913+ ) ;
2914+ } ) ;
2915+ }
0 commit comments