11use core :: num :: traits :: Zero ;
22use snforge_std :: TokenImpl ;
3- use staking :: constants :: STRK_IN_FRIS ;
3+ use staking :: constants :: { K , STRK_IN_FRIS } ;
44use staking :: flow_test :: flows;
55use staking :: flow_test :: utils :: {
66 RewardSupplierTrait , StakingTrait , SystemConfigTrait , SystemDelegatorTrait , SystemStakerTrait ,
@@ -9,22 +9,29 @@ use staking::flow_test::utils::{
99use staking :: pool :: pool :: Pool ;
1010use staking :: pool :: pool :: Pool :: STRK_CONFIG ;
1111use staking :: pool :: utils :: compute_rewards_rounded_down;
12- use staking :: staking :: interface :: {IStakingConsensusDispatcherTrait , IStakingDispatcherTrait };
12+ use staking :: staking :: errors :: Error as StakingError ;
13+ use staking :: staking :: interface :: {
14+ IStakingConsensusDispatcherTrait , IStakingDispatcherTrait ,
15+ IStakingRewardsManagerSafeDispatcherTrait ,
16+ };
1317use staking :: staking :: utils :: {BTC_WEIGHT_FACTOR , STAKING_POWER_BASE_VALUE , STRK_WEIGHT_FACTOR };
1418use staking :: test_utils :: constants :: {
1519 BTC_18D_CONFIG , BTC_5D_CONFIG , BTC_8D_CONFIG , PUBLIC_KEY , STRK_BASE_VALUE ,
1620 TEST_MIN_BTC_FOR_REWARDS ,
1721};
1822use staking :: test_utils :: {
1923 StakingInitConfig , calculate_staker_btc_pool_rewards_v2,
20- calculate_staker_strk_rewards_with_balances_v2,
24+ calculate_staker_strk_rewards_with_balances_v2, calculate_staker_strk_rewards_with_balances_v3,
2125 calculate_strk_pool_rewards_with_pool_balance_v2, compute_rewards_per_unit,
2226 custom_decimals_token, deploy_mock_erc20_decimals_contract,
2327};
28+ use starkware_utils :: errors :: {Describable , ErrorDisplay };
2429use starkware_utils :: math :: abs :: wide_abs_diff;
2530use starkware_utils :: math :: utils :: mul_wide_and_div;
2631use starkware_utils :: time :: time :: Time ;
27- use starkware_utils_testing :: test_utils :: cheat_caller_address_once;
32+ use starkware_utils_testing :: test_utils :: {
33+ advance_block_number_global, assert_panic_with_error, cheat_caller_address_once,
34+ };
2835use crate :: types :: Amount ;
2936
3037#[test]
@@ -2619,3 +2626,131 @@ fn get_stakers_staking_power_100_flow_test() {
26192626 . span ();
26202627 assert! (stakers == expected_stakers );
26212628}
2629+
2630+ /// Flow:
2631+ /// Staker stake
2632+ /// Disable rewards is true with consensus off - test no rewards
2633+ /// Attempt again same block - panic
2634+ /// Disable rewards is false with consensus off - test no rewards
2635+ /// Attempt again same block - panic
2636+ /// Enable consensus rewards (in K epochs)
2637+ /// Disable rewards is true before consensus epoch - test no rewards
2638+ /// Attempt again same block - panic
2639+ /// Disable rewards is false before consensus epoch - test no rewards
2640+ /// Attempt again same block - panic
2641+ /// Disable rewards is true with consensus on - test no rewards
2642+ /// Attempt again same block - panic
2643+ /// Disable rewards is false with consensus on - test rewards
2644+ /// Attempt again same block - panic
2645+ #[test]
2646+ #[feature(" safe_dispatcher" )]
2647+ fn update_rewards_disable_rewards_consensus_rewards_flow_test () {
2648+ let cfg : StakingInitConfig = Default :: default ();
2649+ let mut system = SystemConfigTrait :: basic_stake_flow_cfg (: cfg ). deploy ();
2650+ let stake_amount = system . staking. get_min_stake ();
2651+ let staker = system . new_staker (amount : stake_amount );
2652+ let commission = 200 ;
2653+ system . stake (: staker , amount : stake_amount , pool_enabled : false , : commission );
2654+ system . advance_k_epochs ();
2655+
2656+ // Disable rewards = true with consensus off - no rewards
2657+ system . update_rewards (: staker , disable_rewards : true );
2658+ let rewards = system . staker_claim_rewards (: staker );
2659+ assert! (rewards . is_zero ());
2660+
2661+ // Attempt again same block - panic
2662+ let result = system
2663+ . staking
2664+ . rewards_manager_safe_dispatcher ()
2665+ . update_rewards (staker_address : staker . staker. address, disable_rewards : true );
2666+ assert_panic_with_error (
2667+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2668+ );
2669+ advance_block_number_global (blocks : 1 );
2670+
2671+ // Disable rewards = false with consensus off - no rewards
2672+ system . update_rewards (: staker , disable_rewards : false );
2673+ let rewards = system . staker_claim_rewards (: staker );
2674+ assert! (rewards . is_zero ());
2675+
2676+ // Attempt again same block - panic
2677+ let result = system
2678+ . staking
2679+ . rewards_manager_safe_dispatcher ()
2680+ . update_rewards (staker_address : staker . staker. address, disable_rewards : false );
2681+ assert_panic_with_error (
2682+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2683+ );
2684+ advance_block_number_global (blocks : 1 );
2685+
2686+ // Enable consensus rewards
2687+ system
2688+ . set_consensus_rewards_first_epoch (epoch_id : system . staking. get_current_epoch () + K . into ());
2689+
2690+ // Disable rewards = true before consensus epoch - no rewards
2691+ system . update_rewards (: staker , disable_rewards : true );
2692+ let rewards = system . staker_claim_rewards (: staker );
2693+ assert! (rewards . is_zero ());
2694+
2695+ // Attempt again same block - panic
2696+ let result = system
2697+ . staking
2698+ . rewards_manager_safe_dispatcher ()
2699+ . update_rewards (staker_address : staker . staker. address, disable_rewards : true );
2700+ assert_panic_with_error (
2701+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2702+ );
2703+ advance_block_number_global (blocks : 1 );
2704+
2705+ // Disable rewards = false before consensus epoch - no rewards
2706+ system . update_rewards (: staker , disable_rewards : false );
2707+ let rewards = system . staker_claim_rewards (: staker );
2708+ assert! (rewards . is_zero ());
2709+
2710+ // Attempt again same block - panic
2711+ let result = system
2712+ . staking
2713+ . rewards_manager_safe_dispatcher ()
2714+ . update_rewards (staker_address : staker . staker. address, disable_rewards : false );
2715+ assert_panic_with_error (
2716+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2717+ );
2718+ system . advance_k_epochs ();
2719+
2720+ // Disable rewards = true with consensus on - no rewards
2721+ system . update_rewards (: staker , disable_rewards : true );
2722+ let rewards = system . staker_claim_rewards (: staker );
2723+ assert! (rewards . is_zero ());
2724+
2725+ // Attempt again same block - panic
2726+ let result = system
2727+ . staking
2728+ . rewards_manager_safe_dispatcher ()
2729+ . update_rewards (staker_address : staker . staker. address, disable_rewards : true );
2730+ assert_panic_with_error (
2731+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2732+ );
2733+ advance_block_number_global (blocks : 1 );
2734+
2735+ // Disable rewards = false with consensus on - rewards
2736+ system . update_rewards (: staker , disable_rewards : false );
2737+ let rewards = system . staker_claim_rewards (: staker );
2738+ let (expected_rewards , _ ) = calculate_staker_strk_rewards_with_balances_v3 (
2739+ amount_own : stake_amount ,
2740+ pool_amount : Zero :: zero (),
2741+ : commission ,
2742+ staking_contract : system . staking. address,
2743+ minting_curve_contract : system . minting_curve. address,
2744+ );
2745+ assert! (expected_rewards . is_non_zero ());
2746+ assert! (rewards == expected_rewards );
2747+
2748+ // Attempt again same block - panic
2749+ let result = system
2750+ . staking
2751+ . rewards_manager_safe_dispatcher ()
2752+ . update_rewards (staker_address : staker . staker. address, disable_rewards : false );
2753+ assert_panic_with_error (
2754+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2755+ );
2756+ }
0 commit comments