From 1626c9685fdb98c6df45338d4c665f177341f22d Mon Sep 17 00:00:00 2001 From: jordansexton Date: Mon, 7 Jun 2021 21:08:24 -0500 Subject: [PATCH 1/4] handle rounding consistently --- token-lending/program/src/math/rate.rs | 10 ---------- token-lending/program/src/state/reserve.rs | 20 +++++++++++++------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/token-lending/program/src/math/rate.rs b/token-lending/program/src/math/rate.rs index c956491337d..883668ec2ab 100644 --- a/token-lending/program/src/math/rate.rs +++ b/token-lending/program/src/math/rate.rs @@ -72,16 +72,6 @@ impl Rate { Self(U128::from(scaled_val)) } - /// Round scaled decimal to u64 - pub fn try_round_u64(&self) -> Result { - let rounded_val = Self::half_wad() - .checked_add(self.0) - .ok_or(LendingError::MathOverflow)? - .checked_div(Self::wad()) - .ok_or(LendingError::MathOverflow)?; - Ok(u64::try_from(rounded_val).map_err(|_| LendingError::MathOverflow)?) - } - /// Calculates base^exp pub fn try_pow(&self, mut exp: u64) -> Result { let mut base = *self; diff --git a/token-lending/program/src/state/reserve.rs b/token-lending/program/src/state/reserve.rs index c29fa280a7a..c043fde3a25 100644 --- a/token-lending/program/src/state/reserve.rs +++ b/token-lending/program/src/state/reserve.rs @@ -555,7 +555,7 @@ impl CollateralExchangeRate { pub fn collateral_to_liquidity(&self, collateral_amount: u64) -> Result { Decimal::from(collateral_amount) .try_div(self.0)? - .try_round_u64() + .try_floor_u64() } /// Convert reserve collateral to liquidity @@ -568,7 +568,9 @@ impl CollateralExchangeRate { /// Convert reserve liquidity to collateral pub fn liquidity_to_collateral(&self, liquidity_amount: u64) -> Result { - self.0.try_mul(liquidity_amount)?.try_round_u64() + Decimal::from(liquidity_amount) + .try_mul(self.0)? + .try_floor_u64() } /// Convert reserve liquidity to collateral @@ -662,9 +664,9 @@ impl ReserveFees { if borrow_fee_rate > Rate::zero() && amount > Decimal::zero() { let need_to_assess_host_fee = host_fee_rate > Rate::zero(); let minimum_fee = if need_to_assess_host_fee { - 2 // 1 token to owner, 1 to host + 2u64 // 1 token to owner, 1 to host } else { - 1 // 1 token to owner, nothing else + 1u64 // 1 token to owner, nothing else }; let borrow_fee_amount = match fee_calculation { @@ -678,14 +680,18 @@ impl ReserveFees { } }; - let borrow_fee = borrow_fee_amount.try_round_u64()?.max(minimum_fee); - if Decimal::from(borrow_fee) >= amount { + let borrow_fee_decimal = borrow_fee_amount.max(minimum_fee.into()); + if borrow_fee_decimal >= amount { msg!("Borrow amount is too small to receive liquidity after fees"); return Err(LendingError::BorrowTooSmall.into()); } + let borrow_fee = borrow_fee_decimal.try_round_u64()?; let host_fee = if need_to_assess_host_fee { - host_fee_rate.try_mul(borrow_fee)?.try_round_u64()?.max(1) + borrow_fee_decimal + .try_mul(host_fee_rate)? + .try_round_u64()? + .max(1u64) } else { 0 }; From 5232404aceb7c2d4f62d7b5518957a13caf04785 Mon Sep 17 00:00:00 2001 From: jordansexton Date: Mon, 7 Jun 2021 21:25:37 -0500 Subject: [PATCH 2/4] remove unused method --- token-lending/program/src/math/rate.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/token-lending/program/src/math/rate.rs b/token-lending/program/src/math/rate.rs index 883668ec2ab..c404c8ff2b8 100644 --- a/token-lending/program/src/math/rate.rs +++ b/token-lending/program/src/math/rate.rs @@ -51,11 +51,6 @@ impl Rate { U128::from(WAD) } - // OPTIMIZE: use const slice when fixed in BPF toolchain - fn half_wad() -> U128 { - U128::from(HALF_WAD) - } - /// Create scaled decimal from percent value pub fn from_percent(percent: u8) -> Self { Self(U128::from(percent as u64 * PERCENT_SCALER)) From 96df47993a807265ee67bfa38ea9d61ecae91a9d Mon Sep 17 00:00:00 2001 From: jordansexton Date: Tue, 8 Jun 2021 21:02:54 -0500 Subject: [PATCH 3/4] slightly increase test compute limits --- token-lending/program/tests/borrow_obligation_liquidity.rs | 4 ++-- token-lending/program/tests/deposit_reserve_liquidity.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/token-lending/program/tests/borrow_obligation_liquidity.rs b/token-lending/program/tests/borrow_obligation_liquidity.rs index 9b4a9a53134..f6456168c6c 100644 --- a/token-lending/program/tests/borrow_obligation_liquidity.rs +++ b/token-lending/program/tests/borrow_obligation_liquidity.rs @@ -28,7 +28,7 @@ async fn test_borrow_usdc_fixed_amount() { ); // limit to track compute unit increase - test.set_bpf_compute_max_units(41_000); + test.set_bpf_compute_max_units(43_000); const USDC_TOTAL_BORROW_FRACTIONAL: u64 = 1_000 * FRACTIONAL_TO_USDC; const FEE_AMOUNT: u64 = 100; @@ -175,7 +175,7 @@ async fn test_borrow_sol_max_amount() { ); // limit to track compute unit increase - test.set_bpf_compute_max_units(42_000); + test.set_bpf_compute_max_units(43_000); const FEE_AMOUNT: u64 = 5000; const HOST_FEE_AMOUNT: u64 = 1000; diff --git a/token-lending/program/tests/deposit_reserve_liquidity.rs b/token-lending/program/tests/deposit_reserve_liquidity.rs index 424f419b6c7..0f9735296fb 100644 --- a/token-lending/program/tests/deposit_reserve_liquidity.rs +++ b/token-lending/program/tests/deposit_reserve_liquidity.rs @@ -16,7 +16,7 @@ async fn test_success() { ); // limit to track compute unit increase - test.set_bpf_compute_max_units(27_000); + test.set_bpf_compute_max_units(28_000); let user_accounts_owner = Keypair::new(); let lending_market = add_lending_market(&mut test); From 103ebf1608c554b6f6a7107a917fe02fb6b7bbe1 Mon Sep 17 00:00:00 2001 From: jordansexton Date: Wed, 9 Jun 2021 13:45:11 -0500 Subject: [PATCH 4/4] reuse existing decimal functions --- token-lending/program/src/state/reserve.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/token-lending/program/src/state/reserve.rs b/token-lending/program/src/state/reserve.rs index c043fde3a25..fd51af49ce5 100644 --- a/token-lending/program/src/state/reserve.rs +++ b/token-lending/program/src/state/reserve.rs @@ -553,8 +553,7 @@ pub struct CollateralExchangeRate(Rate); impl CollateralExchangeRate { /// Convert reserve collateral to liquidity pub fn collateral_to_liquidity(&self, collateral_amount: u64) -> Result { - Decimal::from(collateral_amount) - .try_div(self.0)? + self.decimal_collateral_to_liquidity(collateral_amount.into())? .try_floor_u64() } @@ -568,8 +567,7 @@ impl CollateralExchangeRate { /// Convert reserve liquidity to collateral pub fn liquidity_to_collateral(&self, liquidity_amount: u64) -> Result { - Decimal::from(liquidity_amount) - .try_mul(self.0)? + self.decimal_liquidity_to_collateral(liquidity_amount.into())? .try_floor_u64() }