Summary
distribute_rewards computes the vesting duration as:
let ledger_duration = program.end_ledger - program.start_ledger; // u32
let vesting_duration = ledger_duration * 5; // u32 * u32 = u32, can overflow!
ledger_duration is a u32. Multiplying by 5 as a u32 operation can overflow when ledger_duration > 858,993,459 (~13 years at 5 s/ledger). The result wraps silently to a small value, making the vesting period appear much shorter than intended. The UserRewards.vesting_duration field is u64, so the fix is to cast before multiplying.
Location
contracts/rewards-distributor/src/lib.rs, distribute_rewards
let ledger_duration = program.end_ledger - program.start_ledger;
let vesting_duration = ledger_duration * 5; // ❌ u32 overflow if duration is large
Fix
let vesting_duration: u64 = (ledger_duration as u64)
.checked_mul(5)
.expect("vesting_duration overflow");
Summary
distribute_rewardscomputes the vesting duration as:ledger_durationis au32. Multiplying by 5 as au32operation can overflow whenledger_duration > 858,993,459(~13 years at 5 s/ledger). The result wraps silently to a small value, making the vesting period appear much shorter than intended. TheUserRewards.vesting_durationfield isu64, so the fix is to cast before multiplying.Location
contracts/rewards-distributor/src/lib.rs,distribute_rewardsFix