Skip to content

Commit 3ee5f59

Browse files
test: add balances delay flow (#65)
<!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/starkware-libs/starknet-staking/65) <!-- Reviewable:end --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a new BalancesDelayFlow and mainnet fork test to verify staking power and STRK/BTC rewards timing across epochs pre/post-upgrade. > > - **Flows (`src/flow_test/flows.cairo`)**: > - **`BalancesDelayFlow`**: New flow exercising delayed balance effects across epochs and an upgrade. > - Sets up staker, STRK and BTC delegators; performs stake/delegate increases; triggers upgrade; and asserts: > - Total staking power per epoch (Epoch 0 baseline; Epoch 1 pre-/post-upgrade). > - Staker rewards via attestations and delegator rewards (STRK/BTC) across Epochs 1–4. > - **Tests (`src/flow_test/fork_test.cairo`)**: > - Adds `balances_delay_flow_test` (MAINNET_LATEST) to run the new flow. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5f4a056. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent fdd38dd commit 3ee5f59

File tree

3 files changed

+269
-1
lines changed

3 files changed

+269
-1
lines changed

src/flow_test/flow_ideas.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ more ideas:
5050
- staker enter in V0, advance epoch, update balance, advance epoch, update balance, upgrade to V3, attest
5151
- staker enter in V1, advance epoch, update balance, advance epoch, update balance, upgrade to V3, attest
5252
- staker in V2, update balance staker+update balance pool, upgrade, attest in current epoch, attest in next epoch, attest in next next epoch
53-
- staker in V2, update balance staker+update balance pool, upgrade, update balance staker+update balance pool, attest in current epoch, attest in next epoch, attest in next next epoch
5453
- staker in V2, advance epoch, update balance staker+update balance pool, advance epoch, update balance staker+update balance pool, upgrade, update balance staker+update balance pool, attest in current epoch, attest in next epoch, attest in next next epoch
5554

5655
## pool member balance at curr epoch migration

src/flow_test/flows.cairo

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8570,3 +8570,255 @@ pub(crate) impl MemberChangeBalanceClaimRewardsOneRewardsFlowImpl of MultiVersio
85708570
);
85718571
}
85728572
}
8573+
8574+
/// Flow:
8575+
/// Epoch 0:
8576+
/// Staker stake
8577+
/// Epoch 1:
8578+
/// Staker increase stake
8579+
/// Delegators delegate STRK and BTC
8580+
/// Upgrade
8581+
/// Staker increase stake
8582+
/// Delegators increase delegation STRK and BTC
8583+
/// Test total staking power - according to Epoch 0
8584+
/// Test staker balance with attestation rewards - according to Epoch 0
8585+
/// Epoch 2:
8586+
/// Test delegator balances with attestation rewards - according to Epoch 0
8587+
/// Test total staking power - according to Epoch 1 (pre-upgrade)
8588+
/// Test staker balance with attestation rewards - according to Epoch 1 (pre-upgrade)
8589+
/// Epoch 3:
8590+
/// Test delegator balances with attestation rewards - according to Epoch 1 (pre-upgrade)
8591+
/// Test total staking power - according to Epoch 1 (post-upgrade)
8592+
/// Test staker balance with attestation rewards - according to Epoch 1 (post-upgrade)
8593+
/// Epoch 4:
8594+
/// Test delegator balances with attestation rewards - according to Epoch 1 (post-upgrade)
8595+
#[derive(Drop, Copy)]
8596+
pub(crate) struct BalancesDelayFlow {
8597+
pub(crate) staker: Option<Staker>,
8598+
pub(crate) stake_amount: Option<Amount>,
8599+
pub(crate) commission: Option<Commission>,
8600+
pub(crate) strk_delegated_amount: Option<Amount>,
8601+
pub(crate) btc_delegated_amount: Option<Amount>,
8602+
pub(crate) strk_delegator: Option<Delegator>,
8603+
pub(crate) btc_delegator: Option<Delegator>,
8604+
pub(crate) strk_pool: Option<ContractAddress>,
8605+
pub(crate) btc_pool: Option<ContractAddress>,
8606+
}
8607+
pub(crate) impl BalancesDelayFlowImpl of FlowTrait<BalancesDelayFlow> {
8608+
fn setup_v2(ref self: BalancesDelayFlow, ref system: SystemState) {
8609+
let stake_amount = system.staking.get_min_stake();
8610+
let strk_delegated_amount = STRK_CONFIG.min_for_rewards;
8611+
let btc_delegated_amount = TEST_MIN_BTC_FOR_REWARDS;
8612+
let staker = system.new_staker(amount: stake_amount * 3);
8613+
let commission = 200;
8614+
let strk_delegator = system.new_delegator(amount: strk_delegated_amount * 2);
8615+
let btc_delegator = system
8616+
.new_btc_delegator(amount: btc_delegated_amount * 2, token: system.btc_token);
8617+
8618+
system.stake(:staker, amount: stake_amount, pool_enabled: true, :commission);
8619+
let strk_pool = system.staking.get_pool(:staker);
8620+
let btc_pool = system
8621+
.set_open_for_delegation(:staker, token_address: system.btc_token.contract_address());
8622+
8623+
system.advance_epoch(); // Epoch 0 - > 1
8624+
system.increase_stake(:staker, amount: stake_amount);
8625+
system.delegate(delegator: strk_delegator, pool: strk_pool, amount: strk_delegated_amount);
8626+
system
8627+
.delegate_btc(
8628+
delegator: btc_delegator,
8629+
pool: btc_pool,
8630+
amount: btc_delegated_amount,
8631+
token: system.btc_token,
8632+
);
8633+
8634+
system.set_staker_for_migration(staker_address: staker.staker.address);
8635+
self.staker = Option::Some(staker);
8636+
self.stake_amount = Option::Some(stake_amount);
8637+
self.commission = Option::Some(commission);
8638+
self.strk_delegated_amount = Option::Some(strk_delegated_amount);
8639+
self.btc_delegated_amount = Option::Some(btc_delegated_amount);
8640+
self.strk_delegator = Option::Some(strk_delegator);
8641+
self.btc_delegator = Option::Some(btc_delegator);
8642+
self.strk_pool = Option::Some(strk_pool);
8643+
self.btc_pool = Option::Some(btc_pool);
8644+
}
8645+
8646+
#[feature("safe_dispatcher")]
8647+
fn test(self: BalancesDelayFlow, ref system: SystemState) {
8648+
let staker = self.staker.unwrap();
8649+
let stake_amount = self.stake_amount.unwrap();
8650+
let commission = self.commission.unwrap();
8651+
let strk_delegated_amount = self.strk_delegated_amount.unwrap();
8652+
let btc_delegated_amount = self.btc_delegated_amount.unwrap();
8653+
let strk_delegator = self.strk_delegator.unwrap();
8654+
let btc_delegator = self.btc_delegator.unwrap();
8655+
let strk_pool = self.strk_pool.unwrap();
8656+
let btc_pool = self.btc_pool.unwrap();
8657+
8658+
let staking_contract = system.staking.address;
8659+
let minting_curve_contract = system.minting_curve.address;
8660+
8661+
// Increase stake and delegations.
8662+
system.increase_stake(:staker, amount: stake_amount);
8663+
system
8664+
.increase_delegate(
8665+
delegator: strk_delegator, pool: strk_pool, amount: strk_delegated_amount,
8666+
);
8667+
system
8668+
.increase_delegate_btc(
8669+
delegator: btc_delegator,
8670+
pool: btc_pool,
8671+
amount: btc_delegated_amount,
8672+
token: system.btc_token,
8673+
);
8674+
8675+
// Test total staking power - according to Epoch 0.
8676+
let mut staker_stake = stake_amount;
8677+
let total_staking_power = system.staking.get_current_total_staking_power_v2();
8678+
let expected_total_staking_power = (
8679+
NormalizedAmountTrait::from_strk_native_amount(staker_stake), Zero::zero(),
8680+
);
8681+
assert!(total_staking_power == expected_total_staking_power);
8682+
8683+
// Calculate expected rewards - according to Epoch 0.
8684+
let (expected_staker_rewards, _) = calculate_staker_strk_rewards_with_balances_v2(
8685+
amount_own: staker_stake,
8686+
pool_amount: Zero::zero(),
8687+
:commission,
8688+
:staking_contract,
8689+
:minting_curve_contract,
8690+
);
8691+
assert!(expected_staker_rewards.is_non_zero());
8692+
8693+
// Test staker balance with attestation rewards - according to Epoch 0.
8694+
system
8695+
.advance_block_into_attestation_window_custom_stake(
8696+
staker_address: staker.staker.address, stake: staker_stake,
8697+
);
8698+
system.attest(:staker);
8699+
let staker_rewards = system.staker_claim_rewards(:staker);
8700+
assert!(staker_rewards == expected_staker_rewards);
8701+
8702+
// Advance epoch - test delegator balances with attestation rewards - according to Epoch 0.
8703+
system.advance_epoch(); // Epoch 1 - > 2
8704+
let strk_delegator_rewards = system
8705+
.delegator_claim_rewards(delegator: strk_delegator, pool: strk_pool);
8706+
let btc_delegator_rewards = system
8707+
.delegator_claim_rewards(delegator: btc_delegator, pool: btc_pool);
8708+
assert!(strk_delegator_rewards == Zero::zero());
8709+
assert!(btc_delegator_rewards == Zero::zero());
8710+
8711+
// Update variables for Epoch 1 (pre-upgrade).
8712+
staker_stake += stake_amount;
8713+
let mut strk_pool_balance = strk_delegated_amount;
8714+
let mut btc_pool_balance = btc_delegated_amount;
8715+
8716+
// Test total staking power - according to Epoch 1 (pre-upgrade).
8717+
let total_staking_power = system.staking.get_current_total_staking_power_v2();
8718+
let expected_total_staking_power = (
8719+
NormalizedAmountTrait::from_strk_native_amount(staker_stake + strk_pool_balance),
8720+
NormalizedAmountTrait::from_native_amount(btc_pool_balance, TEST_BTC_DECIMALS),
8721+
);
8722+
assert!(total_staking_power == expected_total_staking_power);
8723+
8724+
// Calculate expected rewards - according to Epoch 1 (pre-upgrade).
8725+
let prev_staker_rewards = expected_staker_rewards;
8726+
let (expected_staker_rewards, expected_strk_pool_rewards) =
8727+
calculate_staker_strk_rewards_with_balances_v2(
8728+
amount_own: staker_stake,
8729+
pool_amount: strk_pool_balance,
8730+
:commission,
8731+
:staking_contract,
8732+
:minting_curve_contract,
8733+
);
8734+
assert!(expected_staker_rewards != prev_staker_rewards);
8735+
assert!(expected_strk_pool_rewards.is_non_zero());
8736+
let (expected_btc_commission_rewards, expected_btc_pool_rewards) =
8737+
calculate_staker_btc_pool_rewards_v2(
8738+
pool_balance: btc_pool_balance,
8739+
:commission,
8740+
:staking_contract,
8741+
:minting_curve_contract,
8742+
token_address: system.btc_token.contract_address(),
8743+
);
8744+
assert!(expected_btc_commission_rewards.is_non_zero());
8745+
assert!(expected_btc_pool_rewards.is_non_zero());
8746+
8747+
// Test staker balance with attestation rewards - according to Epoch 1 (pre-upgrade).
8748+
system
8749+
.advance_block_into_attestation_window_custom_stake(
8750+
staker_address: staker.staker.address, stake: staker_stake + strk_pool_balance,
8751+
);
8752+
system.attest(:staker);
8753+
let staker_rewards = system.staker_claim_rewards(:staker);
8754+
assert!(staker_rewards == expected_staker_rewards + expected_btc_commission_rewards);
8755+
8756+
// Advance epoch - test delegator balances with attestation rewards - according to Epoch 1
8757+
// (pre-upgrade).
8758+
system.advance_epoch(); // Epoch 2 - > 3
8759+
let strk_delegator_rewards = system
8760+
.delegator_claim_rewards(delegator: strk_delegator, pool: strk_pool);
8761+
let btc_delegator_rewards = system
8762+
.delegator_claim_rewards(delegator: btc_delegator, pool: btc_pool);
8763+
assert!(strk_delegator_rewards == expected_strk_pool_rewards);
8764+
assert!(btc_delegator_rewards == expected_btc_pool_rewards);
8765+
8766+
// Update variables for Epoch 1 (post-upgrade).
8767+
staker_stake += stake_amount;
8768+
strk_pool_balance += strk_delegated_amount;
8769+
btc_pool_balance += btc_delegated_amount;
8770+
8771+
// Test total staking power - according to Epoch 1 (post-upgrade).
8772+
let total_staking_power = system.staking.get_current_total_staking_power_v2();
8773+
let expected_total_staking_power = (
8774+
NormalizedAmountTrait::from_strk_native_amount(staker_stake + strk_pool_balance),
8775+
NormalizedAmountTrait::from_native_amount(btc_pool_balance, TEST_BTC_DECIMALS),
8776+
);
8777+
assert!(total_staking_power == expected_total_staking_power);
8778+
8779+
// Calculate expected rewards - according to Epoch 1 (post-upgrade).
8780+
let prev_staker_rewards = expected_staker_rewards;
8781+
let prev_strk_pool_rewards = expected_strk_pool_rewards;
8782+
let prev_btc_commission_rewards = expected_btc_commission_rewards;
8783+
let prev_btc_pool_rewards = expected_btc_pool_rewards;
8784+
let (expected_staker_rewards, expected_strk_pool_rewards) =
8785+
calculate_staker_strk_rewards_with_balances_v2(
8786+
amount_own: staker_stake,
8787+
pool_amount: strk_pool_balance,
8788+
:commission,
8789+
:staking_contract,
8790+
:minting_curve_contract,
8791+
);
8792+
assert!(expected_staker_rewards != prev_staker_rewards);
8793+
assert!(expected_strk_pool_rewards != prev_strk_pool_rewards);
8794+
let (expected_btc_commission_rewards, expected_btc_pool_rewards) =
8795+
calculate_staker_btc_pool_rewards_v2(
8796+
pool_balance: btc_pool_balance,
8797+
:commission,
8798+
:staking_contract,
8799+
:minting_curve_contract,
8800+
token_address: system.btc_token.contract_address(),
8801+
);
8802+
assert!(expected_btc_commission_rewards != prev_btc_commission_rewards);
8803+
assert!(expected_btc_pool_rewards != prev_btc_pool_rewards);
8804+
8805+
// Test staker balance with attestation rewards - according to Epoch 1 (post-upgrade).
8806+
system
8807+
.advance_block_into_attestation_window_custom_stake(
8808+
staker_address: staker.staker.address, stake: staker_stake + strk_pool_balance,
8809+
);
8810+
system.attest(:staker);
8811+
let staker_rewards = system.staker_claim_rewards(:staker);
8812+
assert!(staker_rewards == expected_staker_rewards + expected_btc_commission_rewards);
8813+
8814+
// Advance epoch - test delegator balances with attestation rewards - according to Epoch 1
8815+
// (post-upgrade).
8816+
system.advance_epoch(); // Epoch 3 - > 4
8817+
let strk_delegator_rewards = system
8818+
.delegator_claim_rewards(delegator: strk_delegator, pool: strk_pool);
8819+
let btc_delegator_rewards = system
8820+
.delegator_claim_rewards(delegator: btc_delegator, pool: btc_pool);
8821+
assert!(strk_delegator_rewards == expected_strk_pool_rewards);
8822+
assert!(btc_delegator_rewards == expected_btc_pool_rewards);
8823+
}
8824+
}

src/flow_test/fork_test.cairo

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,20 @@ fn delegator_change_balance_before_upgrade_rewards_consensus_flow_test() {
545545
};
546546
test_flow_mainnet(ref :flow);
547547
}
548+
549+
#[test]
550+
#[fork("MAINNET_LATEST")]
551+
fn balances_delay_flow_test() {
552+
let mut flow = flows::BalancesDelayFlow {
553+
staker: Option::None,
554+
stake_amount: Option::None,
555+
commission: Option::None,
556+
strk_delegated_amount: Option::None,
557+
btc_delegated_amount: Option::None,
558+
strk_delegator: Option::None,
559+
btc_delegator: Option::None,
560+
strk_pool: Option::None,
561+
btc_pool: Option::None,
562+
};
563+
test_flow_mainnet(ref :flow);
564+
}

0 commit comments

Comments
 (0)