From 718e7904b4f48fdfe8cf7f1b873cb3994e39a6ae Mon Sep 17 00:00:00 2001 From: Vivek Pandya Date: Thu, 13 Jan 2022 20:12:17 +0530 Subject: [PATCH] CU-1yykjpw Fix calc_utilization_ratio() and add proptest for it. --- frame/composable-traits/src/lending/math.rs | 8 ++------ frame/composable-traits/src/rate_model.rs | 22 --------------------- frame/lending/src/tests.rs | 16 +++++++++++++++ 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/frame/composable-traits/src/lending/math.rs b/frame/composable-traits/src/lending/math.rs index 8eef34c1384..66b6c3af81b 100644 --- a/frame/composable-traits/src/lending/math.rs +++ b/frame/composable-traits/src/lending/math.rs @@ -39,15 +39,11 @@ pub fn calc_utilization_ratio( } let total = cash.safe_add(&borrows)?; - // also max value is 1.00000000000000000, it still fails with u8, so mul by u16 and cast to u8 - // safely let utilization_ratio = borrows .checked_div(&total) .expect("above checks prove it cannot error") - .checked_mul_int(100_u16) - .ok_or(ArithmeticError::Overflow)? - .try_into() - .map_err(|_| ArithmeticError::Overflow)?; + .checked_mul_int(100_u8) + .ok_or(ArithmeticError::Overflow)?; Ok(Percent::from_percent(utilization_ratio)) } diff --git a/frame/composable-traits/src/rate_model.rs b/frame/composable-traits/src/rate_model.rs index 47b299ff91b..adebe31a0ed 100644 --- a/frame/composable-traits/src/rate_model.rs +++ b/frame/composable-traits/src/rate_model.rs @@ -47,28 +47,6 @@ pub type Ratio = FixedU128; /// accounts to length of year) pub const SECONDS_PER_YEAR: DurationSeconds = 365 * 24 * ONE_HOUR; -/// utilization_ratio = total_borrows / (total_cash + total_borrows) -pub fn calc_utilization_ratio( - cash: LiftedFixedBalance, - borrows: LiftedFixedBalance, -) -> Result { - if borrows.is_zero() { - return Ok(Percent::zero()) - } - - let total = cash.safe_add(&borrows)?; - // also max value is 1.00000000000000000, it still fails with u8, so mul by u16 and cast to u8 - // safely - let utilization_ratio = borrows - .checked_div(&total) - .expect("above checks prove it cannot error") - .checked_mul_int(100_u16) - .ok_or(ArithmeticError::Overflow)? - .try_into() - .map_err(|_| ArithmeticError::Overflow)?; - Ok(Percent::from_percent(utilization_ratio)) -} - pub trait InterestRate { fn get_borrow_rate(&mut self, utilization: Percent) -> Option; } diff --git a/frame/lending/src/tests.rs b/frame/lending/src/tests.rs index ef9d070819b..a062561f054 100644 --- a/frame/lending/src/tests.rs +++ b/frame/lending/src/tests.rs @@ -331,6 +331,7 @@ fn new_jump_model() -> (Percent, InterestRateModel) { fn test_calc_utilization_ratio() { // 50% borrow assert_eq!(Lending::calc_utilization_ratio(&1, &1).unwrap(), Percent::from_percent(50)); + assert_eq!(Lending::calc_utilization_ratio(&1, &1).unwrap(), Percent::from_float(0.50)); assert_eq!(Lending::calc_utilization_ratio(&100, &100).unwrap(), Percent::from_percent(50)); // no borrow assert_eq!(Lending::calc_utilization_ratio(&1, &0).unwrap(), Percent::zero()); @@ -705,6 +706,13 @@ prop_compose! { } } +prop_compose! { + fn valid_cash_borrow()(cash in 1..u32::MAX)(borrow in 0..cash, cash in Just(cash)) + -> (u32, u32) { + (cash, borrow) + } +} + prop_compose! { fn valid_amounts_without_overflow_2() (x in MINIMUM_BALANCE..u64::MAX as Balance / 2, @@ -831,6 +839,14 @@ proptest! { })?; } + #[test] + fn calc_utilization_ratio_proptest((cash, borrow) in valid_cash_borrow()) { + new_test_ext().execute_with(|| { + prop_assert_eq!(Lending::calc_utilization_ratio(&cash.into(), &borrow.into()).unwrap(), Percent::from_float(borrow as f64 / (cash as f64 + borrow as f64))); + Ok(()) + })?; + } + #[test] fn market_creation_with_multi_level_priceable_lp(depth in 0..20) { new_test_ext().execute_with(|| {