@@ -3029,3 +3029,249 @@ fn enable_disable_btc_tokens_flow_test() {
30293029 . span ();
30303030 assert! (tokens == expected_tokens );
30313031}
3032+
3033+ /// Flow:
3034+ /// Staker stake with STRK pool and BTC pool
3035+ /// 2 delegators to STRK pool
3036+ /// 2 delegators to BTC pool
3037+ /// Change balance (staker increase, delegate enter, delegate increase, delegate intent) and attest
3038+ /// in each epoch.
3039+ /// Test rewards
3040+ #[test]
3041+ fn staker_multiple_pools_multiple_delegators_flow_test () {
3042+ let cfg : StakingInitConfig = Default :: default ();
3043+ let mut system = SystemConfigTrait :: basic_stake_flow_cfg (: cfg ). deploy ();
3044+ let staking_contract = system . staking. address;
3045+ let minting_curve_contract = system . minting_curve. address;
3046+ let stake_amount = system . staking. get_min_stake ();
3047+ let strk_amount = STRK_CONFIG . min_for_rewards;
3048+ let btc_amount = TEST_MIN_BTC_FOR_REWARDS ;
3049+ let btc_token = system . btc_token;
3050+ let staker = system . new_staker (amount : 10 * stake_amount );
3051+ let commission = 200 ;
3052+ system . stake (: staker , amount : stake_amount , pool_enabled : true , : commission );
3053+ let strk_pool = system . staking. get_pool (: staker );
3054+ let btc_pool = system
3055+ . set_open_for_delegation (: staker , token_address : btc_token . contract_address ());
3056+ let strk_delegator_1 = system . new_delegator (amount : 10 * strk_amount );
3057+ let strk_delegator_2 = system . new_delegator (amount : 10 * strk_amount );
3058+ let btc_delegator_1 = system . new_btc_delegator (amount : 10 * btc_amount , token : btc_token );
3059+ let btc_delegator_2 = system . new_btc_delegator (amount : 10 * btc_amount , token : btc_token );
3060+ let mut total_staker_rewards = Zero :: zero ();
3061+ let mut total_strk_delegator_1_rewards = Zero :: zero ();
3062+ let mut total_strk_delegator_2_rewards = Zero :: zero ();
3063+ let mut total_btc_delegator_1_rewards = Zero :: zero ();
3064+ let mut total_btc_delegator_2_rewards = Zero :: zero ();
3065+
3066+ system . advance_k_epochs ();
3067+
3068+ system . advance_block_custom_and_attest (: staker , stake : stake_amount );
3069+ let (staker_rewards , _ ) = calculate_staker_strk_rewards_with_balances_v2 (
3070+ amount_own : stake_amount ,
3071+ pool_amount : Zero :: zero (),
3072+ : commission ,
3073+ : staking_contract ,
3074+ : minting_curve_contract ,
3075+ );
3076+ total_staker_rewards += staker_rewards ;
3077+ system . delegate (delegator : strk_delegator_1 , pool : strk_pool , amount : strk_amount );
3078+ system . delegate (delegator : strk_delegator_2 , pool : strk_pool , amount : strk_amount );
3079+
3080+ system . advance_epoch ();
3081+
3082+ system . advance_block_custom_and_attest (: staker , stake : stake_amount );
3083+ total_staker_rewards += staker_rewards ;
3084+ system
3085+ . add_to_delegation_pool (delegator : strk_delegator_1 , pool : strk_pool , amount : strk_amount );
3086+ system
3087+ . delegate_btc (
3088+ delegator : btc_delegator_1 , pool : btc_pool , amount : btc_amount , token : btc_token ,
3089+ );
3090+
3091+ system . advance_epoch ();
3092+
3093+ system
3094+ . delegate_btc (
3095+ delegator : btc_delegator_2 , pool : btc_pool , amount : btc_amount , token : btc_token ,
3096+ );
3097+ system . delegator_exit_intent (delegator : strk_delegator_1 , pool : strk_pool , amount : strk_amount );
3098+ system . advance_block_custom_and_attest (: staker , stake : stake_amount + 2 * strk_amount );
3099+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3100+ amount_own : stake_amount ,
3101+ pool_amount : 2 * strk_amount ,
3102+ : commission ,
3103+ : staking_contract ,
3104+ : minting_curve_contract ,
3105+ );
3106+ total_staker_rewards += staker_rewards ;
3107+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3108+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3109+
3110+ system . advance_epoch ();
3111+
3112+ system . advance_block_custom_and_attest (: staker , stake : stake_amount + 3 * strk_amount );
3113+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3114+ amount_own : stake_amount ,
3115+ pool_amount : 3 * strk_amount ,
3116+ : commission ,
3117+ : staking_contract ,
3118+ : minting_curve_contract ,
3119+ );
3120+ total_staker_rewards += staker_rewards ;
3121+ total_strk_delegator_1_rewards += strk_pool_rewards * 2 / 3 ;
3122+ total_strk_delegator_2_rewards += strk_pool_rewards / 3 ;
3123+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3124+ pool_balance : btc_amount ,
3125+ : commission ,
3126+ : staking_contract ,
3127+ : minting_curve_contract ,
3128+ token_address : btc_token . contract_address (),
3129+ );
3130+ total_staker_rewards += commission_rewards ;
3131+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3132+ system . increase_stake (: staker , amount : stake_amount );
3133+ system
3134+ . increase_delegate_btc (
3135+ delegator : btc_delegator_1 , pool : btc_pool , amount : btc_amount , token : btc_token ,
3136+ );
3137+
3138+ system . advance_epoch ();
3139+
3140+ system . delegator_exit_intent (delegator : btc_delegator_2 , pool : btc_pool , amount : btc_amount );
3141+ system . advance_block_custom_and_attest (: staker , stake : stake_amount + 2 * strk_amount );
3142+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3143+ amount_own : stake_amount ,
3144+ pool_amount : 2 * strk_amount ,
3145+ : commission ,
3146+ : staking_contract ,
3147+ : minting_curve_contract ,
3148+ );
3149+ total_staker_rewards += staker_rewards ;
3150+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3151+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3152+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3153+ pool_balance : 2 * btc_amount ,
3154+ : commission ,
3155+ : staking_contract ,
3156+ : minting_curve_contract ,
3157+ token_address : btc_token . contract_address (),
3158+ );
3159+ total_staker_rewards += commission_rewards ;
3160+ total_btc_delegator_1_rewards += btc_pool_rewards / 2 ;
3161+ total_btc_delegator_2_rewards += btc_pool_rewards / 2 ;
3162+
3163+ system . advance_epoch ();
3164+
3165+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3166+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3167+ amount_own : 2 * stake_amount ,
3168+ pool_amount : 2 * strk_amount ,
3169+ : commission ,
3170+ : staking_contract ,
3171+ : minting_curve_contract ,
3172+ );
3173+ total_staker_rewards += staker_rewards ;
3174+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3175+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3176+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3177+ pool_balance : 3 * btc_amount ,
3178+ : commission ,
3179+ : staking_contract ,
3180+ : minting_curve_contract ,
3181+ token_address : btc_token . contract_address (),
3182+ );
3183+ total_staker_rewards += commission_rewards ;
3184+ total_btc_delegator_1_rewards += btc_pool_rewards * 2 / 3 ;
3185+ total_btc_delegator_2_rewards += btc_pool_rewards / 3 ;
3186+
3187+ system . advance_epoch ();
3188+
3189+ system
3190+ . add_to_delegation_pool (delegator : strk_delegator_2 , pool : strk_pool , amount : strk_amount );
3191+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3192+ let (staker_rewards , strk_pool_rewards ) = calculate_staker_strk_rewards_with_balances_v2 (
3193+ amount_own : 2 * stake_amount ,
3194+ pool_amount : 2 * strk_amount ,
3195+ : commission ,
3196+ : staking_contract ,
3197+ : minting_curve_contract ,
3198+ );
3199+ total_staker_rewards += staker_rewards ;
3200+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3201+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3202+ let (commission_rewards , btc_pool_rewards ) = calculate_staker_btc_pool_rewards_v2 (
3203+ pool_balance : 2 * btc_amount ,
3204+ : commission ,
3205+ : staking_contract ,
3206+ : minting_curve_contract ,
3207+ token_address : btc_token . contract_address (),
3208+ );
3209+ total_staker_rewards += commission_rewards ;
3210+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3211+
3212+ system . advance_epoch ();
3213+
3214+ system . delegator_exit_intent (delegator : strk_delegator_2 , pool : strk_pool , amount : strk_amount );
3215+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3216+ total_staker_rewards += staker_rewards ;
3217+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3218+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3219+ total_staker_rewards += commission_rewards ;
3220+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3221+
3222+ system . advance_epoch ();
3223+ system . advance_epoch ();
3224+
3225+ system . advance_block_custom_and_attest (: staker , stake : 2 * stake_amount + 2 * strk_amount );
3226+ total_staker_rewards += staker_rewards ;
3227+ total_strk_delegator_1_rewards += strk_pool_rewards / 2 ;
3228+ total_strk_delegator_2_rewards += strk_pool_rewards / 2 ;
3229+ total_staker_rewards += commission_rewards ;
3230+ total_btc_delegator_1_rewards += btc_pool_rewards ;
3231+
3232+ // Test staker rewards.
3233+ let staker_rewards = system . staker_claim_rewards (: staker );
3234+ assert_eq! (staker_rewards , total_staker_rewards );
3235+ // Test balances of the pools (Allow small difference due to rounding).
3236+ assert! (
3237+ wide_abs_diff (
3238+ system . token. balance_of (account : strk_pool ),
3239+ total_strk_delegator_1_rewards + total_strk_delegator_2_rewards ,
3240+ ) <= 10 ,
3241+ );
3242+ assert! (
3243+ wide_abs_diff (
3244+ system . token. balance_of (account : btc_pool ),
3245+ total_btc_delegator_1_rewards + total_btc_delegator_2_rewards ,
3246+ ) <= 10 ,
3247+ );
3248+ // Test delegator rewards (Allow small difference due to rounding).
3249+ system . advance_epoch ();
3250+ assert! (
3251+ wide_abs_diff (
3252+ system . delegator_claim_rewards (delegator : strk_delegator_1 , pool : strk_pool ),
3253+ total_strk_delegator_1_rewards ,
3254+ ) <= 10 ,
3255+ );
3256+ assert! (
3257+ wide_abs_diff (
3258+ system . delegator_claim_rewards (delegator : strk_delegator_2 , pool : strk_pool ),
3259+ total_strk_delegator_2_rewards ,
3260+ ) <= 10 ,
3261+ );
3262+ assert! (
3263+ wide_abs_diff (
3264+ system . delegator_claim_rewards (delegator : btc_delegator_1 , pool : btc_pool ),
3265+ total_btc_delegator_1_rewards ,
3266+ ) <= 10 ,
3267+ );
3268+ assert! (
3269+ wide_abs_diff (
3270+ system . delegator_claim_rewards (delegator : btc_delegator_2 , pool : btc_pool ),
3271+ total_btc_delegator_2_rewards ,
3272+ ) <= 10 ,
3273+ );
3274+ // Test remaining balance in pools.
3275+ assert! (system . token. balance_of (account : strk_pool ) < 10 );
3276+ assert! (system . token. balance_of (account : btc_pool ) < 10 );
3277+ }
0 commit comments