Skip to content

Commit

Permalink
fix interest calculation (#1301)
Browse files Browse the repository at this point in the history
  • Loading branch information
wangjj9219 authored Aug 6, 2021
1 parent 66ea441 commit a1d4800
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 35 deletions.
8 changes: 3 additions & 5 deletions modules/cdp-engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ pub mod module {
CloseCDPInDebitByDEX(CurrencyId, T::AccountId, Balance, Balance, Balance),
/// The interest rate per sec for specific collateral type updated.
/// \[collateral_type, new_interest_rate_per_sec\]
InterestRatePerSec(CurrencyId, Option<Rate>),
InterestRatePerSecUpdated(CurrencyId, Option<Rate>),
/// The liquidation fee for specific collateral type updated.
/// \[collateral_type, new_liquidation_ratio\]
LiquidationRatioUpdated(CurrencyId, Option<Ratio>),
Expand Down Expand Up @@ -458,7 +458,7 @@ pub mod module {
let mut collateral_params = Self::collateral_params(currency_id);
if let Change::NewValue(update) = interest_rate_per_sec {
collateral_params.interest_rate_per_sec = update;
Self::deposit_event(Event::InterestRatePerSec(currency_id, update));
Self::deposit_event(Event::InterestRatePerSecUpdated(currency_id, update));
}
if let Change::NewValue(update) = liquidation_ratio {
collateral_params.liquidation_ratio = update;
Expand Down Expand Up @@ -536,9 +536,7 @@ impl<T: Config> Pallet<T> {
if !rate_to_accumulate.is_zero() && !total_debits.is_zero() {
let debit_exchange_rate = Self::get_debit_exchange_rate(currency_id);
let debit_exchange_rate_increment = debit_exchange_rate.saturating_mul(rate_to_accumulate);
let total_debit_value = Self::get_debit_value(currency_id, total_debits);
let issued_stable_coin_balance =
debit_exchange_rate_increment.saturating_mul_int(total_debit_value);
let issued_stable_coin_balance = debit_exchange_rate_increment.saturating_mul_int(total_debits);

// issue stablecoin to surplus pool
let res = <T as Config>::CDPTreasury::on_system_surplus(issued_stable_coin_balance);
Expand Down
2 changes: 1 addition & 1 deletion modules/cdp-engine/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ ord_parameter_types! {

parameter_types! {
pub DefaultLiquidationRatio: Ratio = Ratio::saturating_from_rational(3, 2);
pub DefaultDebitExchangeRate: ExchangeRate = ExchangeRate::one();
pub DefaultDebitExchangeRate: ExchangeRate = ExchangeRate::saturating_from_rational(1, 10);
pub DefaultLiquidationPenalty: Rate = Rate::saturating_from_rational(10, 100);
pub const MinimumDebitValue: Balance = 2;
pub MaxSlippageSwapWithDEX: Ratio = Ratio::saturating_from_rational(50, 100);
Expand Down
87 changes: 58 additions & 29 deletions modules/cdp-engine/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn is_cdp_unsafe_work() {
Change::NewValue(10000),
));
assert_eq!(is_user_safe(BTC, &ALICE), false);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 50));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 500));
assert_eq!(is_user_safe(BTC, &ALICE), false);
assert_ok!(CDPEngineModule::set_collateral_params(
Origin::signed(1),
Expand All @@ -62,10 +62,15 @@ fn is_cdp_unsafe_work() {
#[test]
fn get_debit_exchange_rate_work() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(CDPEngineModule::debit_exchange_rate(BTC), None);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(BTC),
DefaultDebitExchangeRate::get()
ExchangeRate::saturating_from_rational(1, 10)
);

DebitExchangeRate::<Runtime>::insert(BTC, ExchangeRate::one());
assert_eq!(CDPEngineModule::debit_exchange_rate(BTC), Some(ExchangeRate::one()));
assert_eq!(CDPEngineModule::get_debit_exchange_rate(BTC), ExchangeRate::one());
});
}

Expand Down Expand Up @@ -175,7 +180,7 @@ fn set_collateral_params_work() {
Change::NewValue(Some(Ratio::saturating_from_rational(9, 5))),
Change::NewValue(10000),
));
System::assert_has_event(Event::CDPEngineModule(crate::Event::InterestRatePerSec(
System::assert_has_event(Event::CDPEngineModule(crate::Event::InterestRatePerSecUpdated(
BTC,
Some(Rate::saturating_from_rational(1, 100000)),
)));
Expand Down Expand Up @@ -240,7 +245,7 @@ fn calculate_collateral_ratio_work() {
Change::NewValue(10000),
));
assert_eq!(
CDPEngineModule::calculate_collateral_ratio(BTC, 100, 50, Price::saturating_from_rational(1, 1)),
CDPEngineModule::calculate_collateral_ratio(BTC, 100, 500, Price::saturating_from_rational(1, 1)),
Ratio::saturating_from_rational(100, 50)
);
});
Expand All @@ -258,9 +263,9 @@ fn check_debit_cap_work() {
Change::NewValue(Some(Ratio::saturating_from_rational(9, 5))),
Change::NewValue(10000),
));
assert_ok!(CDPEngineModule::check_debit_cap(BTC, 9999));
assert_ok!(CDPEngineModule::check_debit_cap(BTC, 100000));
assert_noop!(
CDPEngineModule::check_debit_cap(BTC, 10001),
CDPEngineModule::check_debit_cap(BTC, 100010),
Error::<Runtime>::ExceedDebitValueHardCap,
);
});
Expand All @@ -281,12 +286,12 @@ fn check_position_valid_work() {

MockPriceSource::set_relative_price(None);
assert_noop!(
CDPEngineModule::check_position_valid(BTC, 100, 50),
CDPEngineModule::check_position_valid(BTC, 100, 500),
Error::<Runtime>::InvalidFeedPrice
);
MockPriceSource::set_relative_price(Some(Price::one()));

assert_ok!(CDPEngineModule::check_position_valid(BTC, 100, 50));
assert_ok!(CDPEngineModule::check_position_valid(BTC, 100, 500));
});
}

Expand All @@ -303,7 +308,7 @@ fn check_position_valid_failed_when_remain_debit_value_too_small() {
Change::NewValue(10000),
));
assert_noop!(
CDPEngineModule::check_position_valid(BTC, 2, 1),
CDPEngineModule::check_position_valid(BTC, 2, 10),
Error::<Runtime>::RemainDebitValueTooSmall,
);
});
Expand All @@ -322,7 +327,7 @@ fn check_position_valid_ratio_below_liquidate_ratio() {
Change::NewValue(10000),
));
assert_noop!(
CDPEngineModule::check_position_valid(BTC, 91, 50),
CDPEngineModule::check_position_valid(BTC, 91, 500),
Error::<Runtime>::BelowLiquidationRatio,
);
});
Expand All @@ -341,7 +346,7 @@ fn check_position_valid_ratio_below_required_ratio() {
Change::NewValue(10000),
));
assert_noop!(
CDPEngineModule::check_position_valid(BTC, 89, 50),
CDPEngineModule::check_position_valid(BTC, 89, 500),
Error::<Runtime>::BelowRequiredCollateralRatio
);
});
Expand All @@ -360,23 +365,23 @@ fn adjust_position_work() {
Change::NewValue(10000),
));
assert_noop!(
CDPEngineModule::adjust_position(&ALICE, ACA, 100, 50),
CDPEngineModule::adjust_position(&ALICE, ACA, 100, 500),
Error::<Runtime>::InvalidCollateralType,
);
assert_eq!(Currencies::free_balance(BTC, &ALICE), 1000);
assert_eq!(Currencies::free_balance(AUSD, &ALICE), 0);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 0);
assert_eq!(LoansModule::positions(BTC, ALICE).collateral, 0);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 50));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 500));
assert_eq!(Currencies::free_balance(BTC, &ALICE), 900);
assert_eq!(Currencies::free_balance(AUSD, &ALICE), 50);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 50);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 500);
assert_eq!(LoansModule::positions(BTC, ALICE).collateral, 100);
assert_eq!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, 20).is_ok(), false);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, -20));
assert_eq!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, 200).is_ok(), false);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, -200));
assert_eq!(Currencies::free_balance(BTC, &ALICE), 900);
assert_eq!(Currencies::free_balance(AUSD, &ALICE), 30);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 30);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 300);
assert_eq!(LoansModule::positions(BTC, ALICE).collateral, 100);
});
}
Expand All @@ -393,9 +398,9 @@ fn remain_debit_value_too_small_check() {
Change::NewValue(Some(Ratio::saturating_from_rational(9, 5))),
Change::NewValue(10000),
));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 50));
assert_eq!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, -49).is_ok(), false);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, -100, -50));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 500));
assert_eq!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, -490).is_ok(), false);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, -100, -500));
});
}

Expand All @@ -412,10 +417,10 @@ fn liquidate_unsafe_cdp_by_collateral_auction() {
Change::NewValue(Some(Ratio::saturating_from_rational(9, 5))),
Change::NewValue(10000),
));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 50));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 500));
assert_eq!(Currencies::free_balance(BTC, &ALICE), 900);
assert_eq!(Currencies::free_balance(AUSD, &ALICE), 50);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 50);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 500);
assert_eq!(LoansModule::positions(BTC, ALICE).collateral, 100);
assert_noop!(
CDPEngineModule::liquidate_unsafe_cdp(ALICE, BTC),
Expand Down Expand Up @@ -550,15 +555,31 @@ fn accumulate_interest_work() {

CDPEngineModule::accumulate_interest(1, 0);
assert_eq!(CDPEngineModule::last_accumulation_secs(), 1);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(BTC),
ExchangeRate::saturating_from_rational(1, 10)
);
assert_eq!(CDPEngineModule::debit_exchange_rate(BTC), None);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(DOT),
ExchangeRate::saturating_from_rational(1, 10)
);
assert_eq!(CDPEngineModule::debit_exchange_rate(DOT), None);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 30));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 100, 300));

CDPEngineModule::accumulate_interest(2, 1);
assert_eq!(CDPEngineModule::last_accumulation_secs(), 2);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(BTC),
ExchangeRate::saturating_from_rational(101, 1000)
);
assert_eq!(
CDPEngineModule::debit_exchange_rate(BTC),
Some(ExchangeRate::saturating_from_rational(101, 100))
Some(ExchangeRate::saturating_from_rational(101, 1000))
);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(DOT),
ExchangeRate::saturating_from_rational(1, 10)
);
assert_eq!(CDPEngineModule::debit_exchange_rate(DOT), None);

Expand All @@ -567,9 +588,17 @@ fn accumulate_interest_work() {

CDPEngineModule::accumulate_interest(3, 2);
assert_eq!(CDPEngineModule::last_accumulation_secs(), 3);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(BTC),
ExchangeRate::saturating_from_rational(101, 1000)
);
assert_eq!(
CDPEngineModule::debit_exchange_rate(BTC),
Some(ExchangeRate::saturating_from_rational(101, 100))
Some(ExchangeRate::saturating_from_rational(101, 1000))
);
assert_eq!(
CDPEngineModule::get_debit_exchange_rate(DOT),
ExchangeRate::saturating_from_rational(1, 10)
);
assert_eq!(CDPEngineModule::debit_exchange_rate(DOT), None);
});
Expand All @@ -596,8 +625,8 @@ fn settle_cdp_has_debit_work() {
CDPEngineModule::settle_cdp_has_debit(ALICE, BTC),
Error::<Runtime>::NoDebitValue,
);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, 50));
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 50);
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, 500));
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 500);
assert_eq!(CDPTreasuryModule::debit_pool(), 0);
assert_eq!(CDPTreasuryModule::total_collaterals(BTC), 0);
assert_ok!(CDPEngineModule::settle_cdp_has_debit(ALICE, BTC));
Expand Down Expand Up @@ -647,10 +676,10 @@ fn close_cdp_has_debit_by_dex_work() {
Error::<Runtime>::NoDebitValue
);

assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, 50));
assert_ok!(CDPEngineModule::adjust_position(&ALICE, BTC, 0, 500));
assert_eq!(Currencies::free_balance(BTC, &ALICE), 900);
assert_eq!(Currencies::free_balance(AUSD, &ALICE), 50);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 50);
assert_eq!(LoansModule::positions(BTC, ALICE).debit, 500);
assert_eq!(LoansModule::positions(BTC, ALICE).collateral, 100);
assert_eq!(CDPTreasuryModule::get_surplus_pool(), 0);
assert_eq!(CDPTreasuryModule::get_debit_pool(), 0);
Expand Down

0 comments on commit a1d4800

Please sign in to comment.