@@ -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};
@@ -3120,3 +3122,179 @@ fn staker_change_balance_twice_same_epoch_flow_test() {
31203122 assert! (expected_rewards . is_non_zero ());
31213123 assert! (system . staker_claim_rewards (: staker ) == expected_rewards );
31223124}
3125+
3126+ /// Flow:
3127+ /// Add tokens A and B
3128+ /// Enable token B
3129+ /// Advance K epochs
3130+ /// Enable token A, disable token B
3131+ /// Attest
3132+ /// Advance epoch - test rewards only for token B
3133+ /// Attest
3134+ /// Advance epoch - test rewards only for token B
3135+ /// Attest
3136+ /// Advance epoch - test rewards only for token A
3137+ /// Start consensus rewards
3138+ /// Enable token B, disable token A
3139+ /// update_rewards twice in the same epoch
3140+ /// Advance epoch - test rewards only for token A
3141+ /// update_rewards
3142+ /// Advance epoch - test rewards only for token A
3143+ /// update_rewards
3144+ /// Advance epoch - test rewards only for token B
3145+ #[test]
3146+ fn update_rewards_token_enable_disable_flow_test () {
3147+ let cfg : StakingInitConfig = Default :: default ();
3148+ let mut system = SystemConfigTrait :: basic_stake_flow_cfg (: cfg ). deploy ();
3149+ let token_a_decimals = 8 ;
3150+ let token_b_decimals = 18 ;
3151+ let token_a = system . deploy_new_btc_token (name : " Token A" , decimals : token_a_decimals );
3152+ let token_b = system . deploy_new_btc_token (name : " Token B" , decimals : token_b_decimals );
3153+ let staking_contract = system . staking. address;
3154+ let minting_curve_contract = system . minting_curve. address;
3155+
3156+ // Setup tokens
3157+ system . staking. add_token (token_address : token_a . contract_address ());
3158+ system . staking. add_token (token_address : token_b . contract_address ());
3159+ system . staking. enable_token (token_address : token_b . contract_address ());
3160+
3161+ // Stake and delegate
3162+ let stake_amount = system . staking. get_min_stake ();
3163+ let delegation_amount_a = BTC_8D_CONFIG . min_for_rewards;
3164+ let delegation_amount_b = BTC_18D_CONFIG . min_for_rewards;
3165+ let staker = system . new_staker (amount : stake_amount );
3166+ let commission = 200 ;
3167+ system . stake (: staker , amount : stake_amount , pool_enabled : true , : commission );
3168+ let pool_a = system . set_open_for_delegation (: staker , token_address : token_a . contract_address ());
3169+ let pool_b = system . set_open_for_delegation (: staker , token_address : token_b . contract_address ());
3170+ let delegator_a = system . new_btc_delegator (amount : delegation_amount_a , token : token_a );
3171+ let delegator_b = system . new_btc_delegator (amount : delegation_amount_b , token : token_b );
3172+ system
3173+ . delegate_btc (
3174+ delegator : delegator_a , pool : pool_a , amount : delegation_amount_a , token : token_a ,
3175+ );
3176+ system
3177+ . delegate_btc (
3178+ delegator : delegator_b , pool : pool_b , amount : delegation_amount_b , token : token_b ,
3179+ );
3180+ system . advance_k_epochs ();
3181+
3182+ // Enable token A, disable token B
3183+ system . staking. enable_token (token_address : token_a . contract_address ());
3184+ system . staking. disable_token (token_address : token_b . contract_address ());
3185+
3186+ // Attest
3187+ system . advance_block_into_attestation_window (: staker );
3188+ system . attest (: staker );
3189+ system . advance_epoch ();
3190+
3191+ // Calculate rewards
3192+ let staker_info = system . staker_info_v1 (: staker );
3193+ let staker_rewards = system . staker_claim_rewards (: staker );
3194+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3195+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3196+ let (expected_staker_rewards , _ ) = calculate_staker_strk_rewards_v2 (
3197+ : staker_info , : staking_contract , : minting_curve_contract ,
3198+ );
3199+ assert! (expected_staker_rewards . is_non_zero ());
3200+ let (commission_rewards , expected_delegator_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3201+ pool_balance : delegation_amount_b ,
3202+ : commission ,
3203+ : staking_contract ,
3204+ : minting_curve_contract ,
3205+ token_address : token_b . contract_address (),
3206+ );
3207+ assert! (commission_rewards . is_non_zero ());
3208+ assert! (expected_delegator_rewards . is_non_zero ());
3209+
3210+ // Test rewards
3211+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3212+ assert! (delegator_a_rewards . is_zero ());
3213+ assert! (delegator_b_rewards == expected_delegator_rewards );
3214+
3215+ // Attest - test rewards only for token B
3216+ system . advance_block_into_attestation_window (: staker );
3217+ system . attest (: staker );
3218+ system . advance_epoch ();
3219+ let staker_rewards = system . staker_claim_rewards (: staker );
3220+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3221+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3222+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3223+ assert! (delegator_a_rewards . is_zero ());
3224+ // Same rewards because the delegation amount is the same (with different decimals).
3225+ assert! (delegator_b_rewards == expected_delegator_rewards );
3226+
3227+ // Attest - test rewards only for token A
3228+ system . advance_block_into_attestation_window (: staker );
3229+ system . attest (: staker );
3230+ system . advance_epoch ();
3231+ let staker_rewards = system . staker_claim_rewards (: staker );
3232+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3233+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3234+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3235+ assert! (delegator_a_rewards == expected_delegator_rewards );
3236+ assert! (delegator_b_rewards . is_zero ());
3237+
3238+ // Start consensus rewards
3239+ system . start_consensus_rewards ();
3240+
3241+ // Enable token B, disable token A
3242+ system . staking. enable_token (token_address : token_b . contract_address ());
3243+ system . staking. disable_token (token_address : token_a . contract_address ());
3244+
3245+ // Calculate rewards for consensus rewards - for single enabled token.
3246+ let (expected_staker_rewards , _ ) = calculate_staker_strk_rewards_with_balances_v3 (
3247+ amount_own : stake_amount ,
3248+ pool_amount : Zero :: zero (),
3249+ : commission ,
3250+ : staking_contract ,
3251+ : minting_curve_contract ,
3252+ );
3253+ assert! (expected_staker_rewards . is_non_zero ());
3254+ let (commission_rewards , expected_delegator_rewards ) = calculate_staker_btc_pool_rewards_v3 (
3255+ normalized_pool_balance : NormalizedAmountTrait :: from_native_amount (
3256+ amount : delegation_amount_a , decimals : token_a_decimals ,
3257+ ),
3258+ normalized_staker_total_btc_balance : NormalizedAmountTrait :: from_native_amount (
3259+ amount : delegation_amount_a , decimals : token_a_decimals ,
3260+ ),
3261+ : commission ,
3262+ : staking_contract ,
3263+ : minting_curve_contract ,
3264+ token_address : token_a . contract_address (),
3265+ );
3266+ assert! (commission_rewards . is_non_zero ());
3267+ assert! (expected_delegator_rewards . is_non_zero ());
3268+
3269+ // update_rewards - test rewards only for token A
3270+ system . update_rewards (: staker , disable_rewards : false );
3271+ advance_block_number_global (blocks : 1 );
3272+ system . update_rewards (: staker , disable_rewards : false );
3273+ system . advance_epoch ();
3274+ let staker_rewards = system . staker_claim_rewards (: staker );
3275+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3276+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3277+ assert! (staker_rewards == expected_staker_rewards * 2 + commission_rewards * 2 );
3278+ assert! (delegator_a_rewards == expected_delegator_rewards * 2 );
3279+ assert! (delegator_b_rewards . is_zero ());
3280+
3281+ // update_rewards - test rewards only for token A
3282+ system . update_rewards (: staker , disable_rewards : false );
3283+ system . advance_epoch ();
3284+ let staker_rewards = system . staker_claim_rewards (: staker );
3285+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3286+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3287+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3288+ assert! (delegator_a_rewards == expected_delegator_rewards );
3289+ assert! (delegator_b_rewards . is_zero ());
3290+
3291+ // update_rewards - test rewards only for token B
3292+ system . update_rewards (: staker , disable_rewards : false );
3293+ system . advance_epoch ();
3294+ let staker_rewards = system . staker_claim_rewards (: staker );
3295+ let delegator_a_rewards = system . delegator_claim_rewards (delegator : delegator_a , pool : pool_a );
3296+ let delegator_b_rewards = system . delegator_claim_rewards (delegator : delegator_b , pool : pool_b );
3297+ assert! (staker_rewards == expected_staker_rewards + commission_rewards );
3298+ assert! (delegator_a_rewards . is_zero ());
3299+ assert! (delegator_b_rewards == expected_delegator_rewards );
3300+ }
0 commit comments