Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into loans/integration-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Sep 28, 2023
2 parents 782de0c + 0387385 commit c7260b5
Show file tree
Hide file tree
Showing 28 changed files with 1,172 additions and 388 deletions.
33 changes: 15 additions & 18 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
# Centrifudge Code Owners

## Changes to .github
.github/* @mikiquantum @mustermeiszer @branan @NunoAlexandre
.github/* @mustermeiszer @NunoAlexandre @lemunozm

## Changes to ci
ci/* @mikiquantum @mustermeiszer @branan @NunoAlexandre
ci/* @mustermeiszer @NunoAlexandre @lemunozm

## Changes to the service of our chain.
node/* @mikiquantum @mustermeiszer @branan @NunoAlexandre
node/* @mustermeiszer @NunoAlexandre

## Changes to chain-specs
node/res/* @mikiquantum @mustermeiszer @branan @NunoAlexandre @wischli

## Changes to toml files
*.toml @mikiquantum @mustermeiszer @branan @NunoAlexandre @lemunozm @wischli @cdamian @thea-leake
node/res/* @mustermeiszer @NunoAlexandre @wischli

## Changes to specific pallets
pallets/liquidity-pools/* @NunoAlexandre @cdamian @wischli @mustermeiszer
pallets/rewards/* @lemunozm @mikiquantum
pallets/liquidity-rewards/* @lemunozm @mikiquantum
pallets/rewards/* @lemunozm
pallets/liquidity-rewards/* @lemunozm
pallets/block-rewards/* @wischli @lemunozm
pallets/nft-sales/* @NunoAlexandre
pallets/keystore/* @cdamian @mikiquantum
pallets/keystore/* @cdamian
pallets/pool-registry/* @mustermeiszer
pallets/pool-system/* @mustermeiszer @branan @offerijns
pallets/loans/* @mustermeiszer @branan @offerijns @lemunozm
pallets/interest-accrual/* @branan @lemunozm
pallets/pool-system/* @mustermeiszer @hieronx
pallets/loans/* @mustermeiszer @hieronx @lemunozm
pallets/interest-accrual/* @lemunozm
pallets/investments/* @mustermeiszer
pallets/permissions/* @mustermeiszer
pallets/restricted-tokens/* @mustermeiszer
pallets/data-collector/* @lemunozm
pallets/fees/* @lemunozm @mikiquantum
pallets/transfer-allowlist/* @thea-leake @mustermeiszer
pallets/fees/* @lemunozm
pallets/transfer-allowlist/* @mustermeiszer

## Changes to specific libraries
libs/mock-builder/* @lemunozm
Expand All @@ -41,9 +38,9 @@ libs/traits/src/changes.rs @lemunozm
libs/traits/src/data.rs @lemunozm

## Changes to runtime
runtime/common/* @branan @mikiquantum @mustermeiszer @NunoAlexandre @offerijns @lemunozm
runtime/altair/* @branan @mikiquantum @mustermeiszer @NunoAlexandre @offerijns @wischli
runtime/centrifuge/* @branan @mikiquantum @mustermeiszer @NunoAlexandre @offerijns @wischli
runtime/common/* @mustermeiszer @NunoAlexandre @hieronx @lemunozm
runtime/altair/* @mustermeiszer @NunoAlexandre @hieronx @wischli
runtime/centrifuge/* @mustermeiszer @NunoAlexandre @hieronx @wischli

## Changes to integration tests
runtime/integration-tests/* @mustermeiszer @NunoAlexandre @wischli @cdamian
Expand Down
4 changes: 2 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.
[description]

Fixes # (issue)
Fixes #(issue)

## Changes and Descriptions

Expand Down
85 changes: 73 additions & 12 deletions pallets/loans/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,19 @@ use sp_std::time::Duration;

use crate::{
entities::{
changes::{Change, LoanMutation},
input::{PrincipalInput, RepaidInput},
loans::LoanInfo,
pricing::{
internal::{InternalPricing, MaxBorrowAmount},
Pricing, PricingAmount, RepaidPricingAmount,
Pricing,
},
},
pallet::*,
types::{
valuation::{DiscountedCashFlow, ValuationMethod},
BorrowRestrictions, InterestPayments, LoanMutation, LoanRestrictions, Maturity,
PayDownSchedule, RepayRestrictions, RepaymentSchedule,
BorrowRestrictions, InterestPayments, LoanRestrictions, Maturity, PayDownSchedule,
RepayRestrictions, RepaymentSchedule,
},
};

Expand Down Expand Up @@ -185,7 +187,7 @@ where
RawOrigin::Signed(borrower).into(),
pool_id,
loan_id,
PricingAmount::Internal(10.into()),
PrincipalInput::Internal(10.into()),
)
.unwrap();
}
Expand All @@ -196,8 +198,8 @@ where
RawOrigin::Signed(borrower).into(),
pool_id,
loan_id,
RepaidPricingAmount {
principal: PricingAmount::Internal(10.into()),
RepaidInput {
principal: PrincipalInput::Internal(10.into()),
interest: T::Balance::max_value(),
unscheduled: 0.into(),
},
Expand Down Expand Up @@ -225,7 +227,7 @@ where
// to obtain the ChangeId used previously.
T::ChangeGuard::note(
pool_id,
ChangeOf::<T>::Loan(loan_id, Self::create_mutation()).into(),
Change::<T>::Loan(loan_id, Self::create_mutation()).into(),
)
.unwrap()
}
Expand All @@ -243,7 +245,40 @@ where
// We need to call noted again
// (that is idempotent for the same change and instant)
// to obtain the ChangeId used previously.
T::ChangeGuard::note(pool_id, ChangeOf::<T>::Policy(policy).into()).unwrap()
T::ChangeGuard::note(pool_id, Change::<T>::Policy(policy).into()).unwrap()
}

fn propose_transfer_debt(pool_id: T::PoolId) -> T::Hash {
let borrower = account("borrower", 0, 0);
let loan_1 = Helper::<T>::create_loan(pool_id, u16::MAX.into());
Helper::<T>::borrow_loan(pool_id, loan_1);
let loan_2 = Helper::<T>::create_loan(pool_id, (u16::MAX - 1).into());

let repaid_amount = RepaidInput {
principal: PrincipalInput::Internal(10.into()),
interest: 0.into(),
unscheduled: 0.into(),
};
let borrow_amount = PrincipalInput::Internal(10.into());

Pallet::<T>::propose_transfer_debt(
RawOrigin::Signed(borrower).into(),
pool_id,
loan_1,
loan_2,
repaid_amount.clone(),
borrow_amount.clone(),
)
.unwrap();

// We need to call noted again
// (that is idempotent for the same change and instant)
// to obtain the ChangeId used previously.
T::ChangeGuard::note(
pool_id,
Change::<T>::TransferDebt(loan_1, loan_2, repaid_amount, borrow_amount).into(),
)
.unwrap()
}

fn set_policy(pool_id: T::PoolId) {
Expand All @@ -255,7 +290,7 @@ where
}

fn expire_loan(pool_id: T::PoolId, loan_id: T::LoanId) {
Pallet::<T>::expire(pool_id, loan_id).unwrap();
Pallet::<T>::expire_action(pool_id, loan_id).unwrap();
}

fn initialize_active_state(n: u32) -> T::PoolId {
Expand Down Expand Up @@ -323,7 +358,7 @@ benchmarks! {
let pool_id = Helper::<T>::initialize_active_state(n);
let loan_id = Helper::<T>::create_loan(pool_id, u16::MAX.into());

}: _(RawOrigin::Signed(borrower), pool_id, loan_id, PricingAmount::Internal(10.into()))
}: _(RawOrigin::Signed(borrower), pool_id, loan_id, PrincipalInput::Internal(10.into()))

repay {
let n in 1..Helper::<T>::max_active_loans() - 1;
Expand All @@ -333,8 +368,8 @@ benchmarks! {
let loan_id = Helper::<T>::create_loan(pool_id, u16::MAX.into());
Helper::<T>::borrow_loan(pool_id, loan_id);

let repaid = RepaidPricingAmount {
principal: PricingAmount::Internal(10.into()),
let repaid = RepaidInput {
principal: PrincipalInput::Internal(10.into()),
interest: 0.into(),
unscheduled: 0.into()
};
Expand Down Expand Up @@ -423,6 +458,32 @@ benchmarks! {
verify {
assert!(Pallet::<T>::portfolio_valuation(pool_id).value() > Zero::zero());
}

propose_transfer_debt {
let n in 2..Helper::<T>::max_active_loans() - 2;

let borrower = account("borrower", 0, 0);
let pool_id = Helper::<T>::initialize_active_state(n);
let loan_1 = Helper::<T>::create_loan(pool_id, u16::MAX.into());
Helper::<T>::borrow_loan(pool_id, loan_1);
let loan_2 = Helper::<T>::create_loan(pool_id, (u16::MAX - 1).into());

let repaid_amount = RepaidInput {
principal: PrincipalInput::Internal(10.into()),
interest: 0.into(),
unscheduled: 0.into()
};
let borrow_amount = PrincipalInput::Internal(10.into());

}: _(RawOrigin::Signed(borrower), pool_id, loan_1, loan_2, repaid_amount, borrow_amount)

apply_transfer_debt {
let any = account("any", 0, 0);
let pool_id = Helper::<T>::prepare_benchmark();
let change_id = Helper::<T>::propose_transfer_debt(pool_id);

}: _(RawOrigin::Signed(any), pool_id, change_id)

}

impl_benchmark_test_suite!(
Expand Down
43 changes: 43 additions & 0 deletions pallets/loans/src/entities/changes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use cfg_primitives::Moment;
use cfg_traits::interest::InterestRate;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{storage::bounded_vec::BoundedVec, RuntimeDebug};
use scale_info::TypeInfo;

use crate::{
entities::input::{PrincipalInput, RepaidInput},
pallet::Config,
types::{
policy::WriteOffRule, valuation::ValuationMethod, InterestPayments, Maturity,
PayDownSchedule,
},
};

/// Active loan mutation for internal pricing
#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebug, MaxEncodedLen)]
pub enum InternalMutation<Rate> {
ValuationMethod(ValuationMethod<Rate>),
ProbabilityOfDefault(Rate),
LossGivenDefault(Rate),
DiscountRate(InterestRate<Rate>),
}

/// Active loan mutation
#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebug, MaxEncodedLen)]
pub enum LoanMutation<Rate> {
Maturity(Maturity),
MaturityExtension(Moment),
InterestRate(InterestRate<Rate>),
InterestPayments(InterestPayments),
PayDownSchedule(PayDownSchedule),
Internal(InternalMutation<Rate>),
}

/// Change description
#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebug, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
pub enum Change<T: Config> {
Loan(T::LoanId, LoanMutation<T::Rate>),
Policy(BoundedVec<WriteOffRule<T::Rate>, T::MaxWriteOffPolicySize>),
TransferDebt(T::LoanId, T::LoanId, RepaidInput<T>, PrincipalInput<T>),
}
58 changes: 58 additions & 0 deletions pallets/loans/src/entities/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::RuntimeDebugNoBound;
use scale_info::TypeInfo;
use sp_runtime::{ArithmeticError, DispatchError};

use crate::{
entities::pricing::external::ExternalAmount,
pallet::{Config, Error},
types::RepaidAmount,
};

#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebugNoBound, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
pub enum PrincipalInput<T: Config> {
Internal(T::Balance),
External(ExternalAmount<T>),
}

impl<T: Config> PrincipalInput<T> {
pub fn balance(&self) -> Result<T::Balance, ArithmeticError> {
match self {
Self::Internal(amount) => Ok(*amount),
Self::External(external) => external.balance(),
}
}

pub fn internal(&self) -> Result<T::Balance, DispatchError> {
match self {
Self::Internal(amount) => Ok(*amount),
Self::External(_) => Err(Error::<T>::MismatchedPricingMethod.into()),
}
}

pub fn external(&self) -> Result<ExternalAmount<T>, DispatchError> {
match self {
Self::Internal(_) => Err(Error::<T>::MismatchedPricingMethod.into()),
Self::External(principal) => Ok(principal.clone()),
}
}
}

#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebugNoBound, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
pub struct RepaidInput<T: Config> {
pub principal: PrincipalInput<T>,
pub interest: T::Balance,
pub unscheduled: T::Balance,
}

impl<T: Config> RepaidInput<T> {
pub fn repaid_amount(&self) -> Result<RepaidAmount<T::Balance>, ArithmeticError> {
Ok(RepaidAmount {
principal: self.principal.balance()?,
interest: self.interest,
unscheduled: self.unscheduled,
})
}
}
Loading

0 comments on commit c7260b5

Please sign in to comment.