diff --git a/programs/mango-v4/src/instructions/benchmark.rs b/programs/mango-v4/src/instructions/benchmark.rs index eef660335..ad4ae1265 100644 --- a/programs/mango-v4/src/instructions/benchmark.rs +++ b/programs/mango-v4/src/instructions/benchmark.rs @@ -81,6 +81,39 @@ pub fn division_i80f48_f64(a: I80F48, b: I80F48) -> I80F48 { r } +#[inline(never)] +pub fn mul_f64(a: f64, b: f64) -> f64 { + msg!("mul_f64"); + sol_log_compute_units(); + let r = a * b; + if r.is_nan() { + panic!("nan"); // here as a side-effect to avoid reordering + } + sol_log_compute_units(); + r +} + +#[inline(never)] +pub fn mul_i80f48(a: I80F48, b: I80F48) -> I80F48 { + msg!("mul_i80f48"); + sol_log_compute_units(); + let r = a.checked_mul(b).unwrap(); + sol_log_compute_units(); + r +} + +#[inline(never)] +pub fn i80f48_to_f64(a: I80F48) -> f64 { + msg!("i80f48_to_f64"); + sol_log_compute_units(); + let r = a.to_num::(); + if r.is_nan() { + panic!("nan"); // here as a side-effect to avoid reordering + } + sol_log_compute_units(); + r +} + pub fn benchmark(_ctx: Context) -> Result<()> { // 101000 // 477 @@ -98,6 +131,8 @@ pub fn benchmark(_ctx: Context) -> Result<()> { division_i128(a.to_bits(), b.to_bits()); // 100 - 2000 CU division_i80f48_30bit(a, b); // 300 CU division_i80f48_f64(a, b); // 500 CU + mul_i80f48(a >> 64, b >> 64); // 100 CU + i80f48_to_f64(a); // 50 CU } { @@ -126,6 +161,12 @@ pub fn benchmark(_ctx: Context) -> Result<()> { division_u32(a, b); // 20 CU } + { + let a = clock.slot as f64; + let b = clock.unix_timestamp as f64; + mul_f64(a, b); // 0 CU?? + } + sol_log_compute_units(); // 100321 -> 101 msg!("msg!"); // 100079+101 -> 203 sol_log_compute_units(); // 100117 diff --git a/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs b/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs index d54d5aac6..d4d84e65b 100644 --- a/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs +++ b/programs/mango-v4/src/instructions/serum3_liq_force_cancel_orders.rs @@ -218,7 +218,7 @@ pub fn serum3_liq_force_cancel_orders( after_base_vault, before_base_vault, )? - .adjust_health_cache(&mut health_cache)?; + .adjust_health_cache(&mut health_cache, &base_bank)?; apply_vault_difference( ctx.accounts.account.key(), &mut account.borrow_mut(), @@ -227,7 +227,7 @@ pub fn serum3_liq_force_cancel_orders( after_quote_vault, before_quote_vault, )? - .adjust_health_cache(&mut health_cache)?; + .adjust_health_cache(&mut health_cache, "e_bank)?; // // Health check at the end diff --git a/programs/mango-v4/src/instructions/serum3_place_order.rs b/programs/mango-v4/src/instructions/serum3_place_order.rs index 263a3af86..d1296753a 100644 --- a/programs/mango-v4/src/instructions/serum3_place_order.rs +++ b/programs/mango-v4/src/instructions/serum3_place_order.rs @@ -340,8 +340,8 @@ pub fn serum3_place_order( require_gte!(before_vault, after_vault); // Charge the difference in vault balance to the user's account + let mut payer_bank = ctx.accounts.payer_bank.load_mut()?; let vault_difference = { - let mut payer_bank = ctx.accounts.payer_bank.load_mut()?; apply_vault_difference( ctx.accounts.account.key(), &mut account.borrow_mut(), @@ -356,7 +356,7 @@ pub fn serum3_place_order( // Health check // if let Some((mut health_cache, pre_health)) = pre_health_opt { - vault_difference.adjust_health_cache(&mut health_cache)?; + vault_difference.adjust_health_cache(&mut health_cache, &payer_bank)?; oo_difference.adjust_health_cache(&mut health_cache, &serum_market)?; account.check_health_post(&health_cache, pre_health)?; } @@ -408,8 +408,9 @@ pub struct VaultDifference { } impl VaultDifference { - pub fn adjust_health_cache(&self, health_cache: &mut HealthCache) -> Result<()> { - health_cache.adjust_token_balance(self.token_index, self.native_change)?; + pub fn adjust_health_cache(&self, health_cache: &mut HealthCache, bank: &Bank) -> Result<()> { + assert_eq!(bank.token_index, self.token_index); + health_cache.adjust_token_balance(bank, self.native_change)?; Ok(()) } } diff --git a/programs/mango-v4/src/instructions/token_liq_bankruptcy.rs b/programs/mango-v4/src/instructions/token_liq_bankruptcy.rs index 79ed7eefb..a4e36f917 100644 --- a/programs/mango-v4/src/instructions/token_liq_bankruptcy.rs +++ b/programs/mango-v4/src/instructions/token_liq_bankruptcy.rs @@ -297,7 +297,7 @@ pub fn token_liq_bankruptcy( let liab_bank = bank_ais[0].load::()?; let end_liab_native = liqee_liab.native(&liab_bank); liqee_health_cache - .adjust_token_balance(liab_token_index, cm!(end_liab_native - initial_liab_native))?; + .adjust_token_balance(&liab_bank, cm!(end_liab_native - initial_liab_native))?; // Check liqee health again let liqee_init_health = liqee_health_cache.health(HealthType::Init); diff --git a/programs/mango-v4/src/instructions/token_liq_with_token.rs b/programs/mango-v4/src/instructions/token_liq_with_token.rs index 68da55b69..d03cc230b 100644 --- a/programs/mango-v4/src/instructions/token_liq_with_token.rs +++ b/programs/mango-v4/src/instructions/token_liq_with_token.rs @@ -187,12 +187,10 @@ pub fn token_liq_with_token( let liqee_assets_native_after = liqee_asset_position.native(asset_bank); // Update the health cache + liqee_health_cache + .adjust_token_balance(&liab_bank, cm!(liqee_liab_native_after - liqee_liab_native))?; liqee_health_cache.adjust_token_balance( - liab_token_index, - cm!(liqee_liab_native_after - liqee_liab_native), - )?; - liqee_health_cache.adjust_token_balance( - asset_token_index, + &asset_bank, cm!(liqee_assets_native_after - liqee_asset_native), )?; diff --git a/programs/mango-v4/src/instructions/token_register.rs b/programs/mango-v4/src/instructions/token_register.rs index f2418a2d7..5fecc57f1 100644 --- a/programs/mango-v4/src/instructions/token_register.rs +++ b/programs/mango-v4/src/instructions/token_register.rs @@ -151,7 +151,9 @@ pub fn token_register( * net_borrows_window_size_ts, net_borrows_limit_native, net_borrows_window_native: 0, - reserved: [0; 2136], + borrow_limit_quote: f64::MAX, + collateral_limit_quote: f64::MAX, + reserved: [0; 2120], }; require_gt!(bank.max_rate, MINIMUM_MAX_RATE); diff --git a/programs/mango-v4/src/instructions/token_register_trustless.rs b/programs/mango-v4/src/instructions/token_register_trustless.rs index 9fe6e4d97..187f72232 100644 --- a/programs/mango-v4/src/instructions/token_register_trustless.rs +++ b/programs/mango-v4/src/instructions/token_register_trustless.rs @@ -126,7 +126,9 @@ pub fn token_register_trustless( * net_borrows_window_size_ts, net_borrows_limit_native: 1_000_000, net_borrows_window_native: 0, - reserved: [0; 2136], + borrow_limit_quote: f64::MAX, + collateral_limit_quote: f64::MAX, + reserved: [0; 2120], }; require_gt!(bank.max_rate, MINIMUM_MAX_RATE); diff --git a/programs/mango-v4/src/instructions/token_withdraw.rs b/programs/mango-v4/src/instructions/token_withdraw.rs index 3ebb31e18..3405722c1 100644 --- a/programs/mango-v4/src/instructions/token_withdraw.rs +++ b/programs/mango-v4/src/instructions/token_withdraw.rs @@ -146,8 +146,7 @@ pub fn token_withdraw(ctx: Context, amount: u64, allow_borrow: bo // Health check // if let Some((mut health_cache, pre_health)) = pre_health_opt { - health_cache - .adjust_token_balance(token_index, cm!(native_position_after - native_position))?; + health_cache.adjust_token_balance(&bank, cm!(native_position_after - native_position))?; account.check_health_post(&health_cache, pre_health)?; } diff --git a/programs/mango-v4/src/state/bank.rs b/programs/mango-v4/src/state/bank.rs index 81f1526ad..29839be5e 100644 --- a/programs/mango-v4/src/state/bank.rs +++ b/programs/mango-v4/src/state/bank.rs @@ -113,8 +113,25 @@ pub struct Bank { pub net_borrows_limit_native: i64, pub net_borrows_window_native: i64, + /// Soft borrow limit in native quote + /// + /// Once the borrows on the bank exceed this quote value, init_liab_weight is scaled up. + /// Set to f64::MAX to disable. + /// + /// See scaled_init_liab_weight(). + pub borrow_limit_quote: f64, + + /// Limit for collateral of deposits + /// + /// Once the deposits in the bank exceed this quote value, init_asset_weight is scaled + /// down to keep the total collateral value constant. + /// Set to f64::MAX to disable. + /// + /// See scaled_init_asset_weight(). + pub collateral_limit_quote: f64, + #[derivative(Debug = "ignore")] - pub reserved: [u8; 2136], + pub reserved: [u8; 2120], } const_assert_eq!(size_of::(), 3112); const_assert_eq!(size_of::() % 8, 0); @@ -175,7 +192,9 @@ impl Bank { net_borrows_window_size_ts: existing_bank.net_borrows_window_size_ts, last_net_borrows_window_start_ts: existing_bank.last_net_borrows_window_start_ts, net_borrows_window_native: 0, - reserved: [0; 2136], + borrow_limit_quote: f64::MAX, + collateral_limit_quote: f64::MAX, + reserved: [0; 2120], } } @@ -185,12 +204,14 @@ impl Bank { .trim_matches(char::from(0)) } + #[inline(always)] pub fn native_borrows(&self) -> I80F48 { - self.borrow_index * self.indexed_borrows + cm!(self.borrow_index * self.indexed_borrows) } + #[inline(always)] pub fn native_deposits(&self) -> I80F48 { - self.deposit_index * self.indexed_deposits + cm!(self.deposit_index * self.indexed_deposits) } /// Deposits `native_amount`. @@ -692,6 +713,47 @@ impl Bank { pub fn stable_price(&self) -> I80F48 { I80F48::from_num(self.stable_price_model.stable_price) } + + /// Returns the init asset weight, adjusted for the number of deposits on the bank. + /// + /// If max_collateral is 0, then the scaled init weight will be 0. + /// Otherwise the weight is unadjusted until max_collateral and then scaled down + /// such that scaled_init_weight * deposits remains constant. + #[inline(always)] + pub fn scaled_init_asset_weight(&self, price: I80F48) -> I80F48 { + if self.collateral_limit_quote == f64::MAX { + return self.init_asset_weight; + } + // The next line is around 500 CU + let deposits_quote = self.native_deposits().to_num::() * price.to_num::(); + if deposits_quote <= self.collateral_limit_quote { + self.init_asset_weight + } else { + // The next line is around 500 CU + let scale = self.collateral_limit_quote / deposits_quote; + cm!(self.init_asset_weight * I80F48::from_num(scale)) + } + } + + #[inline(always)] + pub fn scaled_init_liab_weight(&self, price: I80F48) -> I80F48 { + if self.borrow_limit_quote == f64::MAX { + return self.init_liab_weight; + } + // The next line is around 500 CU + let borrows_quote = self.native_borrows().to_num::() * price.to_num::(); + if borrows_quote <= self.borrow_limit_quote { + self.init_liab_weight + } else if self.borrow_limit_quote == 0.0 { + // TODO: will certainly cause overflow, so it's not exactly what is needed; health should be -MAX? + // maybe handling this case isn't super helpful? + I80F48::MAX + } else { + // The next line is around 500 CU + let scale = borrows_quote / self.borrow_limit_quote; + cm!(self.init_liab_weight * I80F48::from_num(scale)) + } + } } #[macro_export] diff --git a/programs/mango-v4/src/state/health/cache.rs b/programs/mango-v4/src/state/health/cache.rs index d113a67d7..0a4e35396 100644 --- a/programs/mango-v4/src/state/health/cache.rs +++ b/programs/mango-v4/src/state/health/cache.rs @@ -5,7 +5,7 @@ use fixed_macro::types::I80F48; use crate::error::*; use crate::state::{ - MangoAccountFixed, MangoAccountRef, PerpMarket, PerpMarketIndex, PerpPosition, + Bank, MangoAccountFixed, MangoAccountRef, PerpMarket, PerpMarketIndex, PerpPosition, Serum3MarketIndex, TokenIndex, }; use crate::util::checked_math as cm; @@ -365,10 +365,15 @@ impl HealthCache { .ok_or_else(|| error_msg!("token index {} not found", token_index)) } - pub fn adjust_token_balance(&mut self, token_index: TokenIndex, change: I80F48) -> Result<()> { - let entry_index = self.token_info_index(token_index)?; + /// Changes the cached user account token balance. + pub fn adjust_token_balance(&mut self, bank: &Bank, change: I80F48) -> Result<()> { + let entry_index = self.token_info_index(bank.token_index)?; let mut entry = &mut self.token_infos[entry_index]; + entry.init_asset_weight = + bank.scaled_init_asset_weight(entry.prices.asset(HealthType::Init)); + entry.init_liab_weight = bank.scaled_init_liab_weight(entry.prices.liab(HealthType::Init)); + // Work around the fact that -((-x) * y) == x * y does not hold for I80F48: // We need to make sure that if balance is before * price, then change = -before // brings it to exactly zero. @@ -377,6 +382,20 @@ impl HealthCache { Ok(()) } + /// Recomputes the dynamic init weights for the bank's current deposits/borrows. + pub fn recompute_token_weights(&mut self, bank: &Bank) -> Result<()> { + let entry_index = self.token_info_index(bank.token_index)?; + let mut entry = &mut self.token_infos[entry_index]; + entry.init_asset_weight = + bank.scaled_init_asset_weight(entry.prices.asset(HealthType::Init)); + entry.init_liab_weight = bank.scaled_init_liab_weight(entry.prices.liab(HealthType::Init)); + Ok(()) + } + + /// Changes the cached user account token and serum balances. + /// + /// WARNING: You must also call recompute_token_weights() after all bank + /// deposit/withdraw changes! pub fn adjust_serum3_reserved( &mut self, market_index: Serum3MarketIndex, @@ -604,16 +623,17 @@ pub fn new_health_cache( retriever.bank_and_oracle(&account.fixed.group, i, position.token_index)?; let native = position.native(bank); + let prices = Prices { + oracle: oracle_price, + stable: bank.stable_price(), + }; token_infos.push(TokenInfo { token_index: bank.token_index, maint_asset_weight: bank.maint_asset_weight, - init_asset_weight: bank.init_asset_weight, + init_asset_weight: bank.scaled_init_asset_weight(prices.asset(HealthType::Init)), maint_liab_weight: bank.maint_liab_weight, - init_liab_weight: bank.init_liab_weight, - prices: Prices { - oracle: oracle_price, - stable: bank.stable_price(), - }, + init_liab_weight: bank.scaled_init_liab_weight(prices.liab(HealthType::Init)), + prices, balance_native: native, }); } @@ -787,6 +807,14 @@ mod tests { )); } + #[derive(Default)] + struct BankSettings { + deposits: u64, + borrows: u64, + collateral_limit_quote: u64, + borrow_limit_quote: u64, + } + #[derive(Default)] struct TestHealth1Case { token1: i64, @@ -796,6 +824,7 @@ mod tests { oo_1_3: (u64, u64), perp1: (i64, i64, i64, i64), expected_health: f64, + bank_settings: [BankSettings; 3], } fn test_health1_runner(testcase: &TestHealth1Case) { let buffer = MangoAccount::default_for_tests().try_to_vec().unwrap(); @@ -830,6 +859,21 @@ mod tests { DUMMY_NOW_TS, ) .unwrap(); + for (settings, bank) in testcase + .bank_settings + .iter() + .zip([&mut bank1, &mut bank2, &mut bank3].iter_mut()) + { + let bank = bank.data(); + bank.indexed_deposits = I80F48::from(settings.deposits) / bank.deposit_index; + bank.indexed_borrows = I80F48::from(settings.borrows) / bank.borrow_index; + if settings.collateral_limit_quote > 0 { + bank.collateral_limit_quote = settings.collateral_limit_quote as f64; + } + if settings.borrow_limit_quote > 0 { + bank.borrow_limit_quote = settings.borrow_limit_quote as f64; + } + } let mut oo1 = TestAccount::::new_zeroed(); let serum3account1 = account.create_serum3_orders(2).unwrap(); @@ -995,6 +1039,66 @@ mod tests { + 20.0 * 0.8, ..Default::default() }, + TestHealth1Case { // 10, checking collateral limit + token1: 100, + token2: 100, + token3: 100, + bank_settings: [ + BankSettings { + deposits: 100, + collateral_limit_quote: 1000, + ..BankSettings::default() + }, + BankSettings { + deposits: 1500, + collateral_limit_quote: 1000 * 5, + ..BankSettings::default() + }, + BankSettings { + deposits: 10000, + collateral_limit_quote: 1000 * 10, + ..BankSettings::default() + }, + ], + expected_health: + // token1 + 0.8 * 100.0 + // token2 + + 0.5 * 100.0 * 5.0 * (5000.0 / (1500.0 * 5.0)) + // token3 + + 0.5 * 100.0 * 10.0 * (10000.0 / (10000.0 * 10.0)), + ..Default::default() + }, + TestHealth1Case { // 11, checking borrow limit + token1: -100, + token2: -100, + token3: -100, + bank_settings: [ + BankSettings { + borrows: 100, + borrow_limit_quote: 1000, + ..BankSettings::default() + }, + BankSettings { + borrows: 1500, + borrow_limit_quote: 1000 * 5, + ..BankSettings::default() + }, + BankSettings { + borrows: 10000, + borrow_limit_quote: 1000 * 10, + ..BankSettings::default() + }, + ], + expected_health: + // token1 + -1.2 * 100.0 + // token2 + - 1.5 * 100.0 * 5.0 * (1500.0 * 5.0 / 5000.0) + // token3 + - 1.5 * 100.0 * 10.0 * (10000.0 * 10.0 / 10000.0), + ..Default::default() + }, ]; for (i, testcase) in testcases.iter().enumerate() { diff --git a/programs/mango-v4/src/state/health/client.rs b/programs/mango-v4/src/state/health/client.rs index c13bf1baf..dcdc548de 100644 --- a/programs/mango-v4/src/state/health/client.rs +++ b/programs/mango-v4/src/state/health/client.rs @@ -6,7 +6,7 @@ use fixed::types::I80F48; use fixed_macro::types::I80F48; use crate::error::*; -use crate::state::{PerpMarketIndex, TokenIndex}; +use crate::state::{Bank, MangoAccountValue, PerpMarketIndex}; use crate::util::checked_math as cm; use super::*; @@ -43,6 +43,44 @@ impl HealthCache { } } + fn cache_after_swap( + &self, + account: &MangoAccountValue, + source_bank: &Bank, + target_bank: &Bank, + amount: I80F48, + price: I80F48, + ) -> Self { + let mut source_position = account + .token_position(source_bank.token_index) + .map(|v| v.clone()) + .unwrap_or_default(); + let mut target_position = account + .token_position(target_bank.token_index) + .map(|v| v.clone()) + .unwrap_or_default(); + + let target_amount = cm!(amount * price); + + let mut source_bank = source_bank.clone(); + source_bank + .withdraw_with_fee(&mut source_position, amount, 0) + .unwrap(); + let mut target_bank = target_bank.clone(); + target_bank + .deposit(&mut target_position, target_amount, 0) + .unwrap(); + + let mut resulting_cache = self.clone(); + resulting_cache + .adjust_token_balance(&source_bank, -amount) + .unwrap(); + resulting_cache + .adjust_token_balance(&target_bank, target_amount) + .unwrap(); + resulting_cache + } + /// How much source native tokens may be swapped for target tokens while staying /// above the min_ratio health ratio. /// @@ -54,8 +92,9 @@ impl HealthCache { /// NOTE: keep getMaxSourceForTokenSwap in ts/client in sync with changes here pub fn max_swap_source_for_health_ratio( &self, - source: TokenIndex, - target: TokenIndex, + account: &MangoAccountValue, + source_bank: &Bank, + target_bank: &Bank, price: I80F48, min_ratio: I80F48, ) -> Result { @@ -74,8 +113,8 @@ impl HealthCache { return Ok(I80F48::ZERO); } - let source_index = find_token_info_index(&self.token_infos, source)?; - let target_index = find_token_info_index(&self.token_infos, target)?; + let source_index = find_token_info_index(&self.token_infos, source_bank.token_index)?; + let target_index = find_token_info_index(&self.token_infos, target_bank.token_index)?; let source = &self.token_infos[source_index]; let target = &self.token_infos[target_index]; @@ -89,10 +128,7 @@ impl HealthCache { } let cache_after_swap = |amount: I80F48| { - let mut adjusted_cache = self.clone(); - adjusted_cache.token_infos[source_index].balance_native -= amount; - adjusted_cache.token_infos[target_index].balance_native += cm!(amount * price); - adjusted_cache + self.cache_after_swap(account, source_bank, target_bank, amount, price) }; let health_ratio_after_swap = |amount| cache_after_swap(amount).health_ratio(HealthType::Init); @@ -379,6 +415,15 @@ mod tests { balance_native: I80F48::ZERO, }; + let buffer = MangoAccount::default_for_tests().try_to_vec().unwrap(); + let account = MangoAccountValue::from_bytes(&buffer).unwrap(); + + let group = Pubkey::new_unique(); + let (mut bank0, _) = mock_bank_and_oracle(group, 0, 1.0, 0.1, 0.1); + let (mut bank1, _) = mock_bank_and_oracle(group, 1, 5.0, 0.2, 0.2); + let (mut bank2, _) = mock_bank_and_oracle(group, 2, 5.0, 0.3, 0.3); + let banks = [bank0.data(), bank1.data(), bank2.data()]; + let health_cache = HealthCache { token_infos: vec![ TokenInfo { @@ -407,8 +452,9 @@ mod tests { assert_eq!( health_cache .max_swap_source_for_health_ratio( - 0, - 1, + &account, + banks[0], + banks[1], I80F48::from_num(2.0 / 3.0), I80F48::from_num(50.0) ) @@ -425,15 +471,17 @@ mod tests { target: TokenIndex, ratio: f64, price_factor: f64| { - let mut c = c.clone(); let source_price = &c.token_infos[source as usize].prices; + let source_bank = &banks[source as usize]; let target_price = &c.token_infos[target as usize].prices; + let target_bank = &banks[target as usize]; let swap_price = I80F48::from_num(price_factor) * source_price.oracle / target_price.oracle; let source_amount = c .max_swap_source_for_health_ratio( - source, - target, + &account, + source_bank, + target_bank, swap_price, I80F48::from_num(ratio), ) @@ -441,12 +489,16 @@ mod tests { if source_amount == I80F48::MAX { return (f64::MAX, f64::MAX); } - c.adjust_token_balance(source, -source_amount).unwrap(); - c.adjust_token_balance(target, source_amount * swap_price) - .unwrap(); + let after_swap = c.cache_after_swap( + &account, + source_bank, + target_bank, + source_amount, + swap_price, + ); ( source_amount.to_num::(), - c.health_ratio(HealthType::Init).to_num::(), + after_swap.health_ratio(HealthType::Init).to_num::(), ) }; let check_max_swap_result = |c: &HealthCache, diff --git a/programs/mango-v4/src/state/health/test.rs b/programs/mango-v4/src/state/health/test.rs index b02569e33..e66c24003 100644 --- a/programs/mango-v4/src/state/health/test.rs +++ b/programs/mango-v4/src/state/health/test.rs @@ -95,6 +95,8 @@ pub fn mock_bank_and_oracle( bank.data().maint_asset_weight = I80F48::from_num(1.0 - maint_weights); bank.data().maint_liab_weight = I80F48::from_num(1.0 + maint_weights); bank.data().stable_price_model.reset_to_price(price, 0); + bank.data().collateral_limit_quote = f64::MAX; + bank.data().borrow_limit_quote = f64::MAX; bank.data().net_borrows_window_size_ts = 1; // dummy bank.data().net_borrows_limit_native = i64::MAX; // max since we don't want this to interfere (bank, oracle) diff --git a/programs/mango-v4/tests/test_bankrupt_tokens.rs b/programs/mango-v4/tests/test_bankrupt_tokens.rs index ae5d758a0..dcb2c3a2e 100644 --- a/programs/mango-v4/tests/test_bankrupt_tokens.rs +++ b/programs/mango-v4/tests/test_bankrupt_tokens.rs @@ -13,7 +13,9 @@ mod program_test; #[tokio::test] async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> { - let context = TestContext::new().await; + let mut test_builder = TestContextBuilder::new(); + test_builder.test().set_compute_max_units(85_000); // TokenLiqWithToken needs 84k + let context = test_builder.start_default().await; let solana = &context.solana.clone(); let admin = TestKeypair::new(); @@ -275,7 +277,9 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> { #[tokio::test] async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> { - let context = TestContext::new().await; + let mut test_builder = TestContextBuilder::new(); + test_builder.test().set_compute_max_units(85_000); // TokenLiqWithToken needs 84k + let context = test_builder.start_default().await; let solana = &context.solana.clone(); let admin = TestKeypair::new(); diff --git a/programs/mango-v4/tests/test_health_compute.rs b/programs/mango-v4/tests/test_health_compute.rs index 57afd6972..a665df64c 100644 --- a/programs/mango-v4/tests/test_health_compute.rs +++ b/programs/mango-v4/tests/test_health_compute.rs @@ -39,7 +39,7 @@ async fn test_health_compute_tokens() -> Result<(), TransportError> { create_funded_account(&solana, group, owner, 0, &context.users[1], mints, 1000, 0).await; // TODO: actual explicit CU comparisons. - // On 2022-11-18 the final deposit costs 45495 CU and each new token increases it by roughly 1729 CU + // On 2022-11-29 the final deposit costs 61568 CU and each new token increases it by roughly 3125 CU Ok(()) } @@ -47,7 +47,9 @@ async fn test_health_compute_tokens() -> Result<(), TransportError> { // Try to reach compute limits in health checks by having many serum markets in an account #[tokio::test] async fn test_health_compute_serum() -> Result<(), TransportError> { - let context = TestContext::new().await; + let mut test_builder = TestContextBuilder::new(); + test_builder.test().set_compute_max_units(80_000); + let context = test_builder.start_default().await; let solana = &context.solana.clone(); let admin = TestKeypair::new(); @@ -156,7 +158,7 @@ async fn test_health_compute_serum() -> Result<(), TransportError> { } // TODO: actual explicit CU comparisons. - // On 2022-11-18 the final deposit costs 62920 CU and each new market increases it by roughly 4820 CU + // On 2022-11-29 the final deposit costs 76029 CU and each new market increases it by roughly 6191 CU Ok(()) } @@ -272,7 +274,7 @@ async fn test_health_compute_perp() -> Result<(), TransportError> { } // TODO: actual explicit CU comparisons. - // On 2022-11-18 the final deposit costs 50502 CU and each new market increases it by roughly 3037 CU + // On 2022-11-29 the final deposit costs 54954 CU and each new market increases it by roughly 3171 CU Ok(()) } diff --git a/programs/mango-v4/tests/test_liq_tokens.rs b/programs/mango-v4/tests/test_liq_tokens.rs index 4c6c7970e..ab24be1f5 100644 --- a/programs/mango-v4/tests/test_liq_tokens.rs +++ b/programs/mango-v4/tests/test_liq_tokens.rs @@ -173,7 +173,9 @@ async fn test_liq_tokens_force_cancel() -> Result<(), TransportError> { #[tokio::test] async fn test_liq_tokens_with_token() -> Result<(), TransportError> { - let context = TestContext::new().await; + let mut test_builder = TestContextBuilder::new(); + test_builder.test().set_compute_max_units(85_000); // LiqTokenWithToken needs 79k + let context = test_builder.start_default().await; let solana = &context.solana.clone(); let admin = TestKeypair::new();