From 6a206631df6df2a1756aa3b15b438832f8bbf6c7 Mon Sep 17 00:00:00 2001 From: Maks Nabokov Date: Wed, 22 Nov 2023 10:17:22 +0300 Subject: [PATCH 1/3] fix rounding in borrow + tests --- contracts/common-token/src/balance.rs | 6 +- contracts/common-token/src/lib.rs | 6 + contracts/common/src/fixedi128.rs | 19 + contracts/common/src/test.rs | 39 +++ contracts/pool/src/methods/borrow.rs | 2 +- contracts/pool/src/tests/borrow.rs | 8 +- contracts/pool/src/tests/collat_coeff.rs | 16 +- contracts/pool/src/tests/flash_loan.rs | 2 +- contracts/pool/src/tests/liquidate.rs | 8 +- contracts/pool/src/tests/mod.rs | 1 + contracts/pool/src/tests/repay.rs | 67 +++- contracts/pool/src/tests/rounding.rs | 132 +++++++ .../tests/snapshots/budget_utilization.snap | 330 +++++++++--------- contracts/pool/src/tests/withdraw.rs | 16 +- contracts/s-token/src/lib.rs | 13 +- 15 files changed, 460 insertions(+), 205 deletions(-) create mode 100644 contracts/pool/src/tests/rounding.rs diff --git a/contracts/common-token/src/balance.rs b/contracts/common-token/src/balance.rs index 8b823493..07a1e404 100644 --- a/contracts/common-token/src/balance.rs +++ b/contracts/common-token/src/balance.rs @@ -1,12 +1,12 @@ use soroban_sdk::{Address, Env}; -use crate::require_nonnegative_amount; +use crate::require_positive_amount; use crate::storage::{ is_authorized, read_balance, read_total_supply, write_balance, write_total_supply, }; pub fn receive_balance(e: &Env, addr: Address, amount: i128) { - require_nonnegative_amount(amount); + require_positive_amount(amount); let balance = read_balance(e, addr.clone()); if !is_authorized(e, addr.clone()) { panic!("can't receive when deauthorized"); @@ -15,7 +15,7 @@ pub fn receive_balance(e: &Env, addr: Address, amount: i128) { } pub fn spend_balance(e: &Env, addr: Address, amount: i128) { - require_nonnegative_amount(amount); + require_positive_amount(amount); let balance = read_balance(e, addr.clone()); if !is_authorized(e, addr.clone()) { panic!("can't spend when deauthorized"); diff --git a/contracts/common-token/src/lib.rs b/contracts/common-token/src/lib.rs index fdd1c4da..e9641d0c 100644 --- a/contracts/common-token/src/lib.rs +++ b/contracts/common-token/src/lib.rs @@ -17,3 +17,9 @@ pub fn require_nonnegative_amount(amount: i128) { panic!("negative amount is not allowed: {}", amount) } } + +pub fn require_positive_amount(amount: i128) { + if amount <= 0 { + panic!("zero or negative amount is not allowed: {}", amount) + } +} diff --git a/contracts/common/src/fixedi128.rs b/contracts/common/src/fixedi128.rs index 9c5ff838..e15c914b 100644 --- a/contracts/common/src/fixedi128.rs +++ b/contracts/common/src/fixedi128.rs @@ -90,6 +90,25 @@ impl FixedI128 { .checked_div(self.0) } + /// Calculates division of non fixed int value and fixed value, e.g. other / self and rounds towards infinity. + /// Result is int value + pub fn recip_mul_int_ceil>(self, other: T) -> Option { + let other = other.into(); + if other == 0 { + return Some(0); + } + let mb_res = Self::DENOMINATOR.checked_mul(other)?.checked_div(self.0); + mb_res.map(|res| { + if res == 0 { + 1 + } else if other >= self.0 && other % self.0 == 0 { + res + } else { + res + 1 + } + }) + } + /// Multiply inner value of fixed pub fn mul_inner>(self, value: T) -> Option { self.0.checked_mul(value.into()).map(FixedI128) diff --git a/contracts/common/src/test.rs b/contracts/common/src/test.rs index c10f3eae..283e3398 100644 --- a/contracts/common/src/test.rs +++ b/contracts/common/src/test.rs @@ -111,4 +111,43 @@ mod fixedi128 { let zero = FixedI128::from_inner(0); assert_eq!(zero.recip_mul_int(value), None); } + + #[test] + fn recip_mul_int_ceil() { + let inner = 1000054757; + let fixed = FixedI128::from_inner(inner); + let value = 1; + assert_eq!(fixed.recip_mul_int_ceil(value).unwrap(), 1); + + let value2 = 2; + assert_eq!(fixed.recip_mul_int_ceil(value2).unwrap(), 2); + + let zero = FixedI128::from_inner(0); + assert_eq!(zero.recip_mul_int_ceil(value), None); + + assert_eq!( + fixed.recip_mul_int_ceil(inner).unwrap(), + FixedI128::DENOMINATOR + ); + + let zero = 0; + assert_eq!(fixed.recip_mul_int_ceil(zero).unwrap(), 0); + + assert_eq!( + fixed.recip_mul_int_ceil(inner + 1).unwrap(), + FixedI128::DENOMINATOR + 1 + ); + assert_eq!( + fixed.recip_mul_int_ceil(inner + 2).unwrap(), + FixedI128::DENOMINATOR + 2 + ); + assert_eq!( + fixed.recip_mul_int_ceil(inner + 9).unwrap(), + FixedI128::DENOMINATOR + 9 + ); + assert_eq!( + fixed.recip_mul_int_ceil(inner + 10).unwrap(), + FixedI128::DENOMINATOR + 10 + ); + } } diff --git a/contracts/pool/src/methods/borrow.rs b/contracts/pool/src/methods/borrow.rs index f1611e7d..54fdbeeb 100644 --- a/contracts/pool/src/methods/borrow.rs +++ b/contracts/pool/src/methods/borrow.rs @@ -103,7 +103,7 @@ pub fn do_borrow( let debt_coeff = get_actual_borrower_accrued_rate(env, reserve)?; let amount_of_debt_token = debt_coeff - .recip_mul_int(amount) + .recip_mul_int_ceil(amount) .ok_or(Error::MathOverflowError)?; require_util_cap_not_exceeded( diff --git a/contracts/pool/src/tests/borrow.rs b/contracts/pool/src/tests/borrow.rs index c0d2390a..e57c9e5e 100644 --- a/contracts/pool/src/tests/borrow.rs +++ b/contracts/pool/src/tests/borrow.rs @@ -310,16 +310,16 @@ fn should_change_balances_when_borrow_and_repay() { assert_eq!(underlying_supply_before, 100_000_000); assert_eq!(treasury_after_borrow, 0); - assert_eq!(debt_balance_after_borrow, 20_000_000); - assert_eq!(debt_total_after_borrow, 20_000_000); + assert_eq!(debt_balance_after_borrow, 20_000_001); + assert_eq!(debt_total_after_borrow, 20_000_001); assert_eq!(borrower_balance_after_borrow, 1_020_000_000); assert_eq!(underlying_supply_after_borrow, 80_000_000); assert_eq!(treasury_after_repay, 37_156); assert_eq!(debt_balance_after_repay, 0); assert_eq!(debt_total_after_repay, 0); - assert_eq!(borrower_balance_after_repay, 999_954_790); - assert_eq!(underlying_supply_after_repay, 100_008_054); + assert_eq!(borrower_balance_after_repay, 999_954_789); + assert_eq!(underlying_supply_after_repay, 100_008_055); } #[test] diff --git a/contracts/pool/src/tests/collat_coeff.rs b/contracts/pool/src/tests/collat_coeff.rs index 338cab07..0b7272fc 100644 --- a/contracts/pool/src/tests/collat_coeff.rs +++ b/contracts/pool/src/tests/collat_coeff.rs @@ -59,11 +59,11 @@ fn should_update_when_deposit_borrow_withdraw_liquidate() { env.ledger().with_mut(|l| l.timestamp = 6 * DAY); let collat_coeff_after_liquidate = sut.pool.collat_coeff(&debt_token); - assert_eq!(collat_coeff_initial, 1_000_000_000); - assert_eq!(collat_coeff_after_withdraw, 1_000_000_000); - assert_eq!(collat_coeff_after_borrow, 1_000_199_480); - assert_eq!(collat_coeff_after_price_change, 1_000_265_990); - assert_eq!(collat_coeff_after_liquidate, 1_000_295_540); + assert_eq!(collat_coeff_initial, 1_000_000_010); + assert_eq!(collat_coeff_after_withdraw, 1_000_000_010); + assert_eq!(collat_coeff_after_borrow, 1_000_199_500); + assert_eq!(collat_coeff_after_price_change, 1_000_266_010); + assert_eq!(collat_coeff_after_liquidate, 1_000_295_560); } #[test] @@ -83,9 +83,9 @@ fn should_change_over_time() { env.ledger().with_mut(|l| l.timestamp = 5 * DAY); let collat_coeff_3 = sut.pool.collat_coeff(&debt_token); - assert_eq!(collat_coeff_1, 1_000_330_690); - assert_eq!(collat_coeff_2, 1_000_440_950); - assert_eq!(collat_coeff_3, 1_000_551_210); + assert_eq!(collat_coeff_1, 1_000_330_700); + assert_eq!(collat_coeff_2, 1_000_440_960); + assert_eq!(collat_coeff_3, 1_000_551_220); } #[test] diff --git a/contracts/pool/src/tests/flash_loan.rs b/contracts/pool/src/tests/flash_loan.rs index 4cb4a83e..d52277e9 100644 --- a/contracts/pool/src/tests/flash_loan.rs +++ b/contracts/pool/src/tests/flash_loan.rs @@ -167,7 +167,7 @@ fn should_borrow_if_borrowing_specified_on_asset() { let borrower_debt_after = sut.reserves[2].debt_token.balance(&borrower); assert_eq!(borrower_debt_before, 0); - assert_eq!(borrower_debt_after, 3000000); + assert_eq!(borrower_debt_after, 3000001); } #[test] diff --git a/contracts/pool/src/tests/liquidate.rs b/contracts/pool/src/tests/liquidate.rs index 2b272072..822e13d7 100644 --- a/contracts/pool/src/tests/liquidate.rs +++ b/contracts/pool/src/tests/liquidate.rs @@ -198,7 +198,7 @@ fn should_liquidate_and_receive_collateral_partially() { assert_eq!(underlying_2_supply_before, 150_000_000); assert_eq!(borrower_stoken_0_balance_before, 1_000_000); assert_eq!(borrower_stoken_2_balance_before, 50_000_000); - assert_eq!(borrower_debt_balance_before, 60_000_000); + assert_eq!(borrower_debt_balance_before, 60_000_001); assert_eq!(liquidator_repayment_balance_before, 1_000_000_000); assert_eq!(liquidator_underlying_0_balance_before, 0); assert_eq!(liquidator_underlying_2_balance_before, 0); @@ -207,7 +207,7 @@ fn should_liquidate_and_receive_collateral_partially() { assert_eq!(underlying_0_supply_after_partial_liquidation, 1_000_000); assert_eq!(borrower_stoken_0_balance_after_partial_liquidation, 0); - assert_eq!(borrower_debt_balance_after_partial_liquidation, 15_055_058); + assert_eq!(borrower_debt_balance_after_partial_liquidation, 15_055_059); assert_eq!( liquidator_repayment_balance_after_partial_liquidation, 955_000_000 @@ -307,7 +307,7 @@ fn should_receive_stokens_when_requested() { assert_eq!(underlying_2_supply_before, 150_000_000); assert_eq!(borrower_stoken_1_balance_before, 1_000_000); assert_eq!(borrower_stoken_2_balance_before, 50_000_000); - assert_eq!(borrower_debt_balance_before, 60_000_000); + assert_eq!(borrower_debt_balance_before, 60_000_001); assert_eq!(liquidator_repayment_balance_before, 1_000_000_000); assert_eq!(liquidator_underlying_1_balance_before, 0); assert_eq!(liquidator_underlying_2_balance_before, 0); @@ -328,7 +328,7 @@ fn should_receive_stokens_when_requested() { assert_eq!(borrower_debt_balance_after_full_liquidation, 0); assert_eq!( liquidator_repayment_balance_after_full_liquidation, - 939_933_589 + 939_933_588 ); assert_eq!( liquidator_stoken_2_balance_after_full_liquidation, diff --git a/contracts/pool/src/tests/mod.rs b/contracts/pool/src/tests/mod.rs index e90b2c63..7d5cdc64 100644 --- a/contracts/pool/src/tests/mod.rs +++ b/contracts/pool/src/tests/mod.rs @@ -16,6 +16,7 @@ pub mod liquidate; pub mod paused; pub mod rates; pub mod repay; +pub mod rounding; pub mod set_as_collateral; pub mod set_base_asset; pub mod set_flash_loan_fee; diff --git a/contracts/pool/src/tests/repay.rs b/contracts/pool/src/tests/repay.rs index 11a4d913..b93995a0 100644 --- a/contracts/pool/src/tests/repay.rs +++ b/contracts/pool/src/tests/repay.rs @@ -24,7 +24,7 @@ fn should_partially_repay() { assert_eq!(stoken_underlying_balance, 60_000_000); assert_eq!(user_balance, 1_040_000_000); assert_eq!(treasury_balance, 0); - assert_eq!(user_debt_balance, 40_000_000); + assert_eq!(user_debt_balance, 40_000_001); sut.pool.repay(&borrower, &debt_token, &20_000_000i128); @@ -36,7 +36,7 @@ fn should_partially_repay() { assert_eq!(stoken_underlying_balance, 79_997_089); assert_eq!(user_balance, 1_020_000_000); assert_eq!(treasury_balance, 2_911); - assert_eq!(user_debt_balance, 20_004_548); + assert_eq!(user_debt_balance, 20_004_549); } #[test] @@ -60,7 +60,7 @@ fn should_fully_repay() { assert_eq!(stoken_underlying_balance, 60_000_000); assert_eq!(user_balance, 1_040_000_000); assert_eq!(treasury_balance, 0); - assert_eq!(user_debt_balance, 40_000_000); + assert_eq!(user_debt_balance, 40_000_001); sut.pool.repay(&borrower, &debt_token, &i128::MAX); @@ -69,8 +69,8 @@ fn should_fully_repay() { let treasury_balance = debt_config.token.balance(&treasury_address); let user_debt_balance = debt_config.debt_token.balance(&borrower); - assert_eq!(stoken_underlying_balance, 100_003_274); - assert_eq!(user_balance, 999_990_903); + assert_eq!(stoken_underlying_balance, 100_003_275); + assert_eq!(user_balance, 999_990_902); assert_eq!(treasury_balance, 5_823); assert_eq!(user_debt_balance, 0); } @@ -174,8 +174,63 @@ fn should_emit_events() { ( sut.pool.address.clone(), (Symbol::new(&env, "repay"), borrower.clone()).into_val(&env), - (debt_token, 40_009_097i128).into_val(&env) + (debt_token, 40_009_098i128).into_val(&env) ), ] ); } + +#[test] +fn ceil() { + extern crate std; + let env = Env::default(); + env.mock_all_auths(); + let sut = init_pool(&env, false); + let (_, _, _debt_config) = fill_pool(&env, &sut, true); + // let _asset_to_borrow = &debt_config.token.address; + // let attacker = Address::random(&env); + // sut.reserves[0].token_admin.mint(&attacker, &9999999999999999999); + // sut.pool + // .deposit(&attacker, &sut.reserves[0].token.address, &99999999999999999999); + + // sut.pool.borrow(&attacker, asset_to_borrow, &1); + // let debt_token_balance = debt_config.debt_token.balance(&attacker); + // std::println!("{:?} borrow", debt_token_balance); + + // let mut i = 1; + // let input = loop { + // env.budget().reset_unlimited(); + // sut.pool.borrow(&attacker, asset_to_borrow, &i); + // let debt_token_balance = debt_config.debt_token.balance(&attacker); + // std::println!("{:?} borrow", debt_token_balance); + // if debt_token_balance == 0 { + // std::println!("{:?} borrow", debt_token_balance); + // break i; + // } + // // if debt_token_balance > 0 { + // // std::println!("{:?} borrow", debt_token_balance); + // // break i; + // // } + // // let collateral_amount = r.deposit_liquidity(i).unwrap(); + // // let output = r.redeem_collateral(collateral_amount).unwrap(); + // if i == 1 { + // continue; + // } + // sut.pool.repay(&attacker, asset_to_borrow, &(i - 1)); + + // let debt_token_balance = debt_config.debt_token.balance(&attacker); + // // let debt_coeff = sut.pool.debt_coeff(asset_to_borrow); + + // if debt_token_balance == 0 { + // std::println!("repay"); + // break i; + // } + + // i += 1; + + // sut.pool.repay(&attacker, &asset_to_borrow, &i128::MAX); + + // // token balance after full repay ? + // }; + // std::println!("{:?}", input); +} diff --git a/contracts/pool/src/tests/rounding.rs b/contracts/pool/src/tests/rounding.rs new file mode 100644 index 00000000..7321870d --- /dev/null +++ b/contracts/pool/src/tests/rounding.rs @@ -0,0 +1,132 @@ +use soroban_sdk::{testutils::Address as _, Address, Env}; + +use crate::tests::sut::{fill_pool, init_pool}; + +#[test] +fn rounding_deposit_withdraw() { + extern crate std; + + let env = Env::default(); + env.mock_all_auths(); + + let sut = init_pool(&env, false); + let (_, _borrower, debt_config) = fill_pool(&env, &sut, true); + let token_address = debt_config.token.address.clone(); + + let attacker = Address::random(&env); + sut.reserves[1] + .token_admin + .mint(&attacker, &100_000_000_000); + + std::println!("collat coeff {:?}", sut.pool.collat_coeff(&token_address)); + std::println!("debt coeff {:?}", sut.pool.debt_coeff(&token_address)); + // i = 1 will panic with s-token: invalid mint amount, cause mint_amount would be equal to 0 + for i in 2..101 { + env.budget().reset_unlimited(); + + let balance_before = sut.reserves[1].token.balance(&attacker); + let s_balance_before = sut.reserves[1].s_token.balance(&attacker); + + sut.pool.deposit(&attacker, &token_address, &i); + + let s_balance_after_deposit = sut.reserves[1].s_token.balance(&attacker); + + let s_token_balance = sut.reserves[1].s_token.balance(&attacker); + if s_token_balance == 0 || s_token_balance >= i { + std::println!("input {:?}, output {:?}", i, s_token_balance); + panic!(); + } + + sut.pool.withdraw(&attacker, &token_address, &i, &attacker); + + let s_balance_after_withdraw = sut.reserves[1].s_token.balance(&attacker); + + if s_balance_after_deposit <= s_balance_before + || s_balance_after_withdraw > s_balance_after_deposit + { + std::println!("{:?}: s_balance_before {:?}, s_balance_after_deposit {:?}, s_balance_after_withdraw {:?}", + i, + s_balance_before, + s_balance_after_deposit, + s_balance_after_withdraw); + panic!(); + } + + let balance_after = sut.reserves[1].token.balance(&attacker); + + if balance_after > balance_before { + std::println!( + "{:?}: balance_before: {:?} balance_after: {:?}", + i, + balance_before, + balance_after + ); + panic!(); + } + } +} + +#[test] +fn rounding_borrow_repay() { + extern crate std; + + let env = Env::default(); + env.mock_all_auths(); + + let sut = init_pool(&env, false); + let (_, _borrower, _debt_config) = fill_pool(&env, &sut, true); + let token_address = sut.reserves[1].token.address.clone(); + + let attacker = Address::random(&env); + sut.reserves[0] + .token_admin + .mint(&attacker, &100_000_000_000); + sut.pool + .deposit(&attacker, &sut.reserves[0].token.address, &100_000_000_000); + + std::println!("collat coeff {:?}", sut.pool.collat_coeff(&token_address)); + std::println!("debt coeff {:?}", sut.pool.debt_coeff(&token_address)); + // i = 1 will panic with zero or negative amount is not allowed, cause mint_amount would be equal to 0 + for i in 2..101 { + env.budget().reset_unlimited(); + + let balance_before = sut.reserves[1].token.balance(&attacker); + let d_balance_before = sut.reserves[1].debt_token.balance(&attacker); + + sut.pool.borrow(&attacker, &token_address, &i); + + let d_balance_after_borrow = sut.reserves[1].debt_token.balance(&attacker); + + if d_balance_after_borrow == 0 { + std::println!("input {:?}, output {:?}", i, d_balance_after_borrow); + panic!(); + } + + sut.pool.repay(&attacker, &token_address, &i); + + let d_balance_after_repay = sut.reserves[1].debt_token.balance(&attacker); + + if d_balance_after_borrow <= d_balance_before + || d_balance_after_repay == d_balance_after_borrow + { + std::println!("{:?}: d_balance_before {:?}, d_balance_after_borrow {:?}, d_balance_after_repay {:?}", + i, + d_balance_before, + d_balance_after_borrow, + d_balance_after_repay); + panic!(); + } + + let balance_after = sut.reserves[1].token.balance(&attacker); + + if balance_after > balance_before { + std::println!( + "{:?}: balance_before: {:?} balance_after: {:?}", + i, + balance_before, + balance_after + ); + panic!(); + } + } +} diff --git a/contracts/pool/src/tests/snapshots/budget_utilization.snap b/contracts/pool/src/tests/snapshots/budget_utilization.snap index 840f5258..aaa321e4 100644 --- a/contracts/pool/src/tests/snapshots/budget_utilization.snap +++ b/contracts/pool/src/tests/snapshots/budget_utilization.snap @@ -1,402 +1,402 @@ ['pool::tests::budget::init_reserve'] = { - "cpu_cost": 371302, + "cpu_cost": 371590, "memory_cost": 28587, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::account_position'] = { - "cpu_cost": 43957203, - "memory_cost": 6789390, + "cpu_cost": 44091794, + "memory_cost": 6800457, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::configure_as_collateral'] = { - "cpu_cost": 35628815, - "memory_cost": 3841371, + "cpu_cost": 35780356, + "memory_cost": 3852438, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::borrow'] = { - "cpu_cost": 64409623, - "memory_cost": 10707043, +['pool::tests::budget::get_reserve'] = { + "cpu_cost": 35133143, + "memory_cost": 3784973, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::flash_loan_fee'] = { - "cpu_cost": 34904982, - "memory_cost": 3772160, +['pool::tests::budget::borrow'] = { + "cpu_cost": 64568216, + "memory_cost": 10718964, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::get_reserve'] = { - "cpu_cost": 34984263, - "memory_cost": 3773906, +['pool::tests::budget::enable_borrowing_on_reserve'] = { + "cpu_cost": 35748767, + "memory_cost": 3850763, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::enable_borrowing_on_reserve'] = { - "cpu_cost": 35597046, - "memory_cost": 3839696, +['pool::tests::budget::flash_loan_fee'] = { + "cpu_cost": 35052242, + "memory_cost": 3783227, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::flash_loan_without_borrow'] = { - "cpu_cost": 80025961, - "memory_cost": 12059255, + "cpu_cost": 80207466, + "memory_cost": 12072355, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::flash_loan_with_borrow'] = { - "cpu_cost": 130552616, - "memory_cost": 24058514, + "cpu_cost": 129524883, + "memory_cost": 23923120, "cpu_limit_exceeded": true, "memory_limit_exceeded": false, } -['pool::tests::budget::collat_coeff'] = { - "cpu_cost": 35828094, - "memory_cost": 3849553, +['pool::tests::budget::debt_coeff'] = { + "cpu_cost": 35405025, + "memory_cost": 3812108, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::debt_coeff'] = { - "cpu_cost": 35255485, - "memory_cost": 3801041, +['pool::tests::budget::collat_coeff'] = { + "cpu_cost": 35971340, + "memory_cost": 3860620, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::ir_params'] = { - "cpu_cost": 35027230, - "memory_cost": 3784848, +['pool::tests::budget::deposit'] = { + "cpu_cost": 50519326, + "memory_cost": 6167430, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::deposit'] = { - "cpu_cost": 50364141, - "memory_cost": 6155794, +['pool::tests::budget::ir_params'] = { + "cpu_cost": 35174814, + "memory_cost": 3795915, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::paused'] = { - "cpu_cost": 34890910, - "memory_cost": 3771950, + "cpu_cost": 35039466, + "memory_cost": 3783017, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::price_feed'] = { - "cpu_cost": 34922719, - "memory_cost": 3772619, + "cpu_cost": 35073399, + "memory_cost": 3783686, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::liquidate_receive_stoken_when_borrower_has_two_debts'] = { - "cpu_cost": 65742115, - "memory_cost": 10871135, +['pool::tests::budget::set_base_asset'] = { + "cpu_cost": 35495713, + "memory_cost": 3835271, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_price_feed'] = { - "cpu_cost": 339615, + "cpu_cost": 339819, "memory_cost": 23419, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::set_base_asset'] = { - "cpu_cost": 35346587, - "memory_cost": 3824204, +['pool::tests::budget::set_flash_loan_fee'] = { + "cpu_cost": 35488545, + "memory_cost": 3834865, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::liquidate_receive_stoken_when_borrower_has_one_debt'] = { - "cpu_cost": 66446186, - "memory_cost": 10919001, +['pool::tests::budget::liquidate_receive_stoken_when_borrower_has_two_debts'] = { + "cpu_cost": 65892927, + "memory_cost": 10883056, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::treasury'] = { - "cpu_cost": 79428, - "memory_cost": 5627, +['pool::tests::budget::set_ir_params'] = { + "cpu_cost": 35532234, + "memory_cost": 3836976, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::set_flash_loan_fee'] = { - "cpu_cost": 35339815, - "memory_cost": 3823798, +['pool::tests::budget::treasury'] = { + "cpu_cost": 79428, + "memory_cost": 5627, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::set_ir_params'] = { - "cpu_cost": 35384224, - "memory_cost": 3825909, +['pool::tests::budget::liquidate_receive_stoken_when_borrower_has_one_debt'] = { + "cpu_cost": 66613891, + "memory_cost": 10930922, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::repay_full'] = { - "cpu_cost": 45203115, - "memory_cost": 5814798, +['pool::tests::budget::set_pause'] = { + "cpu_cost": 35479035, + "memory_cost": 3834825, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::s_token_transfer'] = { - "cpu_cost": 55805579, - "memory_cost": 8899590, + "cpu_cost": 55959186, + "memory_cost": 8911226, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::set_pause'] = { - "cpu_cost": 35329621, - "memory_cost": 3823758, +['pool::tests::budget::liquidate_receive_underlying_when_borrower_has_two_debts'] = { + "cpu_cost": 66310160, + "memory_cost": 10884380, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::liquidate_receive_underlying_when_borrower_has_one_debt'] = { - "cpu_cost": 66808345, - "memory_cost": 10925465, + "cpu_cost": 66963533, + "memory_cost": 10937386, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::liquidate_receive_underlying_when_borrower_has_two_debts'] = { - "cpu_cost": 66177806, - "memory_cost": 10872459, +['pool::tests::budget::repay_partial'] = { + "cpu_cost": 45390280, + "memory_cost": 5816908, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::set_as_collateral'] = { - "cpu_cost": 42678266, - "memory_cost": 6706198, +['pool::tests::budget::repay_full'] = { + "cpu_cost": 45353784, + "memory_cost": 5826150, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::repay_partial'] = { - "cpu_cost": 45234770, - "memory_cost": 5805556, +['pool::tests::budget::set_reserve_status'] = { + "cpu_cost": 35740354, + "memory_cost": 3850721, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::set_reserve_status'] = { - "cpu_cost": 35592926, - "memory_cost": 3839654, +['pool::tests::budget::set_as_collateral'] = { + "cpu_cost": 42832594, + "memory_cost": 6717265, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::upgrade_debt_token'] = { - "cpu_cost": 41061575, - "memory_cost": 5411111, + "cpu_cost": 41219011, + "memory_cost": 5422463, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::stoken_underlying_balance'] = { - "cpu_cost": 34931712, - "memory_cost": 3774628, +['pool::tests::budget::upgrade'] = { + "cpu_cost": 35387907, + "memory_cost": 3823695, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::upgrade'] = { - "cpu_cost": 35239879, - "memory_cost": 3812628, +['pool::tests::budget::upgrade_s_token'] = { + "cpu_cost": 46933386, + "memory_cost": 5847514, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } -['pool::tests::budget::upgrade_s_token'] = { - "cpu_cost": 46779615, - "memory_cost": 5835878, +['pool::tests::budget::stoken_underlying_balance'] = { + "cpu_cost": 35079944, + "memory_cost": 3785695, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::user_configuration'] = { - "cpu_cost": 34643849, - "memory_cost": 3755636, + "cpu_cost": 34794058, + "memory_cost": 3766703, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::withdraw_partial'] = { - "cpu_cost": 58231406, - "memory_cost": 9078585, + "cpu_cost": 58329534, + "memory_cost": 9090221, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::withdraw_full'] = { - "cpu_cost": 58331419, - "memory_cost": 9088257, + "cpu_cost": 58488997, + "memory_cost": 9099893, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::account_position'] = { - "cpu_cost": 43951716, - "memory_cost": 6789390, + "cpu_cost": 44089511, + "memory_cost": 6800457, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::borrow'] = { - "cpu_cost": 64408127, - "memory_cost": 10707043, + "cpu_cost": 64564470, + "memory_cost": 10718964, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::collat_coeff'] = { - "cpu_cost": 35828342, - "memory_cost": 3849553, + "cpu_cost": 35979160, + "memory_cost": 3860620, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::configure_as_collateral'] = { - "cpu_cost": 35637401, - "memory_cost": 3841371, + "cpu_cost": 35776927, + "memory_cost": 3852438, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::debt_coeff'] = { - "cpu_cost": 35258203, - "memory_cost": 3801041, + "cpu_cost": 35406105, + "memory_cost": 3812108, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::deposit'] = { - "cpu_cost": 50368274, - "memory_cost": 6155794, + "cpu_cost": 50532237, + "memory_cost": 6167430, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::enable_borrowing_on_reserve'] = { - "cpu_cost": 35592213, - "memory_cost": 3839696, + "cpu_cost": 35750891, + "memory_cost": 3850763, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::flash_loan_fee'] = { - "cpu_cost": 34904658, - "memory_cost": 3772160, + "cpu_cost": 35053862, + "memory_cost": 3783227, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::flash_loan_with_borrow'] = { - "cpu_cost": 130532180, - "memory_cost": 24058514, + "cpu_cost": 129534089, + "memory_cost": 23923120, "cpu_limit_exceeded": true, "memory_limit_exceeded": false, } ['pool::tests::budget::flash_loan_without_borrow'] = { - "cpu_cost": 80019786, - "memory_cost": 12059255, + "cpu_cost": 80217016, + "memory_cost": 12072355, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::get_reserve'] = { - "cpu_cost": 34984587, - "memory_cost": 3773906, + "cpu_cost": 35132819, + "memory_cost": 3784973, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::init_reserve'] = { - "cpu_cost": 368998, + "cpu_cost": 371338, "memory_cost": 28587, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::ir_params'] = { - "cpu_cost": 35026906, - "memory_cost": 3784848, + "cpu_cost": 35175786, + "memory_cost": 3795915, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::liquidate_receive_stoken_when_borrower_has_one_debt'] = { - "cpu_cost": 66446649, - "memory_cost": 10919001, + "cpu_cost": 66604964, + "memory_cost": 10930922, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::liquidate_receive_stoken_when_borrower_has_two_debts'] = { - "cpu_cost": 65752240, - "memory_cost": 10871135, + "cpu_cost": 65887044, + "memory_cost": 10883056, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::liquidate_receive_underlying_when_borrower_has_one_debt'] = { - "cpu_cost": 66810966, - "memory_cost": 10925465, + "cpu_cost": 66979344, + "memory_cost": 10937386, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::liquidate_receive_underlying_when_borrower_has_two_debts'] = { - "cpu_cost": 66177327, - "memory_cost": 10872459, + "cpu_cost": 66333619, + "memory_cost": 10884380, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::paused'] = { - "cpu_cost": 34891882, - "memory_cost": 3771950, + "cpu_cost": 35039790, + "memory_cost": 3783017, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::price_feed'] = { - "cpu_cost": 34924843, - "memory_cost": 3772619, + "cpu_cost": 35070303, + "memory_cost": 3783686, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::repay_full'] = { - "cpu_cost": 45227305, - "memory_cost": 5814798, + "cpu_cost": 45385067, + "memory_cost": 5826150, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::repay_partial'] = { - "cpu_cost": 45240891, - "memory_cost": 5805556, + "cpu_cost": 45383913, + "memory_cost": 5816908, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::s_token_transfer'] = { - "cpu_cost": 55816602, - "memory_cost": 8899590, + "cpu_cost": 55972302, + "memory_cost": 8911226, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_as_collateral'] = { - "cpu_cost": 42693776, - "memory_cost": 6706198, + "cpu_cost": 42819283, + "memory_cost": 6717265, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_base_asset'] = { - "cpu_cost": 35346443, - "memory_cost": 3824204, + "cpu_cost": 35496001, + "memory_cost": 3835271, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_flash_loan_fee'] = { - "cpu_cost": 35339311, - "memory_cost": 3823798, + "cpu_cost": 35489409, + "memory_cost": 3834865, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_ir_params'] = { - "cpu_cost": 35384440, - "memory_cost": 3825909, + "cpu_cost": 35533026, + "memory_cost": 3836976, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_pause'] = { - "cpu_cost": 35329801, - "memory_cost": 3823758, + "cpu_cost": 35477415, + "memory_cost": 3834825, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_price_feed'] = { - "cpu_cost": 338307, + "cpu_cost": 338391, "memory_cost": 23419, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::set_reserve_status'] = { - "cpu_cost": 35599496, - "memory_cost": 3839654, + "cpu_cost": 35749840, + "memory_cost": 3850721, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::stoken_underlying_balance'] = { - "cpu_cost": 34932036, - "memory_cost": 3774628, + "cpu_cost": 35080268, + "memory_cost": 3785695, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } @@ -407,38 +407,38 @@ "memory_limit_exceeded": false, } ['pool::tests::budget::upgrade'] = { - "cpu_cost": 35239879, - "memory_cost": 3812628, + "cpu_cost": 35389491, + "memory_cost": 3823695, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::upgrade_debt_token'] = { - "cpu_cost": 41066165, - "memory_cost": 5411111, + "cpu_cost": 41218507, + "memory_cost": 5422463, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::upgrade_s_token'] = { - "cpu_cost": 46777959, - "memory_cost": 5835878, + "cpu_cost": 46930704, + "memory_cost": 5847514, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::user_configuration'] = { - "cpu_cost": 34645928, - "memory_cost": 3755636, + "cpu_cost": 34794391, + "memory_cost": 3766703, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::withdraw_full'] = { - "cpu_cost": 58338756, - "memory_cost": 9088257, + "cpu_cost": 58498234, + "memory_cost": 9099893, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } ['pool::tests::budget::withdraw_partial'] = { - "cpu_cost": 58226221, - "memory_cost": 9078585, + "cpu_cost": 58380510, + "memory_cost": 9090221, "cpu_limit_exceeded": false, "memory_limit_exceeded": false, } diff --git a/contracts/pool/src/tests/withdraw.rs b/contracts/pool/src/tests/withdraw.rs index d69f85b4..1c1f91de 100644 --- a/contracts/pool/src/tests/withdraw.rs +++ b/contracts/pool/src/tests/withdraw.rs @@ -178,10 +178,10 @@ fn should_partially_withdraw() { assert_eq!(lender_stoken_balance_before, 100_000_000); assert_eq!(lender_underlying_balance_before, 900_000_000); - assert_eq!(s_token_supply_before, 199_991_812); + assert_eq!(s_token_supply_before, 199_991_811); assert_eq!(s_token_underlying_supply_before, 160_000_000); - assert_eq!(lender_stoken_balance, 50_043_048); + assert_eq!(lender_stoken_balance, 50_043_049); assert_eq!(lender_underlying_balance, 950_000_000); assert_eq!(s_token_supply, 150_034_860); assert_eq!(s_token_underlying_supply, 110_000_000); @@ -219,13 +219,13 @@ fn should_fully_withdraw() { assert_eq!(lender_stoken_balance_before, 100_000_000); assert_eq!(lender_underlying_balance_before, 900_000_000); - assert_eq!(s_token_supply_before, 199_991_812); + assert_eq!(s_token_supply_before, 199_991_811); assert_eq!(s_token_underlying_supply_before, 160_000_000); assert_eq!(lender_stoken_balance, 0); - assert_eq!(lender_underlying_balance, 1_000_086_169); - assert_eq!(s_token_supply, 99_991_812); - assert_eq!(s_token_underlying_supply, 59_913_831); + assert_eq!(lender_underlying_balance, 1_000_086_170); + assert_eq!(s_token_supply, 99_991_811); + assert_eq!(s_token_underlying_supply, 59_913_830); } #[test] @@ -324,11 +324,11 @@ fn should_allow_withdraw_to_other_address() { assert_eq!(borrower_underlying_balance_before, 900_000_000); assert_eq!(lender_stoken_balance_before, 100_000_000); assert_eq!(lender_underlying_balance_before, 900_000_000); - assert_eq!(s_token_supply_before, 199_991_812); + assert_eq!(s_token_supply_before, 199_991_811); assert_eq!(s_token_underlying_supply_before, 160_000_000); assert_eq!(borrower_underlying_balance, 950000000); - assert_eq!(lender_stoken_balance, 50_043_048); + assert_eq!(lender_stoken_balance, 50_043_049); assert_eq!(lender_underlying_balance, 900_000_000); assert_eq!(s_token_supply, 150_034_860); assert_eq!(s_token_underlying_supply, 110_000_000); diff --git a/contracts/s-token/src/lib.rs b/contracts/s-token/src/lib.rs index ebcec541..ca06f66d 100644 --- a/contracts/s-token/src/lib.rs +++ b/contracts/s-token/src/lib.rs @@ -2,7 +2,10 @@ #![no_std] use crate::storage::*; -use common_token::{balance::*, require_nonnegative_amount, storage::*, verify_caller_is_pool}; +use common_token::{ + balance::*, require_nonnegative_amount, require_positive_amount, storage::*, + verify_caller_is_pool, +}; use pool_interface::LendingPoolClient; use s_token_interface::STokenTrait; use soroban_sdk::{contract, contractimpl, token, Address, BytesN, Env, String}; @@ -172,7 +175,7 @@ impl STokenTrait for SToken { /// fn transfer(e: Env, from: Address, to: Address, amount: i128) { from.require_auth(); - require_nonnegative_amount(amount); + require_positive_amount(amount); do_transfer(&e, from, to, amount, true); } @@ -194,7 +197,7 @@ impl STokenTrait for SToken { /// fn transfer_from(e: Env, spender: Address, from: Address, to: Address, amount: i128) { spender.require_auth(); - require_nonnegative_amount(amount); + require_positive_amount(amount); spend_allowance(&e, from.clone(), spender, amount); do_transfer(&e, from, to, amount, true); @@ -337,7 +340,7 @@ impl STokenTrait for SToken { /// fn transfer_on_liquidation(e: Env, from: Address, to: Address, amount: i128) { verify_caller_is_pool(&e); - require_nonnegative_amount(amount); + require_positive_amount(amount); do_transfer(&e, from, to, amount, false); } @@ -355,7 +358,7 @@ impl STokenTrait for SToken { /// Panics if caller is not associated pool. /// fn transfer_underlying_to(e: Env, to: Address, amount: i128) { - require_nonnegative_amount(amount); + require_positive_amount(amount); verify_caller_is_pool(&e); let underlying_asset = read_underlying_asset(&e); From 337eb2a8af93fc66734474478cb174f5294314d7 Mon Sep 17 00:00:00 2001 From: Maks Nabokov Date: Wed, 22 Nov 2023 14:13:14 +0300 Subject: [PATCH 2/3] clean --- contracts/pool/src/tests/repay.rs | 55 ------------------------------- 1 file changed, 55 deletions(-) diff --git a/contracts/pool/src/tests/repay.rs b/contracts/pool/src/tests/repay.rs index b93995a0..2fb62752 100644 --- a/contracts/pool/src/tests/repay.rs +++ b/contracts/pool/src/tests/repay.rs @@ -179,58 +179,3 @@ fn should_emit_events() { ] ); } - -#[test] -fn ceil() { - extern crate std; - let env = Env::default(); - env.mock_all_auths(); - let sut = init_pool(&env, false); - let (_, _, _debt_config) = fill_pool(&env, &sut, true); - // let _asset_to_borrow = &debt_config.token.address; - // let attacker = Address::random(&env); - // sut.reserves[0].token_admin.mint(&attacker, &9999999999999999999); - // sut.pool - // .deposit(&attacker, &sut.reserves[0].token.address, &99999999999999999999); - - // sut.pool.borrow(&attacker, asset_to_borrow, &1); - // let debt_token_balance = debt_config.debt_token.balance(&attacker); - // std::println!("{:?} borrow", debt_token_balance); - - // let mut i = 1; - // let input = loop { - // env.budget().reset_unlimited(); - // sut.pool.borrow(&attacker, asset_to_borrow, &i); - // let debt_token_balance = debt_config.debt_token.balance(&attacker); - // std::println!("{:?} borrow", debt_token_balance); - // if debt_token_balance == 0 { - // std::println!("{:?} borrow", debt_token_balance); - // break i; - // } - // // if debt_token_balance > 0 { - // // std::println!("{:?} borrow", debt_token_balance); - // // break i; - // // } - // // let collateral_amount = r.deposit_liquidity(i).unwrap(); - // // let output = r.redeem_collateral(collateral_amount).unwrap(); - // if i == 1 { - // continue; - // } - // sut.pool.repay(&attacker, asset_to_borrow, &(i - 1)); - - // let debt_token_balance = debt_config.debt_token.balance(&attacker); - // // let debt_coeff = sut.pool.debt_coeff(asset_to_borrow); - - // if debt_token_balance == 0 { - // std::println!("repay"); - // break i; - // } - - // i += 1; - - // sut.pool.repay(&attacker, &asset_to_borrow, &i128::MAX); - - // // token balance after full repay ? - // }; - // std::println!("{:?}", input); -} From 61de9e1e267dc3dfce41037f4aef76a7e2afab29 Mon Sep 17 00:00:00 2001 From: Maks Nabokov Date: Fri, 24 Nov 2023 16:08:10 +0300 Subject: [PATCH 3/3] fix int tests --- .../tests/pool/1.borrower.spec.ts | 38 +++++++++---------- .../tests/pool/2.liquidator.spec.ts | 4 +- .../tests/pool/3.liquidator.spec.ts | 4 +- integration-tests/tests/pool/4.npv.spec.ts | 25 ++++++------ 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/integration-tests/tests/pool/1.borrower.spec.ts b/integration-tests/tests/pool/1.borrower.spec.ts index f2c96d4e..28e8d0d1 100644 --- a/integration-tests/tests/pool/1.borrower.spec.ts +++ b/integration-tests/tests/pool/1.borrower.spec.ts @@ -115,10 +115,10 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", await delay(20000); // Borrower1 borrows 90_000_000 XLM - await borrow(client, borrower1Keys, "XLM", 90_000_000n); + await borrow(client, borrower1Keys, "XLM", 89_999_999n); // Borrower2 borrows 9_000_000_000 XRP - await borrow(client, borrower2Keys, "XRP", 9_000_000_000n); + await borrow(client, borrower2Keys, "XRP", 8_999_999_999n); const borrower1XlmBalance = await tokenBalanceOf(client, "XLM", borrower1Address); const borrower2XrpBalance = await tokenBalanceOf(client, "XRP", borrower2Address); @@ -132,14 +132,14 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", const dXlmSupply = await debtTokenTotalSupply(client, "XLM"); const dXrpSupply = await debtTokenTotalSupply(client, "XRP"); - assert.equal(borrower1XlmBalance, 90_000_000n); - assert.equal(borrower2XrpBalance, 9_000_000_000n); + assert.equal(borrower1XlmBalance, 89_999_999n); + assert.equal(borrower2XrpBalance, 8_999_999_999n); assert.equal(borrower1DXlmBalance, 90_000_000n); assert.equal(borrower2DXrpBalance, 9_000_000_000n); - assert.equal(sXlmBalance, 10_000_000n); - assert.equal(sXrpBalance, 1_000_000_000n); + assert.equal(sXlmBalance, 10_000_001n); + assert.equal(sXrpBalance, 1_000_000_001n); assert.equal(dXlmSupply, 90_000_000n); assert.equal(dXrpSupply, 9_000_000_000n); @@ -158,11 +158,11 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", const sXlmBalance = await sTokenUnderlyingBalanceOf(client, "XLM"); const sXrpBalance = await sTokenUnderlyingBalanceOf(client, "XRP"); - assert.equal(borrower1XlmBalance, 90_000_000n); - assert.equal(borrower2XrpBalance, 9_000_000_000n); + assert.equal(borrower1XlmBalance, 89_999_999n); + assert.equal(borrower2XrpBalance, 8_999_999_999n); - assert.equal(sXlmBalance, 10_000_000n); - assert.equal(sXrpBalance, 1_000_000_000n); + assert.equal(sXlmBalance, 10_000_001n); + assert.equal(sXrpBalance, 1_000_000_001n); }); it("Case 4: Collateral coefficient should be increased as time goes", async function () { @@ -177,10 +177,10 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", it("Case 5: Lenders withdraw to make utilization ~ 1", async function () { // Lender1 withdraws 10_000_000 XLM - await withdraw(client, lender1Keys, "XLM", 10_000_000n); + await withdraw(client, lender1Keys, "XLM", 10_000_001n); // Lender2 withdraws 1_000_000_000 XRP - await withdraw(client, lender2Keys, "XRP", 1_000_000_000n); + await withdraw(client, lender2Keys, "XRP", 1_000_000_001n); const lender1XlmBalance = await tokenBalanceOf(client, "XLM", lender1Address); const lender1SXlmBalance = await sTokenBalanceOf(client, "XLM", lender1Address); @@ -193,10 +193,10 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", const sXlmSupply = await sTokenTotalSupply(client, "XLM"); const sXrpSupply = await sTokenTotalSupply(client, "XRP"); - assert.equal(lender1XlmBalance, 910_000_000n); + assert.equal(lender1XlmBalance, 910_000_001n); assert(lender1SXlmBalance < 90_010_000n && lender1SXlmBalance > 90_000_000n); - assert.equal(lender2XrpBalance, 91_000_000_000n); + assert.equal(lender2XrpBalance, 91_000_000_001n); assert(lender2SXrpBalance < 9_001_000_000n && lender2SXrpBalance > 9_000_000_000n); @@ -225,8 +225,8 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", const sXlmSupply = await sTokenTotalSupply(client, "XLM"); const sXrpSupply = await sTokenTotalSupply(client, "XRP"); - assert.equal(lender1XlmBalance, 910_000_000n); - assert.equal(lender2XrpBalance, 91_000_000_000n); + assert.equal(lender1XlmBalance, 910_000_001n); + assert.equal(lender2XrpBalance, 91_000_000_001n); assert.equal(sXlmBalance, 0n); assert.equal(sXrpBalance, 0n); @@ -245,7 +245,7 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", const sXlmBalance = await sTokenUnderlyingBalanceOf(client, "XLM"); const dXlmSupply = await debtTokenTotalSupply(client, "XLM"); - assert.equal(borrower1XlmBalance, 80_000_000n); + assert.equal(borrower1XlmBalance, 79_999_999n); assert(treasuryXlmBalance > 0 && treasuryXlmBalance < 1_000n); assert(borrower1DXlmBalance > 80_000_000n && borrower1DXlmBalance < 80_010_000n); @@ -311,10 +311,10 @@ describe("LendingPool: Lenders get and borrowers pay interest when time passed", const sXlmSupply = await sTokenTotalSupply(client, "XLM"); const sXrpSupply = await sTokenTotalSupply(client, "XRP"); - assert.equal(lender1XlmBalance, 920_000_000n); + assert.equal(lender1XlmBalance, 920_000_001n); assert(lender1SXlmBalance < 80_010_000n && lender1SXlmBalance > 80_000_000n); - assert.equal(lender2XrpBalance, 92_000_000_000n); + assert.equal(lender2XrpBalance, 92_000_000_001n); assert(lender2SXrpBalance < 8_001_000_000n && lender2SXrpBalance > 8_000_000_000n); diff --git a/integration-tests/tests/pool/2.liquidator.spec.ts b/integration-tests/tests/pool/2.liquidator.spec.ts index 5b34588e..cd1010a9 100644 --- a/integration-tests/tests/pool/2.liquidator.spec.ts +++ b/integration-tests/tests/pool/2.liquidator.spec.ts @@ -114,9 +114,9 @@ describe("LendingPool: Liquidation (receive underlying assets)", function () { const borrower1Position = await accountPosition(client, borrower1Keys); assert.equal(borrower1XlmBalance, 119_990_000n); - assert.equal(borrower1DXlmBalance, 119_990_000n); + assert.equal(borrower1DXlmBalance, 119_990_001n); assert.equal(sXlmBalance, 180_010_000n); - assert.equal(dXlmSupply, 119_990_000n); + assert.equal(dXlmSupply, 119_990_001n); assert(borrower1Position.debt > 119_990_000n && borrower1Position.debt < 120_000_000n); diff --git a/integration-tests/tests/pool/3.liquidator.spec.ts b/integration-tests/tests/pool/3.liquidator.spec.ts index 32a86557..96dcb9b4 100644 --- a/integration-tests/tests/pool/3.liquidator.spec.ts +++ b/integration-tests/tests/pool/3.liquidator.spec.ts @@ -130,9 +130,9 @@ describe("LendingPool: Liquidation (receive STokens)", function () { const borrower1Position = await accountPosition(client, borrower1Keys); assert.equal(borrower1XlmBalance, 119_990_000n); - assert.equal(borrower1DXlmBalance, 119_990_000n); + assert.equal(borrower1DXlmBalance, 119_990_001n); assert.equal(sXlmBalance, 580_010_000n); - assert.equal(dXlmSupply, 119_990_000n); + assert.equal(dXlmSupply, 119_990_001n); assert(borrower1Position.debt > 119_990_000n && borrower1Position.debt < 120_000_000n); diff --git a/integration-tests/tests/pool/4.npv.spec.ts b/integration-tests/tests/pool/4.npv.spec.ts index c6a9f3bd..4c703c31 100644 --- a/integration-tests/tests/pool/4.npv.spec.ts +++ b/integration-tests/tests/pool/4.npv.spec.ts @@ -32,6 +32,7 @@ describe("LendingPool: Borrower position", function () { await cleanSlenderEnvKeys(); await deploy(); await init(client); + // require("dotenv").config({ path: contractsFilename }); lender1Address = lender1Keys.publicKey(); borrower1Address = borrower1Keys.publicKey(); @@ -90,20 +91,20 @@ describe("LendingPool: Borrower position", function () { const borrower1Position = await accountPosition(client, borrower1Keys); assert.equal(borrower1XlmBalance, 50_000_000n); - assert.equal(borrower1DXlmBalance, 50_000_000n); + assert.equal(borrower1DXlmBalance, 50_000_001n); assert.equal(sXlmBalance, 450_000_000n); - assert.equal(dXlmSupply, 50_000_000n); + assert.equal(dXlmSupply, 50_000_001n); assert(borrower1Position.debt >= 50_000_000n && borrower1Position.debt < 50_010_000n); assert.equal(borrower1Position.discounted_collateral, 120_000_000n); assert(borrower1Position.npv > 69_990_000n - && borrower1Position.npv <= 70_000_000n); + && borrower1Position.npv <= 70_000_000n, `borrower1Position.npv ${borrower1Position.npv}`); }); it("Case 3: Borrower borrows more with NPV > 0", async function () { // Borrower1 borrows 50_000_000 XLM - await borrow(client, borrower1Keys, "XLM", 50_000_000n); + await borrow(client, borrower1Keys, "XLM", 49_999_998n); const borrower1XlmBalance = await tokenBalanceOf(client, "XLM", borrower1Address); const borrower1DXlmBalance = await debtTokenBalanceOf(client, "XLM", borrower1Address); @@ -111,14 +112,14 @@ describe("LendingPool: Borrower position", function () { const dXlmSupply = await debtTokenTotalSupply(client, "XLM"); const borrower1Position = await accountPosition(client, borrower1Keys); - assert.equal(borrower1XlmBalance, 100_000_000n); + assert.equal(borrower1XlmBalance, 99_999_998n); assert(borrower1DXlmBalance > 99_990_000n - && borrower1DXlmBalance < 100_000_000n); - assert.equal(sXlmBalance, 400_000_000n); + && borrower1DXlmBalance < 100_000_000n, `borrower1DXlmBalance ${borrower1DXlmBalance} `); + assert.equal(sXlmBalance, 400_000_002n); assert.equal(dXlmSupply, borrower1DXlmBalance); assert(borrower1Position.debt >= 100_000_000n - && borrower1Position.debt < 100_010_000n); + && borrower1Position.debt < 100_010_000n, `borrower1Position.debt ${borrower1Position.debt}`); assert.equal(borrower1Position.discounted_collateral, 120_000_000n); assert(borrower1Position.npv > 19_990_000n && borrower1Position.npv <= 20_000_000n); @@ -166,10 +167,10 @@ describe("LendingPool: Borrower position", function () { const dXlmSupply = await debtTokenTotalSupply(client, "XLM"); const borrower1Position = await accountPosition(client, borrower1Keys); - assert.equal(borrower1XlmBalance, 100_000_000n); + assert.equal(borrower1XlmBalance, 99_999_998n); assert(borrower1DXlmBalance > 99_990_000n && borrower1DXlmBalance < 100_000_000n); - assert.equal(sXlmBalance, 400_000_000n); + assert.equal(sXlmBalance, 400_000_002n); assert.equal(dXlmSupply, borrower1DXlmBalance); assert(borrower1Position.debt >= 100_000_000n @@ -238,10 +239,10 @@ describe("LendingPool: Borrower position", function () { const dXlmSupply = await debtTokenTotalSupply(client, "XLM"); const borrower1Position = await accountPosition(client, borrower1Keys); - assert.equal(borrower1XlmBalance, 105_000_000n); + assert.equal(borrower1XlmBalance, 104_999_998n); assert(borrower1DXlmBalance > 100_000_000n && borrower1DXlmBalance <= 105_000_000n); - assert.equal(sXlmBalance, 395_000_000n); + assert.equal(sXlmBalance, 395_000_002n); assert.equal(dXlmSupply, borrower1DXlmBalance); assert(borrower1Position.debt >= 105_000_000n