@@ -917,3 +917,164 @@ mod calculate_fee_for_fulfillment_with_serum {
917917 assert_eq ! ( filler_reward, 2000 ) ;
918918 }
919919}
920+
921+ mod calcuate_fee_tiers {
922+
923+ use crate :: math:: constants:: QUOTE_PRECISION_U64 ;
924+ use crate :: math:: constants:: {
925+ FEE_DENOMINATOR , FEE_PERCENTAGE_DENOMINATOR , MAX_REFERRER_REWARD_EPOCH_UPPER_BOUND ,
926+ } ;
927+ use crate :: math:: fees:: { determine_user_fee_tier, OrderFillerRewardStructure } ;
928+ use crate :: state:: state:: { FeeStructure , FeeTier } ;
929+ use crate :: state:: user:: MarketType ;
930+ use crate :: state:: user:: UserStats ;
931+
932+ #[ test]
933+ fn test_calc_taker_tiers ( ) {
934+ let mut taker_stats = UserStats :: default ( ) ;
935+ let mut fee_tiers = [ FeeTier :: default ( ) ; 10 ] ;
936+
937+ fee_tiers[ 0 ] = FeeTier {
938+ fee_numerator : 35 ,
939+ fee_denominator : FEE_DENOMINATOR , // 3.5 bps
940+ maker_rebate_numerator : 25 ,
941+ maker_rebate_denominator : FEE_DENOMINATOR * 10 , // .25 bps
942+ referrer_reward_numerator : 10 ,
943+ referrer_reward_denominator : FEE_PERCENTAGE_DENOMINATOR , // 10% of taker fee
944+ referee_fee_numerator : 5 ,
945+ referee_fee_denominator : FEE_PERCENTAGE_DENOMINATOR , // 5%
946+ } ;
947+ fee_tiers[ 1 ] = FeeTier {
948+ fee_numerator : 30 ,
949+ fee_denominator : FEE_DENOMINATOR , // 3 bps
950+ maker_rebate_numerator : 25 ,
951+ maker_rebate_denominator : FEE_DENOMINATOR * 10 , // .25 bps
952+ referrer_reward_numerator : 10 ,
953+ referrer_reward_denominator : FEE_PERCENTAGE_DENOMINATOR , // 10% of taker fee
954+ referee_fee_numerator : 5 ,
955+ referee_fee_denominator : FEE_PERCENTAGE_DENOMINATOR , // 5%
956+ } ;
957+ fee_tiers[ 2 ] = FeeTier {
958+ fee_numerator : 275 ,
959+ fee_denominator : FEE_DENOMINATOR * 10 , // 2.75 bps
960+ maker_rebate_numerator : 25 ,
961+ maker_rebate_denominator : FEE_DENOMINATOR * 10 , // .25 bps
962+ referrer_reward_numerator : 10 ,
963+ referrer_reward_denominator : FEE_PERCENTAGE_DENOMINATOR , // 10% of taker fee
964+ referee_fee_numerator : 5 ,
965+ referee_fee_denominator : FEE_PERCENTAGE_DENOMINATOR , // 5%
966+ } ;
967+ fee_tiers[ 3 ] = FeeTier {
968+ fee_numerator : 25 ,
969+ fee_denominator : FEE_DENOMINATOR , // 2.5 bps
970+ maker_rebate_numerator : 25 ,
971+ maker_rebate_denominator : FEE_DENOMINATOR * 10 , // .25 bps
972+ referrer_reward_numerator : 10 ,
973+ referrer_reward_denominator : FEE_PERCENTAGE_DENOMINATOR , // 10% of taker fee
974+ referee_fee_numerator : 5 ,
975+ referee_fee_denominator : FEE_PERCENTAGE_DENOMINATOR , // 5%
976+ } ;
977+ fee_tiers[ 4 ] = FeeTier {
978+ fee_numerator : 225 ,
979+ fee_denominator : FEE_DENOMINATOR * 10 , // 2.25 bps
980+ maker_rebate_numerator : 25 ,
981+ maker_rebate_denominator : FEE_DENOMINATOR * 10 , // .25 bps
982+ referrer_reward_numerator : 10 ,
983+ referrer_reward_denominator : FEE_PERCENTAGE_DENOMINATOR , // 10% of taker fee
984+ referee_fee_numerator : 5 ,
985+ referee_fee_denominator : FEE_PERCENTAGE_DENOMINATOR , // 5%
986+ } ;
987+ fee_tiers[ 5 ] = FeeTier {
988+ fee_numerator : 20 ,
989+ fee_denominator : FEE_DENOMINATOR , // 2 bps
990+ maker_rebate_numerator : 25 ,
991+ maker_rebate_denominator : FEE_DENOMINATOR * 10 , // .25 bps
992+ referrer_reward_numerator : 10 ,
993+ referrer_reward_denominator : FEE_PERCENTAGE_DENOMINATOR , // 10% of taker fee
994+ referee_fee_numerator : 5 ,
995+ referee_fee_denominator : FEE_PERCENTAGE_DENOMINATOR , // 5%
996+ } ;
997+ let fee_structure = FeeStructure {
998+ fee_tiers,
999+ filler_reward_structure : OrderFillerRewardStructure {
1000+ reward_numerator : 10 ,
1001+ reward_denominator : FEE_PERCENTAGE_DENOMINATOR ,
1002+ time_based_reward_lower_bound : 10_000 , // 1 cent
1003+ } ,
1004+ flat_filler_fee : 10_000 ,
1005+ referrer_reward_epoch_upper_bound : MAX_REFERRER_REWARD_EPOCH_UPPER_BOUND ,
1006+ } ;
1007+
1008+ let res = determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , false )
1009+ . unwrap ( ) ;
1010+ assert_eq ! ( res. fee_numerator, 35 ) ;
1011+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1012+
1013+ assert_eq ! ( res. maker_rebate_numerator, 25 ) ;
1014+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1015+
1016+ taker_stats. taker_volume_30d = 80_000_000 * QUOTE_PRECISION_U64 ;
1017+
1018+ let res: FeeTier =
1019+ determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , false )
1020+ . unwrap ( ) ;
1021+ assert_eq ! ( res. fee_numerator, 25 ) ;
1022+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1023+
1024+ assert_eq ! ( res. maker_rebate_numerator, 25 ) ;
1025+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1026+
1027+ taker_stats. if_staked_gov_token_amount = 50_000 * QUOTE_PRECISION_U64 - 8970 ; // still counts for 50K tier
1028+ let res: FeeTier =
1029+ determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , false )
1030+ . unwrap ( ) ;
1031+
1032+ assert_eq ! ( res. fee_numerator, 20 ) ;
1033+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1034+
1035+ assert_eq ! ( res. maker_rebate_numerator, 30 ) ;
1036+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1037+
1038+ taker_stats. if_staked_gov_token_amount = 150_000 * QUOTE_PRECISION_U64 - 8970 ; // still counts for 100K tier
1039+ let res: FeeTier =
1040+ determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , false )
1041+ . unwrap ( ) ;
1042+
1043+ assert_eq ! ( res. fee_numerator, 18 ) ;
1044+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1045+
1046+ assert_eq ! ( res. maker_rebate_numerator, 32 ) ;
1047+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1048+
1049+ taker_stats. if_staked_gov_token_amount = 800_000 * QUOTE_PRECISION_U64 ;
1050+ let res: FeeTier =
1051+ determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , false )
1052+ . unwrap ( ) ;
1053+
1054+ assert_eq ! ( res. fee_numerator, 15 ) ;
1055+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1056+
1057+ assert_eq ! ( res. maker_rebate_numerator, 35 ) ;
1058+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1059+
1060+ taker_stats. taker_volume_30d = 280_000_000 * QUOTE_PRECISION_U64 ;
1061+ let res: FeeTier =
1062+ determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , false )
1063+ . unwrap ( ) ;
1064+
1065+ assert_eq ! ( res. fee_numerator, 12 ) ;
1066+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1067+
1068+ assert_eq ! ( res. maker_rebate_numerator, 35 ) ;
1069+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1070+
1071+ let res: FeeTier =
1072+ determine_user_fee_tier ( & taker_stats, & fee_structure, & MarketType :: Perp , true ) . unwrap ( ) ;
1073+
1074+ assert_eq ! ( res. fee_numerator, 35 ) ;
1075+ assert_eq ! ( res. fee_denominator, 100000 ) ;
1076+
1077+ assert_eq ! ( res. maker_rebate_numerator, 25 ) ;
1078+ assert_eq ! ( res. maker_rebate_denominator, 1000000 ) ;
1079+ }
1080+ }
0 commit comments