@@ -3120,3 +3120,249 @@ fn staker_change_balance_twice_same_epoch_flow_test() {
31203120 assert! (expected_rewards . is_non_zero ());
31213121 assert! (system . staker_claim_rewards (: staker ) == expected_rewards );
31223122}
3123+
3124+ /// Flow:
3125+ /// Staker stake with STRK pool and BTC pool
3126+ /// 2 delegators to STRK pool
3127+ /// 2 delegators to BTC pool
3128+ /// Change balance (staker increase, delegate enter, delegate increase, delegate intent) and attest
3129+ /// in each epoch.
3130+ /// Test rewards
3131+ #[test]
3132+ fn staker_multiple_pools_multiple_delegators_flow_test () {
3133+ let cfg : StakingInitConfig = Default :: default ();
3134+ let mut system = SystemConfigTrait :: basic_stake_flow_cfg (: cfg ). deploy ();
3135+ let staking_contract = system . staking. address;
3136+ let minting_curve_contract = system . minting_curve. address;
3137+ let stake_amount = system . staking. get_min_stake ();
3138+ let strk_amount = STRK_CONFIG . min_for_rewards;
3139+ let btc_amount = TEST_MIN_BTC_FOR_REWARDS ;
3140+ let btc_token = system . btc_token;
3141+ let staker = system . new_staker (amount : 10 * stake_amount );
3142+ let commission = 200 ;
3143+ system . stake (: staker , amount : stake_amount , pool_enabled : true , : commission );
3144+ let strk_pool = system . staking. get_pool (: staker );
3145+ let btc_pool = system
3146+ . set_open_for_delegation (: staker , token_address : btc_token . contract_address ());
3147+ let strk_delegator_1 = system . new_delegator (amount : 10 * strk_amount );
3148+ let strk_delegator_2 = system . new_delegator (amount : 10 * strk_amount );
3149+ let btc_delegator_1 = system . new_btc_delegator (amount : 10 * btc_amount , token : btc_token );
3150+ let btc_delegator_2 = system . new_btc_delegator (amount : 10 * btc_amount , token : btc_token );
3151+ let mut total_staker_rewards = Zero :: zero ();
3152+ let mut total_strk_delegator_1_rewards = Zero :: zero ();
3153+ let mut total_strk_delegator_2_rewards = Zero :: zero ();
3154+ let mut total_btc_delegator_1_rewards = Zero :: zero ();
3155+ let mut total_btc_delegator_2_rewards = Zero :: zero ();
3156+
3157+ system . advance_k_epochs ();
3158+
3159+ system . advance_block_custom_and_attest (: staker , stake : stake_amount );
3160+ let (staker_rewards , _ ) = calculate_staker_strk_rewards_with_balances_v2 (
3161+ amount_own : stake_amount ,
3162+ pool_amount : Zero :: zero (),
3163+ : commission ,
3164+ : staking_contract ,
3165+ : minting_curve_contract ,
3166+ );
3167+ total_staker_rewards += staker_rewards ;
3168+ system . delegate (delegator : strk_delegator_1 , pool : strk_pool , amount : strk_amount );
3169+ system . delegate (delegator : strk_delegator_2 , pool : strk_pool , amount : strk_amount );
3170+
3171+ system . advance_epoch ();
3172+
3173+ system . advance_block_custom_and_attest (: staker , stake : stake_amount );
3174+ total_staker_rewards += staker_rewards ;
3175+ system
3176+ . add_to_delegation_pool (delegator : strk_delegator_1 , pool : strk_pool , amount : strk_amount );
3177+ system
3178+ . delegate_btc (
3179+ delegator : btc_delegator_1 , pool : btc_pool , amount : btc_amount , token : btc_token ,
3180+ );
3181+
3182+ system . advance_epoch ();
3183+
3184+ system
3185+ . delegate_btc (
3186+ delegator : btc_delegator_2 , pool : btc_pool , amount : btc_amount , token : btc_token ,
3187+ );
3188+ system . delegator_exit_intent (delegator : strk_delegator_1 , pool : strk_pool , amount : strk_amount );
3189+ system . advance_block_custom_and_attest (: staker , stake : stake_amount + 2 * strk_amount );
3190+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3191+ amount_own : stake_amount ,
3192+ pool_amount : 2 * strk_amount ,
3193+ : commission ,
3194+ : staking_contract ,
3195+ : minting_curve_contract ,
3196+ );
3197+ total_staker_rewards += staker_rewards ;
3198+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3199+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3200+
3201+ system . advance_epoch ();
3202+
3203+ system . advance_block_custom_and_attest (: staker , stake : stake_amount + 3 * strk_amount );
3204+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3205+ amount_own : stake_amount ,
3206+ pool_amount : 3 * strk_amount ,
3207+ : commission ,
3208+ : staking_contract ,
3209+ : minting_curve_contract ,
3210+ );
3211+ total_staker_rewards += staker_rewards ;
3212+ total_strk_delegator_1_rewards += strk_pool_rewards * 2 / 3 ;
3213+ total_strk_delegator_2_rewards += strk_pool_rewards / 3 ;
3214+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3215+ pool_balance : btc_amount ,
3216+ : commission ,
3217+ : staking_contract ,
3218+ : minting_curve_contract ,
3219+ token_address : btc_token . contract_address (),
3220+ );
3221+ total_staker_rewards += commission_rewards ;
3222+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3223+ system . increase_stake (: staker , amount : stake_amount );
3224+ system
3225+ . increase_delegate_btc (
3226+ delegator : btc_delegator_1 , pool : btc_pool , amount : btc_amount , token : btc_token ,
3227+ );
3228+
3229+ system . advance_epoch ();
3230+
3231+ system . delegator_exit_intent (delegator : btc_delegator_2 , pool : btc_pool , amount : btc_amount );
3232+ system . advance_block_custom_and_attest (: staker , stake : stake_amount + 2 * strk_amount );
3233+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3234+ amount_own : stake_amount ,
3235+ pool_amount : 2 * strk_amount ,
3236+ : commission ,
3237+ : staking_contract ,
3238+ : minting_curve_contract ,
3239+ );
3240+ total_staker_rewards += staker_rewards ;
3241+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3242+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3243+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3244+ pool_balance : 2 * btc_amount ,
3245+ : commission ,
3246+ : staking_contract ,
3247+ : minting_curve_contract ,
3248+ token_address : btc_token . contract_address (),
3249+ );
3250+ total_staker_rewards += commission_rewards ;
3251+ total_btc_delegator_1_rewards += btc_pool_rewards / 2 ;
3252+ total_btc_delegator_2_rewards += btc_pool_rewards / 2 ;
3253+
3254+ system . advance_epoch ();
3255+
3256+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3257+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3258+ amount_own : 2 * stake_amount ,
3259+ pool_amount : 2 * strk_amount ,
3260+ : commission ,
3261+ : staking_contract ,
3262+ : minting_curve_contract ,
3263+ );
3264+ total_staker_rewards += staker_rewards ;
3265+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3266+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3267+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3268+ pool_balance : 3 * btc_amount ,
3269+ : commission ,
3270+ : staking_contract ,
3271+ : minting_curve_contract ,
3272+ token_address : btc_token . contract_address (),
3273+ );
3274+ total_staker_rewards += commission_rewards ;
3275+ total_btc_delegator_1_rewards += btc_pool_rewards * 2 / 3 ;
3276+ total_btc_delegator_2_rewards += btc_pool_rewards / 3 ;
3277+
3278+ system . advance_epoch ();
3279+
3280+ system
3281+ . add_to_delegation_pool (delegator : strk_delegator_2 , pool : strk_pool , amount : strk_amount );
3282+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3283+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3284+ amount_own : 2 * stake_amount ,
3285+ pool_amount : 2 * strk_amount ,
3286+ : commission ,
3287+ : staking_contract ,
3288+ : minting_curve_contract ,
3289+ );
3290+ total_staker_rewards += staker_rewards ;
3291+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3292+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3293+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3294+ pool_balance : 2 * btc_amount ,
3295+ : commission ,
3296+ : staking_contract ,
3297+ : minting_curve_contract ,
3298+ token_address : btc_token . contract_address (),
3299+ );
3300+ total_staker_rewards += commission_rewards ;
3301+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3302+
3303+ system . advance_epoch ();
3304+
3305+ system . delegator_exit_intent (delegator : strk_delegator_2 , pool : strk_pool , amount : strk_amount );
3306+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3307+ total_staker_rewards += staker_rewards ;
3308+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3309+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3310+ total_staker_rewards += commission_rewards ;
3311+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3312+
3313+ system . advance_epoch ();
3314+ system . advance_epoch ();
3315+
3316+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3317+ total_staker_rewards += staker_rewards ;
3318+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3319+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3320+ total_staker_rewards += commission_rewards ;
3321+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3322+
3323+ // Test staker rewards.
3324+ let staker_rewards = system . staker_claim_rewards (: staker );
3325+ assert_eq! (staker_rewards , total_staker_rewards );
3326+ // Test balances of the pools (Allow small difference due to rounding).
3327+ assert! (
3328+ wide_abs_diff (
3329+ system . token. balance_of (account : strk_pool ),
3330+ total_strk_delegator_1_rewards + total_strk_delegator_2_rewards ,
3331+ ) <= 10 ,
3332+ );
3333+ assert! (
3334+ wide_abs_diff (
3335+ system . token. balance_of (account : btc_pool ),
3336+ total_btc_delegator_1_rewards + total_btc_delegator_2_rewards ,
3337+ ) <= 10 ,
3338+ );
3339+ // Test delegator rewards (Allow small difference due to rounding).
3340+ system . advance_epoch ();
3341+ assert! (
3342+ wide_abs_diff (
3343+ system . delegator_claim_rewards (delegator : strk_delegator_1 , pool : strk_pool ),
3344+ total_strk_delegator_1_rewards ,
3345+ ) <= 10 ,
3346+ );
3347+ assert! (
3348+ wide_abs_diff (
3349+ system . delegator_claim_rewards (delegator : strk_delegator_2 , pool : strk_pool ),
3350+ total_strk_delegator_2_rewards ,
3351+ ) <= 10 ,
3352+ );
3353+ assert! (
3354+ wide_abs_diff (
3355+ system . delegator_claim_rewards (delegator : btc_delegator_1 , pool : btc_pool ),
3356+ total_btc_delegator_1_rewards ,
3357+ ) <= 10 ,
3358+ );
3359+ assert! (
3360+ wide_abs_diff (
3361+ system . delegator_claim_rewards (delegator : btc_delegator_2 , pool : btc_pool ),
3362+ total_btc_delegator_2_rewards ,
3363+ ) <= 10 ,
3364+ );
3365+ // Test remaining balance in pools.
3366+ assert! (system . token. balance_of (account : strk_pool ) < 10 );
3367+ assert! (system . token. balance_of (account : btc_pool ) < 10 );
3368+ }
0 commit comments