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,132 @@ 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+ . staking
2689+ . set_consensus_rewards_first_epoch (epoch_id : system . staking. get_current_epoch () + K . into ());
2690+
2691+ // Disable rewards = true before consensus epoch - no rewards
2692+ system . update_rewards (: staker , disable_rewards : true );
2693+ let rewards = system . staker_claim_rewards (: staker );
2694+ assert! (rewards . is_zero ());
2695+
2696+ // Attempt again same block - panic
2697+ let result = system
2698+ . staking
2699+ . rewards_manager_safe_dispatcher ()
2700+ . update_rewards (staker_address : staker . staker. address, disable_rewards : true );
2701+ assert_panic_with_error (
2702+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2703+ );
2704+ advance_block_number_global (blocks : 1 );
2705+
2706+ // Disable rewards = false before consensus epoch - no rewards
2707+ system . update_rewards (: staker , disable_rewards : false );
2708+ let rewards = system . staker_claim_rewards (: staker );
2709+ assert! (rewards . is_zero ());
2710+
2711+ // Attempt again same block - panic
2712+ let result = system
2713+ . staking
2714+ . rewards_manager_safe_dispatcher ()
2715+ . update_rewards (staker_address : staker . staker. address, disable_rewards : false );
2716+ assert_panic_with_error (
2717+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2718+ );
2719+ system . advance_k_epochs ();
2720+
2721+ // Disable rewards = true with consensus on - no rewards
2722+ system . update_rewards (: staker , disable_rewards : true );
2723+ let rewards = system . staker_claim_rewards (: staker );
2724+ assert! (rewards . is_zero ());
2725+
2726+ // Attempt again same block - panic
2727+ let result = system
2728+ . staking
2729+ . rewards_manager_safe_dispatcher ()
2730+ . update_rewards (staker_address : staker . staker. address, disable_rewards : true );
2731+ assert_panic_with_error (
2732+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2733+ );
2734+ advance_block_number_global (blocks : 1 );
2735+
2736+ // Disable rewards = false with consensus on - rewards
2737+ system . update_rewards (: staker , disable_rewards : false );
2738+ let rewards = system . staker_claim_rewards (: staker );
2739+ let (expected_rewards , _ ) = calculate_staker_strk_rewards_with_balances_v3 (
2740+ amount_own : stake_amount ,
2741+ pool_amount : Zero :: zero (),
2742+ : commission ,
2743+ staking_contract : system . staking. address,
2744+ minting_curve_contract : system . minting_curve. address,
2745+ );
2746+ assert! (expected_rewards . is_non_zero ());
2747+ assert! (rewards == expected_rewards );
2748+
2749+ // Attempt again same block - panic
2750+ let result = system
2751+ . staking
2752+ . rewards_manager_safe_dispatcher ()
2753+ . update_rewards (staker_address : staker . staker. address, disable_rewards : false );
2754+ assert_panic_with_error (
2755+ : result , expected_error : StakingError :: REWARDS_ALREADY_UPDATED . describe (),
2756+ );
2757+ }
0 commit comments