@@ -731,3 +731,72 @@ fn named_multi_reservable_repatriate_all_reserved_named_works() {
731
731
} ) ) ;
732
732
} ) ;
733
733
}
734
+
735
+ #[ test]
736
+ fn slash_hook_works ( ) {
737
+ ExtBuilder :: default ( )
738
+ . balances ( vec ! [ ( ALICE , DOT , 100 ) ] )
739
+ . build ( )
740
+ . execute_with ( || {
741
+ let initial_hook_calls = OnSlashHook :: < Runtime > :: calls ( ) ;
742
+
743
+ // slashing zero tokens is a no-op
744
+ assert_eq ! ( Tokens :: slash( DOT , & ALICE , 0 ) , 0 ) ;
745
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_hook_calls) ;
746
+
747
+ assert_eq ! ( Tokens :: slash( DOT , & ALICE , 50 ) , 0 ) ;
748
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_hook_calls + 1 ) ;
749
+
750
+ // `slash` calls the hook even if no amount was slashed
751
+ assert_eq ! ( Tokens :: slash( DOT , & ALICE , 100 ) , 50 ) ;
752
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_hook_calls + 2 ) ;
753
+ } ) ;
754
+ }
755
+
756
+ #[ test]
757
+ fn slash_hook_works_for_reserved ( ) {
758
+ ExtBuilder :: default ( )
759
+ . balances ( vec ! [ ( ALICE , DOT , 100 ) ] )
760
+ . build ( )
761
+ . execute_with ( || {
762
+ let initial_slash_hook_calls = OnSlashHook :: < Runtime > :: calls ( ) ;
763
+
764
+ assert_ok ! ( Tokens :: reserve( DOT , & ALICE , 50 ) ) ;
765
+ // slashing zero tokens is a no-op
766
+ assert_eq ! ( Tokens :: slash_reserved( DOT , & ALICE , 0 ) , 0 ) ;
767
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_slash_hook_calls) ;
768
+
769
+ assert_eq ! ( Tokens :: slash_reserved( DOT , & ALICE , 50 ) , 0 ) ;
770
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_slash_hook_calls + 1 ) ;
771
+
772
+ // `slash_reserved` calls the hook even if no amount was slashed
773
+ assert_eq ! ( Tokens :: slash_reserved( DOT , & ALICE , 50 ) , 50 ) ;
774
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_slash_hook_calls + 2 ) ;
775
+ } ) ;
776
+ }
777
+
778
+ #[ test]
779
+ fn slash_hook_works_for_reserved_named ( ) {
780
+ ExtBuilder :: default ( )
781
+ . balances ( vec ! [ ( ALICE , DOT , 100 ) ] )
782
+ . build ( )
783
+ . execute_with ( || {
784
+ let initial_slash_hook_calls = OnSlashHook :: < Runtime > :: calls ( ) ;
785
+
786
+ assert_ok ! ( Tokens :: reserve_named( & RID_1 , DOT , & ALICE , 10 ) ) ;
787
+ // slashing zero tokens is a no-op
788
+ assert_eq ! ( Tokens :: slash_reserved_named( & RID_1 , DOT , & ALICE , 0 ) , 0 ) ;
789
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_slash_hook_calls) ;
790
+
791
+ assert_eq ! ( Tokens :: slash_reserved_named( & RID_1 , DOT , & ALICE , 10 ) , 0 ) ;
792
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_slash_hook_calls + 1 ) ;
793
+
794
+ // `slash_reserved_named` calls `slash_reserved` under-the-hood with a
795
+ // value to slash based on the account's balance. Because the account's
796
+ // balance is currently zero, `slash_reserved` will be a no-op and
797
+ // the OnSlash hook will not be called.
798
+ assert_eq ! ( Tokens :: slash_reserved_named( & RID_1 , DOT , & ALICE , 50 ) , 50 ) ;
799
+ // Same value as previously because of the no-op
800
+ assert_eq ! ( OnSlashHook :: <Runtime >:: calls( ) , initial_slash_hook_calls + 1 ) ;
801
+ } ) ;
802
+ }
0 commit comments