@@ -280,7 +280,12 @@ pub fn calculate_pending_rewards(
280280 // Saturating sub handles case where reward_debt > current_value (shouldn't happen but defensive)
281281 let pending_128 = current_value. saturating_sub ( reward_debt as u128 ) ;
282282
283- u64:: try_from ( pending_128) . map_err ( |_| error ! ( HelixError :: Overflow ) )
283+ // FIXED: Divide by PRECISION to get unscaled token amount
284+ let pending_rewards = pending_128
285+ . checked_div ( PRECISION as u128 )
286+ . ok_or ( error ! ( HelixError :: Overflow ) ) ?;
287+
288+ u64:: try_from ( pending_rewards) . map_err ( |_| error ! ( HelixError :: Overflow ) )
284289}
285290
286291/// Calculate reward_debt = t_shares × share_rate with overflow protection.
@@ -515,3 +520,35 @@ mod tests {
515520 assert ! ( overflow_result. is_err( ) ) ;
516521 }
517522}
523+
524+ #[ test]
525+ fn test_calculate_pending_rewards ( ) {
526+ // PRECISION is 1_000_000_000
527+ let prec = PRECISION ;
528+
529+ // Case 1: 1 share, rate increases by 1*PRECISION
530+ // t_shares = 1, rate_start = 0, rate_end = 1*PRECISION
531+ // This corresponds to 1 token distributed to 1 share
532+ // pending should be 1 token (unscaled)
533+ let pending = calculate_pending_rewards ( 1 , prec, 0 ) . unwrap ( ) ;
534+ assert_eq ! ( pending, 1 , "Should return unscaled token amount (1)" ) ;
535+
536+ // Case 2: 1 share, rate increases by 0.5 * PRECISION
537+ // pending should be 0 (0.5 rounds down)
538+ let pending_small = calculate_pending_rewards ( 1 , prec / 2 , 0 ) . unwrap ( ) ;
539+ assert_eq ! ( pending_small, 0 , "Should round down small amounts" ) ;
540+
541+ // Case 3: Realistic scenario
542+ // t_shares = 1e12, rate increases by 100_000
543+ // rate_start = 10_000, rate_end = 110_000.
544+ // debt = 1e12 * 10_000 = 1e16.
545+ // current = 1e12 * 110_000 = 1.1e17.
546+ // diff = 1e17.
547+ // pending = 1e17 / 1e9 = 1e8 (100,000,000).
548+ let t_shares = 1_000_000_000_000u64 ;
549+ let rate_start = 10_000u64 ;
550+ let rate_end = 110_000u64 ;
551+ let debt = calculate_reward_debt ( t_shares, rate_start) . unwrap ( ) ;
552+ let pending_large = calculate_pending_rewards ( t_shares, rate_end, debt) . unwrap ( ) ;
553+ assert_eq ! ( pending_large, 100_000_000 , "Should handle large numbers correctly" ) ;
554+ }
0 commit comments