Skip to content

Commit

Permalink
Populate module-ecdp-ussd-loans
Browse files Browse the repository at this point in the history
  • Loading branch information
balqaasem committed Mar 7, 2024
1 parent e283191 commit 8647197
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 53 deletions.
60 changes: 30 additions & 30 deletions blockchain/modules/ecdp-ussd-loans/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#![allow(clippy::collapsible_if)]

use frame_support::{pallet_prelude::*, transactional, PalletId};
use module_support::{SlickUsdEcdpTreasury, SlickUsdRiskManager};
use module_support::{EcdpUssdTreasury, EcdpUssdRiskManager};
use orml_traits::{Happened, MultiCurrency, MultiCurrencyExtended};
use primitives::{Amount, Balance, CurrencyId, Position};
use primitives::{Amount, Balance, CurrencyId, EcdpPosition};
use sp_runtime::{
traits::{AccountIdConversion, Zero},
ArithmeticError, DispatchResult,
Expand Down Expand Up @@ -60,10 +60,10 @@ pub mod module {
>;

/// Risk manager is used to limit the debit size of CDP.
type SlickUsdRiskManager: SlickUsdRiskManager<Self::AccountId, CurrencyId, Balance, Balance>;
type EcdpUssdRiskManager: EcdpUssdRiskManager<Self::AccountId, CurrencyId, Balance, Balance>;

/// CDP treasury for issuing/burning USSD and debit value adjustment.
type SlickUsdEcdpTreasury: SlickUsdEcdpTreasury<Self::AccountId, Balance = Balance, CurrencyId = CurrencyId>;
type EcdpUssdTreasury: EcdpUssdTreasury<Self::AccountId, Balance = Balance, CurrencyId = CurrencyId>;

/// The loan's module id, keep all collaterals of CDPs.
#[pallet::constant]
Expand All @@ -82,8 +82,8 @@ pub mod module {
#[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> {
/// Position updated.
PositionUpdated {
/// EcdpPosition updated.
EcdpPositionUpdated {
owner: T::AccountId,
collateral_type: CurrencyId,
collateral_adjustment: Amount,
Expand All @@ -105,21 +105,21 @@ pub mod module {
}

/// The collateralized debit positions, map from
/// Owner -> CollateralType -> Position
/// Owner -> CollateralType -> EcdpPosition
///
/// Positions: double_map CurrencyId, AccountId => Position
/// EcdpPositions: double_map CurrencyId, AccountId => EcdpPosition
#[pallet::storage]
#[pallet::getter(fn positions)]
pub type Positions<T: Config> =
StorageDoubleMap<_, Twox64Concat, CurrencyId, Twox64Concat, T::AccountId, Position, ValueQuery>;
pub type EcdpPositions<T: Config> =
StorageDoubleMap<_, Twox64Concat, CurrencyId, Twox64Concat, T::AccountId, EcdpPosition, ValueQuery>;

/// The total collateralized debit positions, map from
/// CollateralType -> Position
/// CollateralType -> EcdpPosition
///
/// TotalPositions: CurrencyId => Position
/// TotalEcdpPositions: CurrencyId => EcdpPosition
#[pallet::storage]
#[pallet::getter(fn total_positions)]
pub type TotalPositions<T: Config> = StorageMap<_, Twox64Concat, CurrencyId, Position, ValueQuery>;
pub type TotalEcdpPositions<T: Config> = StorageMap<_, Twox64Concat, CurrencyId, EcdpPosition, ValueQuery>;

#[pallet::pallet]
pub struct Pallet<T>(_);
Expand Down Expand Up @@ -148,11 +148,11 @@ impl<T: Config> Pallet<T> {
let debit_adjustment = Self::amount_try_from_balance(debit_decrease)?;

// transfer collateral to cdp treasury
T::SlickUsdEcdpTreasury::deposit_collateral(&Self::account_id(), currency_id, collateral_confiscate)?;
T::EcdpUssdTreasury::deposit_collateral(&Self::account_id(), currency_id, collateral_confiscate)?;

// deposit debit to cdp treasury
let bad_debt_value = T::SlickUsdRiskManager::get_debit_value(currency_id, debit_decrease);
T::SlickUsdEcdpTreasury::on_system_debit(bad_debt_value)?;
let bad_debt_value = T::EcdpUssdRiskManager::get_debit_value(currency_id, debit_decrease);
T::EcdpUssdTreasury::on_system_debit(bad_debt_value)?;

// update loan
Self::update_loan(
Expand Down Expand Up @@ -197,26 +197,26 @@ impl<T: Config> Pallet<T> {

if debit_adjustment.is_positive() {
// check debit cap when increase debit
T::SlickUsdRiskManager::check_debit_cap(currency_id, Self::total_positions(currency_id).debit)?;
T::EcdpUssdRiskManager::check_debit_cap(currency_id, Self::total_positions(currency_id).debit)?;

// issue debit with collateral backed by cdp treasury
T::SlickUsdEcdpTreasury::issue_debit(
T::EcdpUssdTreasury::issue_debit(
who,
T::SlickUsdRiskManager::get_debit_value(currency_id, debit_balance_adjustment),
T::EcdpUssdRiskManager::get_debit_value(currency_id, debit_balance_adjustment),
true,
)?;
} else if debit_adjustment.is_negative() {
// repay debit
// burn debit by cdp treasury
T::SlickUsdEcdpTreasury::burn_debit(
T::EcdpUssdTreasury::burn_debit(
who,
T::SlickUsdRiskManager::get_debit_value(currency_id, debit_balance_adjustment),
T::EcdpUssdRiskManager::get_debit_value(currency_id, debit_balance_adjustment),
)?;
}

// ensure pass risk check
let Position { collateral, debit } = Self::positions(currency_id, who);
T::SlickUsdRiskManager::check_position_valid(
let EcdpPosition { collateral, debit } = Self::positions(currency_id, who);
T::EcdpUssdRiskManager::check_position_valid(
currency_id,
collateral,
debit,
Expand All @@ -229,9 +229,9 @@ impl<T: Config> Pallet<T> {
/// transfer whole loan of `from` to `to`
pub fn transfer_loan(from: &T::AccountId, to: &T::AccountId, currency_id: CurrencyId) -> DispatchResult {
// get `from` position data
let Position { collateral, debit } = Self::positions(currency_id, from);
let EcdpPosition { collateral, debit } = Self::positions(currency_id, from);

let Position {
let EcdpPosition {
collateral: to_collateral,
debit: to_debit,
} = Self::positions(currency_id, to);
Expand All @@ -243,7 +243,7 @@ impl<T: Config> Pallet<T> {
.expect("existing debit balance cannot overflow; qed");

// check new position
T::SlickUsdRiskManager::check_position_valid(currency_id, new_to_collateral_balance, new_to_debit_balance, true)?;
T::EcdpUssdRiskManager::check_position_valid(currency_id, new_to_collateral_balance, new_to_debit_balance, true)?;

// balance -> amount
let collateral_adjustment = Self::amount_try_from_balance(collateral)?;
Expand Down Expand Up @@ -275,7 +275,7 @@ impl<T: Config> Pallet<T> {
let collateral_balance = Self::balance_try_from_amount_abs(collateral_adjustment)?;
let debit_balance = Self::balance_try_from_amount_abs(debit_adjustment)?;

<Positions<T>>::try_mutate_exists(currency_id, who, |may_be_position| -> DispatchResult {
<EcdpPositions<T>>::try_mutate_exists(currency_id, who, |may_be_position| -> DispatchResult {
let mut p = may_be_position.take().unwrap_or_default();
let new_collateral = if collateral_adjustment.is_positive() {
p.collateral
Expand Down Expand Up @@ -306,7 +306,7 @@ impl<T: Config> Pallet<T> {
}

// TODO:[src/lib.rs:0] - Remove this from this module and add it to `EcdpUssdLoans` module.
// Use the collateral amount (of a position that has fulfilled the `PositionCloudCreditRequirements` -
// Use the collateral amount (of a position that has fulfilled the `EcdpPositionCloudCreditRequirements` -
// this is only offered for SETR) as the shares for Cloud Credit.
//
// T::OnUpdateLoan::happened(&(who.clone(), currency_id, collateral_adjustment, p.collateral));
Expand All @@ -327,7 +327,7 @@ impl<T: Config> Pallet<T> {
Ok(())
})?;

TotalPositions::<T>::try_mutate(currency_id, |total_positions| -> DispatchResult {
TotalEcdpPositions::<T>::try_mutate(currency_id, |total_positions| -> DispatchResult {
total_positions.collateral = if collateral_adjustment.is_positive() {
total_positions
.collateral
Expand Down Expand Up @@ -355,7 +355,7 @@ impl<T: Config> Pallet<T> {
Ok(())
})?;

Self::deposit_event(Event::PositionUpdated {
Self::deposit_event(Event::EcdpPositionUpdated {
owner: who.clone(),
collateral_type: currency_id,
collateral_adjustment,
Expand Down
29 changes: 14 additions & 15 deletions blockchain/modules/ecdp-ussd-loans/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use frame_support::{
PalletId,
};
use frame_system::EnsureSignedBy;
use module_support::{mocks::MockStableAsset, AuctionManager, SlickUsdRiskManager, SpecificJointsSwap};
use module_support::{EcdpAuctionsManager, EcdpUssdRiskManager, SpecificJointsSwap};
use orml_traits::parameter_type_with_key;
use primitives::TokenSymbol;
use sp_runtime::{
Expand Down Expand Up @@ -111,8 +111,8 @@ impl orml_currencies::Config for Runtime {
}
pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter<Runtime, PalletBalances, Amount, BlockNumber>;

pub struct MockAuctionManager;
impl AuctionManager<AccountId> for MockAuctionManager {
pub struct MockEcdpAuctionsManager;
impl EcdpAuctionsManager<AccountId> for MockEcdpAuctionsManager {
type CurrencyId = CurrencyId;
type Balance = Balance;
type AuctionId = AuctionId;
Expand Down Expand Up @@ -144,30 +144,29 @@ ord_parameter_types! {
}

parameter_types! {
pub const GetStableCurrencyId: CurrencyId = USSD;
pub const SlickUsdEcdpTreasuryPalletId: PalletId = PalletId(*b"aca/cdpt");
pub const GetUSSDCurrencyId: CurrencyId = USSD;
pub const EcdpUssdTreasuryPalletId: PalletId = PalletId(*b"aca/cdpt");
pub TreasuryAccount: AccountId = PalletId(*b"aca/hztr").into_account_truncating();
pub AlternativeSwapPathJointList: Vec<Vec<CurrencyId>> = vec![];
}

impl module_ussd_ecdp_treasury::Config for Runtime {
impl module_ecdp_ussd_treasury::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Currencies;
type GetStableCurrencyId = GetStableCurrencyId;
type AuctionManagerHandler = MockAuctionManager;
type GetUSSDCurrencyId = GetUSSDCurrencyId;
type EcdpAuctionsManagerHandler = MockEcdpAuctionsManager;
type UpdateOrigin = EnsureSignedBy<One, AccountId>;
type DEX = ();
type Swap = SpecificJointsSwap<(), AlternativeSwapPathJointList>;
type MaxAuctionsCount = ConstU32<10_000>;
type PalletId = SlickUsdEcdpTreasuryPalletId;
type PalletId = EcdpUssdTreasuryPalletId;
type TreasuryAccount = TreasuryAccount;
type WeightInfo = ();
type StableAsset = MockStableAsset<CurrencyId, Balance, AccountId, BlockNumber>;
}

// mock risk manager
pub struct MockSlickUsdRiskManager;
impl SlickUsdRiskManager<AccountId, CurrencyId, Balance, Balance> for MockSlickUsdRiskManager {
pub struct MockEcdpUssdRiskManager;
impl EcdpUssdRiskManager<AccountId, CurrencyId, Balance, Balance> for MockEcdpUssdRiskManager {
fn get_debit_value(_currency_id: CurrencyId, debit_balance: Balance) -> Balance {
debit_balance / Balance::from(2u64)
}
Expand Down Expand Up @@ -235,8 +234,8 @@ parameter_types! {
impl Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Currencies;
type SlickUsdRiskManager = MockSlickUsdRiskManager;
type SlickUsdEcdpTreasury = SlickUsdEcdpTreasuryModule;
type EcdpUssdRiskManager = MockEcdpUssdRiskManager;
type EcdpUssdTreasury = EcdpUssdTreasuryModule;
type PalletId = EcdpUssdLoansPalletId;
}

Expand All @@ -249,7 +248,7 @@ construct_runtime!(
Tokens: orml_tokens,
PalletBalances: pallet_balances,
Currencies: orml_currencies,
SlickUsdEcdpTreasuryModule: module_ussd_ecdp_treasury,
EcdpUssdTreasuryModule: module_ecdp_ussd_treasury,
}
);

Expand Down
16 changes: 8 additions & 8 deletions blockchain/modules/ecdp-ussd-loans/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn adjust_position_should_work() {
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).debit, 300);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).collateral, 500);
assert_eq!(Currencies::free_balance(USSD, &ALICE), 150);
System::assert_has_event(RuntimeEvent::EcdpUssdLoansModule(crate::Event::PositionUpdated {
System::assert_has_event(RuntimeEvent::EcdpUssdLoansModule(crate::Event::EcdpPositionUpdated {
owner: ALICE,
collateral_type: BTC,
collateral_adjustment: 500,
Expand All @@ -131,7 +131,7 @@ fn update_loan_should_work() {
assert_eq!(EcdpUssdLoansModule::total_positions(BTC).collateral, 0);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).debit, 0);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).collateral, 0);
assert!(!<Positions<Runtime>>::contains_key(BTC, &ALICE));
assert!(!<EcdpPositions<Runtime>>::contains_key(BTC, &ALICE));

let alice_ref_count_0 = System::consumers(&ALICE);

Expand All @@ -152,11 +152,11 @@ fn update_loan_should_work() {
assert_eq!(Currencies::free_balance(BTC, &ALICE), 1000);

// should remove position storage if zero
assert!(<Positions<Runtime>>::contains_key(BTC, &ALICE));
assert!(<EcdpPositions<Runtime>>::contains_key(BTC, &ALICE));
assert_ok!(EcdpUssdLoansModule::update_loan(&ALICE, BTC, -3000, -2000));
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).debit, 0);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).collateral, 0);
assert!(!<Positions<Runtime>>::contains_key(BTC, &ALICE));
assert!(!<EcdpPositions<Runtime>>::contains_key(BTC, &ALICE));

// decrease ref count after remove position
let alice_ref_count_2 = System::consumers(&ALICE);
Expand Down Expand Up @@ -202,14 +202,14 @@ fn confiscate_collateral_and_debit_work() {
);

assert_ok!(EcdpUssdLoansModule::adjust_position(&ALICE, BTC, 500, 300));
assert_eq!(SlickUsdEcdpTreasuryModule::get_total_collaterals(BTC), 0);
assert_eq!(SlickUsdEcdpTreasuryModule::debit_pool(), 0);
assert_eq!(EcdpUssdTreasuryModule::get_total_collaterals(BTC), 0);
assert_eq!(EcdpUssdTreasuryModule::debit_pool(), 0);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).debit, 300);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).collateral, 500);

assert_ok!(EcdpUssdLoansModule::confiscate_collateral_and_debit(&ALICE, BTC, 300, 200));
assert_eq!(SlickUsdEcdpTreasuryModule::get_total_collaterals(BTC), 300);
assert_eq!(SlickUsdEcdpTreasuryModule::debit_pool(), 100);
assert_eq!(EcdpUssdTreasuryModule::get_total_collaterals(BTC), 300);
assert_eq!(EcdpUssdTreasuryModule::debit_pool(), 100);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).debit, 100);
assert_eq!(EcdpUssdLoansModule::positions(BTC, &ALICE).collateral, 200);
System::assert_last_event(RuntimeEvent::EcdpUssdLoansModule(crate::Event::ConfiscateCollateralAndDebit {
Expand Down

0 comments on commit 8647197

Please sign in to comment.