Skip to content

Commit 42fbfcf

Browse files
committed
feat: use block duration config in set_avg_block_durarion to adust the avg
1 parent d82b3d1 commit 42fbfcf

6 files changed

Lines changed: 111 additions & 10 deletions

File tree

Scarb.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,15 @@ dependencies = [
147147
[[package]]
148148
name = "starkware_utils"
149149
version = "1.0.0"
150-
source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=e1955423808045de868987b8fb0b43f5cbdf5699#e1955423808045de868987b8fb0b43f5cbdf5699"
150+
source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=7b46975d5612fb1b920bb248941030bf6c295d44#7b46975d5612fb1b920bb248941030bf6c295d44"
151151
dependencies = [
152152
"openzeppelin",
153153
]
154154

155155
[[package]]
156156
name = "starkware_utils_testing"
157157
version = "1.0.0"
158-
source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=e1955423808045de868987b8fb0b43f5cbdf5699#e1955423808045de868987b8fb0b43f5cbdf5699"
158+
source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=7b46975d5612fb1b920bb248941030bf6c295d44#7b46975d5612fb1b920bb248941030bf6c295d44"
159159
dependencies = [
160160
"openzeppelin",
161161
"snforge_std",

Scarb.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ edition = "2024_07"
66
[dependencies]
77
starknet = "2.12.0"
88
openzeppelin = "2.0.0"
9-
starkware_utils = { git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "e1955423808045de868987b8fb0b43f5cbdf5699" }
9+
starkware_utils = { git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "7b46975d5612fb1b920bb248941030bf6c295d44" }
1010

1111
[dev-dependencies]
1212
assert_macros = "2.12.0"
1313
snforge_std = "0.49.0"
14-
starkware_utils_testing = { git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "e1955423808045de868987b8fb0b43f5cbdf5699" }
14+
starkware_utils_testing = { git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "7b46975d5612fb1b920bb248941030bf6c295d44" }
1515

1616
[scripts]
1717
test = "snforge test"

src/flow_test/flow_ideas.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@
2626
- advance blocks with different block times and check the avg is calculated correctly
2727
- update_rewards for blocks in same epoch - same rewards, then advance epoch, different rewards, update rewards for blocks in same epoch - same rewards.
2828
- update rewards is not called every block, still rewards is updated correctly (miss block, miss first block in epoch, miss epoch)
29+
- set block time config and test rewards after

src/reward_supplier/reward_supplier.cairo

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ pub mod RewardSupplier {
2727
use starkware_utils::erc20::erc20_utils::CheckedIERC20DispatcherTrait;
2828
use starkware_utils::errors::OptionAuxTrait;
2929
use starkware_utils::interfaces::identity::Identity;
30-
use starkware_utils::math::utils::{ceil_of_division, mul_wide_and_div};
30+
use starkware_utils::math::utils::{Clamp, ceil_of_division, mul_wide_and_div};
3131
use starkware_utils::time::time::Timestamp;
32+
3233
pub const CONTRACT_IDENTITY: felt252 = 'Reward Supplier';
3334
pub const CONTRACT_VERSION: felt252 = '3.0.0';
3435
/// Scale factor for block duration measurements. 100 implies granularity of 100th of second.
@@ -367,11 +368,17 @@ pub mod RewardSupplier {
367368
// We calculate `num_blocks` instead of using the configured value to keep the average
368369
// accurate even if some calls are missed.
369370
let num_blocks = current_block_number - snapshot_block_number;
370-
let calculated_block_duration = mul_wide_and_div(
371+
let mut calculated_block_duration = mul_wide_and_div(
371372
lhs: time_delta, rhs: BLOCK_DURATION_SCALE, div: num_blocks,
372373
)
373374
.expect_with_err(err: Error::BLOCK_DURATION_OVERFLOW);
374-
// TODO: Adjust calculated_block_duration with MIN_BLOCK_TIME and MAX_BLOCK_TIME.
375+
// Adjust calculated_block_duration with min and max block duration.
376+
let block_duration_config = self.block_duration_config.read();
377+
calculated_block_duration = calculated_block_duration
378+
.clamp(
379+
block_duration_config.min_block_duration,
380+
block_duration_config.max_block_duration,
381+
);
375382
self.avg_block_duration.write(calculated_block_duration);
376383
}
377384
}

src/reward_supplier/test.cairo

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ use starkware_utils_testing::test_utils::{
4040
advance_block_number_global, assert_panic_with_error, cheat_caller_address_once, check_identity,
4141
};
4242
use test_utils::{
43-
StakingInitConfig, advance_epoch_global, advance_k_epochs_global, advance_time_global, fund,
44-
general_contract_system_deployment, initialize_reward_supplier_state_from_cfg, load_one_felt,
45-
stake_for_testing_using_dispatcher,
43+
StakingInitConfig, advance_epoch_global, advance_epoch_global_custom_time,
44+
advance_k_epochs_global, advance_time_global, fund, general_contract_system_deployment,
45+
initialize_reward_supplier_state_from_cfg, load_one_felt, stake_for_testing_using_dispatcher,
4646
};
4747

4848
#[test]
@@ -602,3 +602,89 @@ fn test_set_block_duration_config_assertions() {
602602
:result, expected_error: Error::INVALID_MIN_MAX_BLOCK_DURATION.describe(),
603603
);
604604
}
605+
606+
#[test]
607+
fn test_update_current_epoch_block_rewards_with_adjustments() {
608+
let mut cfg: StakingInitConfig = Default::default();
609+
general_contract_system_deployment(ref :cfg);
610+
stake_for_testing_using_dispatcher(:cfg);
611+
advance_k_epochs_global();
612+
let reward_supplier = cfg.staking_contract_info.reward_supplier;
613+
let reward_supplier_dispatcher = IRewardSupplierDispatcher {
614+
contract_address: reward_supplier,
615+
};
616+
let minting_curve_dispatcher = IMintingCurveDispatcher {
617+
contract_address: cfg.reward_supplier.minting_curve_contract,
618+
};
619+
let staking_contract = cfg.test_info.staking_contract;
620+
// First snapshot, not update avg_block_time. Rewards are calculated using the default avg block
621+
// time.
622+
cheat_caller_address_once(contract_address: reward_supplier, caller_address: staking_contract);
623+
let (_, _) = reward_supplier_dispatcher.update_current_epoch_block_rewards();
624+
let mut curr_avg_block_time = DEFAULT_AVG_BLOCK_DURATION;
625+
// Adjust avg_block_time to MIN (avg is less than min).
626+
let min_block_time = DEFAULT_BLOCK_DURATION_CONFIG.min_block_duration;
627+
advance_epoch_global_custom_time(
628+
block_time: TimeDelta { seconds: min_block_time / BLOCK_DURATION_SCALE - 1 },
629+
);
630+
cheat_caller_address_once(contract_address: reward_supplier, caller_address: staking_contract);
631+
let (strk_rewards, btc_rewards) = reward_supplier_dispatcher
632+
.update_current_epoch_block_rewards();
633+
// Test avg_block_time.
634+
curr_avg_block_time = min_block_time;
635+
let avg_block_time = load_one_felt(
636+
target: reward_supplier, storage_address: selector!("avg_block_duration"),
637+
)
638+
.try_into()
639+
.unwrap();
640+
assert!(avg_block_time == curr_avg_block_time);
641+
// Test rewards.
642+
let yearly_mint = minting_curve_dispatcher.yearly_mint();
643+
let expected_rewards = mul_wide_and_div(
644+
lhs: yearly_mint,
645+
rhs: curr_avg_block_time.into(),
646+
div: BLOCK_DURATION_SCALE.into() * SECONDS_IN_YEAR.into(),
647+
)
648+
.expect_with_err(err: InternalError::REWARDS_COMPUTATION_OVERFLOW);
649+
let expected_btc_rewards = mul_wide_and_div(
650+
lhs: expected_rewards, rhs: ALPHA, div: ALPHA_DENOMINATOR,
651+
)
652+
.unwrap();
653+
let expected_strk_rewards = expected_rewards - expected_btc_rewards;
654+
assert!(expected_strk_rewards.is_non_zero());
655+
assert!(expected_btc_rewards.is_non_zero());
656+
assert!(strk_rewards == expected_strk_rewards);
657+
assert!(btc_rewards == expected_btc_rewards);
658+
// Adjust avg_block_time to MAX (avg is more than max).
659+
let max_block_time = DEFAULT_BLOCK_DURATION_CONFIG.max_block_duration;
660+
advance_epoch_global_custom_time(
661+
block_time: TimeDelta { seconds: max_block_time / BLOCK_DURATION_SCALE + 1 },
662+
);
663+
cheat_caller_address_once(contract_address: reward_supplier, caller_address: staking_contract);
664+
let (strk_rewards, btc_rewards) = reward_supplier_dispatcher
665+
.update_current_epoch_block_rewards();
666+
// Test avg_block_time.
667+
curr_avg_block_time = max_block_time;
668+
let avg_block_time = load_one_felt(
669+
target: reward_supplier, storage_address: selector!("avg_block_duration"),
670+
)
671+
.try_into()
672+
.unwrap();
673+
assert!(avg_block_time == curr_avg_block_time);
674+
// Test rewards.
675+
let expected_rewards = mul_wide_and_div(
676+
lhs: yearly_mint,
677+
rhs: curr_avg_block_time.into(),
678+
div: BLOCK_DURATION_SCALE.into() * SECONDS_IN_YEAR.into(),
679+
)
680+
.expect_with_err(err: InternalError::REWARDS_COMPUTATION_OVERFLOW);
681+
let expected_btc_rewards = mul_wide_and_div(
682+
lhs: expected_rewards, rhs: ALPHA, div: ALPHA_DENOMINATOR,
683+
)
684+
.unwrap();
685+
let expected_strk_rewards = expected_rewards - expected_btc_rewards;
686+
assert!(expected_strk_rewards.is_non_zero());
687+
assert!(expected_btc_rewards.is_non_zero());
688+
assert!(strk_rewards == expected_strk_rewards);
689+
assert!(btc_rewards == expected_btc_rewards);
690+
}

src/test_utils.cairo

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,13 @@ pub(crate) fn advance_blocks(blocks: u64, block_duration: Seconds) {
931931
advance_time_global(time: TimeDelta { seconds: block_duration * blocks });
932932
}
933933

934+
/// Advance one epoch with the given `block_time` per block.
935+
pub(crate) fn advance_epoch_global_custom_time(block_time: TimeDelta) {
936+
advance_block_number_global(blocks: EPOCH_LENGTH.into());
937+
let time = TimeDelta { seconds: block_time.seconds * EPOCH_LENGTH.into() };
938+
advance_time_global(:time);
939+
}
940+
934941
// ---- Calculate Rewards - V0 (index based) -----
935942

936943
/// Update rewards for STRK pool.

0 commit comments

Comments
 (0)