From 00ac0dfce9e067d34d19a38f8e41abc813f78866 Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Wed, 30 Mar 2022 11:58:45 +0200 Subject: [PATCH] comments and test Signed-off-by: microwavedcola1 --- .../src/instructions/liq_token_with_token.rs | 1 + programs/mango-v4/src/state/health.rs | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/programs/mango-v4/src/instructions/liq_token_with_token.rs b/programs/mango-v4/src/instructions/liq_token_with_token.rs index c31b97b2f..254f3928d 100644 --- a/programs/mango-v4/src/instructions/liq_token_with_token.rs +++ b/programs/mango-v4/src/instructions/liq_token_with_token.rs @@ -83,6 +83,7 @@ pub fn liq_token_with_token( .native(&liab_bank); require!(liqee_liab_native.is_negative(), MangoError::SomeError); + // TODO why sum of both tokens liquidation fees? Add comment let fee_factor = I80F48::ONE + asset_bank.liquidation_fee + liab_bank.liquidation_fee; let liab_price_adjusted = liab_price * fee_factor; diff --git a/programs/mango-v4/src/state/health.rs b/programs/mango-v4/src/state/health.rs index 839581c67..6f6aab399 100644 --- a/programs/mango-v4/src/state/health.rs +++ b/programs/mango-v4/src/state/health.rs @@ -145,6 +145,12 @@ impl<'a, 'b> AccountRetriever<'a, 'b> for ScanningAccountRetriever<'a, 'b> { } } +/// There are two types of health, initial health used for opening new positions and maintenance +/// health used for liquidations. They are both calculated as a weighted sum of the assets +/// minus the liabilities but the maint. health uses slightly larger weights for assets and +/// slightly smaller weights for the liabilities. Zero is used as the bright line for both +/// i.e. if your init health falls below zero, you cannot open new positions and if your maint. health +/// falls below zero you will be liquidated. #[derive(PartialEq, Copy, Clone)] pub enum HealthType { Init, @@ -368,3 +374,33 @@ fn compute_health_detail<'a, 'b: 'a>( Ok(HealthCache { token_infos }) } + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use fixed::types::I80F48; + + #[test] + fn test_precision() { + // I80F48 can only represent until 1/2^48 + assert_ne!( + I80F48::from_num(1_u128) / I80F48::from_num(2_u128.pow(48)), + 0 + ); + assert_eq!( + I80F48::from_num(1_u128) / I80F48::from_num(2_u128.pow(49)), + 0 + ); + + // I80F48 can only represent until 14 decimal points + assert_ne!( + I80F48::from_str(format!("0.{}1", "0".repeat(13)).as_str()).unwrap(), + 0 + ); + assert_eq!( + I80F48::from_str(format!("0.{}1", "0".repeat(14)).as_str()).unwrap(), + 0 + ); + } +}