@@ -556,6 +556,78 @@ fn test_remove_stake_total_balance_no_change() {
556
556
} ) ;
557
557
}
558
558
559
+ #[ test]
560
+ fn test_add_stake_insufficient_liquidity ( ) {
561
+ new_test_ext ( 1 ) . execute_with ( || {
562
+ let subnet_owner_coldkey = U256 :: from ( 1001 ) ;
563
+ let subnet_owner_hotkey = U256 :: from ( 1002 ) ;
564
+ let hotkey = U256 :: from ( 2 ) ;
565
+ let coldkey = U256 :: from ( 3 ) ;
566
+ let amount_staked = DefaultMinStake :: < Test > :: get ( ) * 10 + DefaultStakingFee :: < Test > :: get ( ) ;
567
+
568
+ let netuid = add_dynamic_network ( & subnet_owner_hotkey, & subnet_owner_coldkey) ;
569
+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & hotkey) ;
570
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey, amount_staked) ;
571
+
572
+ // Set the liquidity at lowest possible value so that all staking requests fail
573
+ SubnetTAO :: < Test > :: insert (
574
+ netuid,
575
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
576
+ ) ;
577
+ SubnetAlphaIn :: < Test > :: insert (
578
+ netuid,
579
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
580
+ ) ;
581
+
582
+ // Check the error
583
+ assert_noop ! (
584
+ SubtensorModule :: add_stake(
585
+ RuntimeOrigin :: signed( coldkey) ,
586
+ hotkey,
587
+ netuid,
588
+ amount_staked
589
+ ) ,
590
+ Error :: <Test >:: InsufficientLiquidity
591
+ ) ;
592
+ } ) ;
593
+ }
594
+
595
+ #[ test]
596
+ fn test_remove_stake_insufficient_liquidity ( ) {
597
+ new_test_ext ( 1 ) . execute_with ( || {
598
+ let subnet_owner_coldkey = U256 :: from ( 1001 ) ;
599
+ let subnet_owner_hotkey = U256 :: from ( 1002 ) ;
600
+ let hotkey = U256 :: from ( 2 ) ;
601
+ let coldkey = U256 :: from ( 3 ) ;
602
+ let amount_staked = DefaultMinStake :: < Test > :: get ( ) * 10 + DefaultStakingFee :: < Test > :: get ( ) ;
603
+
604
+ let netuid = add_dynamic_network ( & subnet_owner_hotkey, & subnet_owner_coldkey) ;
605
+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & hotkey) ;
606
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey, amount_staked) ;
607
+
608
+ // Simulate stake for hotkey
609
+ SubnetTAO :: < Test > :: insert ( netuid, u64:: MAX / 1000 ) ;
610
+ SubnetAlphaIn :: < Test > :: insert ( netuid, u64:: MAX / 1000 ) ;
611
+ let alpha = SubtensorModule :: stake_into_subnet ( & hotkey, & coldkey, netuid, amount_staked, 0 ) ;
612
+
613
+ // Set the liquidity at lowest possible value so that all staking requests fail
614
+ SubnetTAO :: < Test > :: insert (
615
+ netuid,
616
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
617
+ ) ;
618
+ SubnetAlphaIn :: < Test > :: insert (
619
+ netuid,
620
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
621
+ ) ;
622
+
623
+ // Check the error
624
+ assert_noop ! (
625
+ SubtensorModule :: remove_stake( RuntimeOrigin :: signed( coldkey) , hotkey, netuid, alpha) ,
626
+ Error :: <Test >:: InsufficientLiquidity
627
+ ) ;
628
+ } ) ;
629
+ }
630
+
559
631
#[ test]
560
632
fn test_remove_stake_total_issuance_no_change ( ) {
561
633
// When we remove stake, the total issuance of the balances pallet should not change
@@ -2132,3 +2204,108 @@ fn test_stake_below_min_validate() {
2132
2204
assert_ok ! ( result_min_stake) ;
2133
2205
} ) ;
2134
2206
}
2207
+
2208
+ #[ test]
2209
+ fn test_stake_low_liquidity_validate ( ) {
2210
+ // Testing the signed extension validate function
2211
+ // correctly filters the `add_stake` transaction.
2212
+
2213
+ new_test_ext ( 0 ) . execute_with ( || {
2214
+ let subnet_owner_coldkey = U256 :: from ( 1001 ) ;
2215
+ let subnet_owner_hotkey = U256 :: from ( 1002 ) ;
2216
+ let hotkey = U256 :: from ( 2 ) ;
2217
+ let coldkey = U256 :: from ( 3 ) ;
2218
+ let amount_staked = DefaultMinStake :: < Test > :: get ( ) * 10 + DefaultStakingFee :: < Test > :: get ( ) ;
2219
+
2220
+ let netuid = add_dynamic_network ( & subnet_owner_hotkey, & subnet_owner_coldkey) ;
2221
+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & hotkey) ;
2222
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey, amount_staked) ;
2223
+
2224
+ // Set the liquidity at lowest possible value so that all staking requests fail
2225
+ SubnetTAO :: < Test > :: insert (
2226
+ netuid,
2227
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
2228
+ ) ;
2229
+ SubnetAlphaIn :: < Test > :: insert (
2230
+ netuid,
2231
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
2232
+ ) ;
2233
+
2234
+ // Add stake call
2235
+ let call = RuntimeCall :: SubtensorModule ( SubtensorCall :: add_stake {
2236
+ hotkey,
2237
+ netuid,
2238
+ amount_staked,
2239
+ } ) ;
2240
+
2241
+ let info: crate :: DispatchInfo =
2242
+ crate :: DispatchInfoOf :: < <Test as frame_system:: Config >:: RuntimeCall > :: default ( ) ;
2243
+
2244
+ let extension = crate :: SubtensorSignedExtension :: < Test > :: new ( ) ;
2245
+ // Submit to the signed extension validate function
2246
+ let result_no_stake = extension. validate ( & coldkey, & call. clone ( ) , & info, 10 ) ;
2247
+
2248
+ // Should fail due to insufficient stake
2249
+ assert_err ! (
2250
+ result_no_stake,
2251
+ crate :: TransactionValidityError :: Invalid ( crate :: InvalidTransaction :: Custom (
2252
+ CustomTransactionError :: InsufficientLiquidity . into( )
2253
+ ) )
2254
+ ) ;
2255
+ } ) ;
2256
+ }
2257
+
2258
+ #[ test]
2259
+ fn test_unstake_low_liquidity_validate ( ) {
2260
+ // Testing the signed extension validate function
2261
+ // correctly filters the `add_stake` transaction.
2262
+
2263
+ new_test_ext ( 0 ) . execute_with ( || {
2264
+ let subnet_owner_coldkey = U256 :: from ( 1001 ) ;
2265
+ let subnet_owner_hotkey = U256 :: from ( 1002 ) ;
2266
+ let hotkey = U256 :: from ( 2 ) ;
2267
+ let coldkey = U256 :: from ( 3 ) ;
2268
+ let amount_staked = DefaultMinStake :: < Test > :: get ( ) * 10 + DefaultStakingFee :: < Test > :: get ( ) ;
2269
+
2270
+ let netuid = add_dynamic_network ( & subnet_owner_hotkey, & subnet_owner_coldkey) ;
2271
+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & hotkey) ;
2272
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey, amount_staked) ;
2273
+
2274
+ // Simulate stake for hotkey
2275
+ SubnetTAO :: < Test > :: insert ( netuid, u64:: MAX / 1000 ) ;
2276
+ SubnetAlphaIn :: < Test > :: insert ( netuid, u64:: MAX / 1000 ) ;
2277
+ let alpha = SubtensorModule :: stake_into_subnet ( & hotkey, & coldkey, netuid, amount_staked, 0 ) ;
2278
+
2279
+ // Set the liquidity at lowest possible value so that all staking requests fail
2280
+ SubnetTAO :: < Test > :: insert (
2281
+ netuid,
2282
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
2283
+ ) ;
2284
+ SubnetAlphaIn :: < Test > :: insert (
2285
+ netuid,
2286
+ DefaultMinimumPoolLiquidity :: < Test > :: get ( ) . to_num :: < u64 > ( ) ,
2287
+ ) ;
2288
+
2289
+ // Remove stake call
2290
+ let call = RuntimeCall :: SubtensorModule ( SubtensorCall :: remove_stake {
2291
+ hotkey,
2292
+ netuid,
2293
+ amount_unstaked : alpha,
2294
+ } ) ;
2295
+
2296
+ let info: crate :: DispatchInfo =
2297
+ crate :: DispatchInfoOf :: < <Test as frame_system:: Config >:: RuntimeCall > :: default ( ) ;
2298
+
2299
+ let extension = crate :: SubtensorSignedExtension :: < Test > :: new ( ) ;
2300
+ // Submit to the signed extension validate function
2301
+ let result_no_stake = extension. validate ( & coldkey, & call. clone ( ) , & info, 10 ) ;
2302
+
2303
+ // Should fail due to insufficient stake
2304
+ assert_err ! (
2305
+ result_no_stake,
2306
+ crate :: TransactionValidityError :: Invalid ( crate :: InvalidTransaction :: Custom (
2307
+ CustomTransactionError :: InsufficientLiquidity . into( )
2308
+ ) )
2309
+ ) ;
2310
+ } ) ;
2311
+ }
0 commit comments