@@ -16,14 +16,16 @@ use staking::staking::interface::{
1616 IStakingConsensusDispatcherTrait , IStakingDispatcherTrait ,
1717 IStakingRewardsManagerSafeDispatcherTrait ,
1818};
19+ use staking :: staking :: objects :: NormalizedAmountTrait ;
1920use staking :: staking :: utils :: {BTC_WEIGHT_FACTOR , STAKING_POWER_BASE_VALUE , STRK_WEIGHT_FACTOR };
2021use staking :: test_utils :: constants :: {
2122 BTC_18D_CONFIG , BTC_5D_CONFIG , BTC_8D_CONFIG , PUBLIC_KEY , STRK_BASE_VALUE ,
2223 TEST_MIN_BTC_FOR_REWARDS ,
2324};
2425use staking :: test_utils :: {
25- StakingInitConfig , calculate_staker_btc_pool_rewards_v2,
26- calculate_staker_strk_rewards_with_balances_v2, calculate_staker_strk_rewards_with_balances_v3,
26+ StakingInitConfig , calculate_staker_btc_pool_rewards_v2, calculate_staker_btc_pool_rewards_v3,
27+ calculate_staker_strk_rewards_v2, calculate_staker_strk_rewards_with_balances_v2,
28+ calculate_staker_strk_rewards_with_balances_v3,
2729 calculate_strk_pool_rewards_with_pool_balance_v2, compute_rewards_per_unit,
2830 custom_decimals_token, deploy_mock_erc20_decimals_contract,
2931};
@@ -3571,3 +3573,179 @@ fn delegate_claim_after_claim_with_rewards_flow_test() {
35713573 system . advance_epoch ();
35723574 assert! (system . delegator_claim_rewards (: delegator , : pool ). is_zero ());
35733575}
3576+
3577+ /// Flow:
3578+ /// Add tokens A and B
3579+ /// Enable token B
3580+ /// Advance K epochs
3581+ /// Enable token A, disable token B
3582+ /// Attest
3583+ /// Advance epoch - test rewards only for token B
3584+ /// Attest
3585+ /// Advance epoch - test rewards only for token B
3586+ /// Attest
3587+ /// Advance epoch - test rewards only for token A
3588+ /// Start consensus rewards
3589+ /// Enable token B, disable token A
3590+ /// update_rewards twice in the same epoch
3591+ /// Advance epoch - test rewards only for token A
3592+ /// update_rewards
3593+ /// Advance epoch - test rewards only for token A
3594+ /// update_rewards
3595+ /// Advance epoch - test rewards only for token B
3596+ #[test]
3597+ fn update_rewards_token_enable_disable_flow_test () {
3598+ let cfg : StakingInitConfig = Default :: default ();
3599+ let mut system = SystemConfigTrait :: basic_stake_flow_cfg (: cfg ). deploy ();
3600+ let token_a_decimals = 8 ;
3601+ let token_b_decimals = 18 ;
3602+ let token_a = system . deploy_new_btc_token (name : " Token A" , decimals : token_a_decimals );
3603+ let token_b = system . deploy_new_btc_token (name : " Token B" , decimals : token_b_decimals );
3604+ let staking_contract = system . staking. address;
3605+ let minting_curve_contract = system . minting_curve. address;
3606+
3607+ // Setup tokens
3608+ system . staking. add_token (token_address : token_a . contract_address ());
3609+ system . staking. add_token (token_address : token_b . contract_address ());
3610+ system . staking. enable_token (token_address : token_b . contract_address ());
3611+
3612+ // Stake and delegate
3613+ let stake_amount = system . staking. get_min_stake ();
3614+ let delegation_amount_a = BTC_8D_CONFIG . min_for_rewards;
3615+ let delegation_amount_b = BTC_18D_CONFIG . min_for_rewards;
3616+ let staker = system . new_staker (amount : stake_amount );
3617+ let commission = 200 ;
3618+ system . stake (: staker , amount : stake_amount , pool_enabled : true , : commission );
3619+ let pool_a = system . set_open_for_delegation (: staker , token_address : token_a . contract_address ());
3620+ let pool_b = system . set_open_for_delegation (: staker , token_address : token_b . contract_address ());
3621+ let delegator_a = system . new_btc_delegator (amount : delegation_amount_a , token : token_a );
3622+ let delegator_b = system . new_btc_delegator (amount : delegation_amount_b , token : token_b );
3623+ system
3624+ . delegate_btc (
3625+ delegator : delegator_a , pool : pool_a , amount : delegation_amount_a , token : token_a ,
3626+ );
3627+ system
3628+ . delegate_btc (
3629+ delegator : delegator_b , pool : pool_b , amount : delegation_amount_b , token : token_b ,
3630+ );
3631+ system . advance_k_epochs ();
3632+
3633+ // Enable token A, disable token B
3634+ system . staking. enable_token (token_address : token_a . contract_address ());
3635+ system . staking. disable_token (token_address : token_b . contract_address ());
3636+
3637+ // Attest
3638+ system . advance_block_into_attestation_window (: staker );
3639+ system . attest (: staker );
3640+ system . advance_epoch ();
3641+
3642+ // Calculate rewards
3643+ let staker_info = system . staker_info_v1 (: staker );
3644+ let staker_rewards = system . staker_claim_rewards (: staker );
3645+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3646+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3647+ let (expected_staker_rewards , _ ) = calculate_staker_strk_rewards_v2 (
3648+ : staker_info , : staking_contract , : minting_curve_contract ,
3649+ );
3650+ assert! (expected_staker_rewards . is_non_zero ());
3651+ let (commission_rewards , expected_delegator_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3652+ pool_balance : delegation_amount_b ,
3653+ : commission ,
3654+ : staking_contract ,
3655+ : minting_curve_contract ,
3656+ token_address : token_b . contract_address (),
3657+ );
3658+ assert! (commission_rewards . is_non_zero ());
3659+ assert! (expected_delegator_rewards . is_non_zero ());
3660+
3661+ // Test rewards
3662+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3663+ assert! (delegator_a_rewards . is_zero ());
3664+ assert! (delegator_b_rewards == expected_delegator_rewards );
3665+
3666+ // Attest - test rewards only for token B
3667+ system . advance_block_into_attestation_window (: staker );
3668+ system . attest (: staker );
3669+ system . advance_epoch ();
3670+ let staker_rewards = system . staker_claim_rewards (: staker );
3671+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3672+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3673+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3674+ assert! (delegator_a_rewards . is_zero ());
3675+ // Same rewards because the delegation amount is the same (with different decimals).
3676+ assert! (delegator_b_rewards == expected_delegator_rewards );
3677+
3678+ // Attest - test rewards only for token A
3679+ system . advance_block_into_attestation_window (: staker );
3680+ system . attest (: staker );
3681+ system . advance_epoch ();
3682+ let staker_rewards = system . staker_claim_rewards (: staker );
3683+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3684+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3685+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3686+ assert! (delegator_a_rewards == expected_delegator_rewards );
3687+ assert! (delegator_b_rewards . is_zero ());
3688+
3689+ // Start consensus rewards
3690+ system . start_consensus_rewards ();
3691+
3692+ // Enable token B, disable token A
3693+ system . staking. enable_token (token_address : token_b . contract_address ());
3694+ system . staking. disable_token (token_address : token_a . contract_address ());
3695+
3696+ // Calculate rewards for consensus rewards - for single enabled token.
3697+ let (expected_staker_rewards , _ ) = calculate_staker_strk_rewards_with_balances_v3 (
3698+ amount_own : stake_amount ,
3699+ pool_amount : Zero :: zero (),
3700+ : commission ,
3701+ : staking_contract ,
3702+ : minting_curve_contract ,
3703+ );
3704+ assert! (expected_staker_rewards . is_non_zero ());
3705+ let (commission_rewards , expected_delegator_rewards ) = calculate_staker_btc_pool_rewards_v3 (
3706+ normalized_pool_balance : NormalizedAmountTrait :: from_native_amount (
3707+ amount : delegation_amount_a , decimals : token_a_decimals ,
3708+ ),
3709+ normalized_staker_total_btc_balance : NormalizedAmountTrait :: from_native_amount (
3710+ amount : delegation_amount_a , decimals : token_a_decimals ,
3711+ ),
3712+ : commission ,
3713+ : staking_contract ,
3714+ : minting_curve_contract ,
3715+ token_address : token_a . contract_address (),
3716+ );
3717+ assert! (commission_rewards . is_non_zero ());
3718+ assert! (expected_delegator_rewards . is_non_zero ());
3719+
3720+ // update_rewards - test rewards only for token A
3721+ system . update_rewards (: staker , disable_rewards : false );
3722+ advance_block_number_global (blocks : 1 );
3723+ system . update_rewards (: staker , disable_rewards : false );
3724+ system . advance_epoch ();
3725+ let staker_rewards = system . staker_claim_rewards (: staker );
3726+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3727+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3728+ assert! (staker_rewards == expected_staker_rewards * 2 + commission_rewards * 2 );
3729+ assert! (delegator_a_rewards == expected_delegator_rewards * 2 );
3730+ assert! (delegator_b_rewards . is_zero ());
3731+
3732+ // update_rewards - test rewards only for token A
3733+ system . update_rewards (: staker , disable_rewards : false );
3734+ system . advance_epoch ();
3735+ let staker_rewards = system . staker_claim_rewards (: staker );
3736+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3737+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3738+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3739+ assert! (delegator_a_rewards == expected_delegator_rewards );
3740+ assert! (delegator_b_rewards . is_zero ());
3741+
3742+ // update_rewards - test rewards only for token B
3743+ system . update_rewards (: staker , disable_rewards : false );
3744+ system . advance_epoch ();
3745+ let staker_rewards = system . staker_claim_rewards (: staker );
3746+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3747+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3748+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3749+ assert! (delegator_a_rewards . is_zero ());
3750+ assert! (delegator_b_rewards == expected_delegator_rewards );
3751+ }
0 commit comments