Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into loans/multi-cashflows
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Jun 5, 2024
2 parents 3321024 + 4b9e47e commit 205fb68
Show file tree
Hide file tree
Showing 38 changed files with 1,239 additions and 361 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ jobs:
- name: upload Docs files
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0
with:
name: github-pages
path: ./target/doc
retention-days: 1

- name: Deploy Docs
# if: github.ref == 'refs/heads/main'
Expand Down
3 changes: 2 additions & 1 deletion pallets/loans/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type MaxRateCountOf<T> = <<T as Config>::InterestAccrual as InterestAccrual<
fn config_mocks() {
use cfg_mocks::pallet_mock_data::util::MockDataCollection;

use crate::tests::mock::{MockChangeGuard, MockPermissions, MockPools, MockPrices};
use crate::tests::mock::{MockChangeGuard, MockPermissions, MockPools, MockPrices, MockTimer};

MockPermissions::mock_add(|_, _, _| Ok(()));
MockPermissions::mock_has(|_, _, _| true);
Expand All @@ -74,6 +74,7 @@ fn config_mocks() {
MockChangeGuard::mock_released(move |_, _| Ok(change.clone()));
Ok(sp_core::H256::default())
});
MockTimer::mock_now(|| 0);
}

struct Helper<T>(sp_std::marker::PhantomData<T>);
Expand Down
3 changes: 2 additions & 1 deletion pallets/loans/src/entities/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
entities::pricing::external::ExternalAmount,
pallet::{Config, Error},
types::RepaidAmount,
PriceOf,
};

#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebugNoBound, MaxEncodedLen)]
Expand Down Expand Up @@ -61,6 +62,6 @@ impl<T: Config> RepaidInput<T> {
#[scale_info(skip_type_params(T))]
pub enum PriceCollectionInput<T: Config> {
Empty,
Custom(BoundedBTreeMap<T::PriceId, T::Balance, T::MaxActiveLoansPerPool>),
Custom(BoundedBTreeMap<T::PriceId, PriceOf<T>, T::MaxActiveLoansPerPool>),
FromRegistry,
}
110 changes: 105 additions & 5 deletions pallets/loans/src/entities/loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::{
BorrowLoanError, BorrowRestrictions, CloseLoanError, CreateLoanError, LoanRestrictions,
MutationError, RepaidAmount, RepayLoanError, RepayRestrictions,
},
PriceOf,
};

/// Loan information.
Expand Down Expand Up @@ -227,7 +228,7 @@ impl<T: Config> ActiveLoan<T> {
self.origination_date
}

pub fn maturity_date(&self) -> Seconds {
pub fn maturity_date(&self) -> Option<Seconds> {
self.schedule.maturity.date()
}

Expand Down Expand Up @@ -275,9 +276,10 @@ impl<T: Config> ActiveLoan<T> {
) -> Result<bool, DispatchError> {
let now = T::Time::now();
match trigger {
WriteOffTrigger::PrincipalOverdue(overdue_secs) => {
Ok(now >= self.maturity_date().ensure_add(*overdue_secs)?)
}
WriteOffTrigger::PrincipalOverdue(overdue_secs) => match self.maturity_date() {
Some(maturity) => Ok(now >= maturity.ensure_add(*overdue_secs)?),
None => Ok(false),
},
WriteOffTrigger::PriceOutdated(secs) => match &self.pricing {
ActivePricing::External(pricing) => {
Ok(now >= pricing.last_updated(pool_id).ensure_add(*secs)?)
Expand Down Expand Up @@ -306,7 +308,7 @@ impl<T: Config> ActiveLoan<T> {
pub fn present_value_by<Rates>(
&self,
rates: &Rates,
prices: &BTreeMap<T::PriceId, T::Balance>,
prices: &BTreeMap<T::PriceId, PriceOf<T>>,
) -> Result<T::Balance, DispatchError>
where
Rates: RateCollection<T::Rate, T::Balance, T::Balance>,
Expand Down Expand Up @@ -599,3 +601,101 @@ impl<T: Config> TryFrom<(T::PoolId, ActiveLoan<T>)> for ActiveLoanInfo<T> {
})
}
}

/// Adds `with_linear_pricing` to ExternalPricing struct for migration to v4
pub mod v3 {
use cfg_traits::{interest::InterestRate, Seconds};
use parity_scale_codec::{Decode, Encode};

use crate::{
entities::{
loans::BlockNumberFor,
pricing::external::v3::{ActivePricing, Pricing},
},
types::{cashflow::RepaymentSchedule, LoanRestrictions, RepaidAmount},
AssetOf, Config,
};

#[derive(Encode, Decode)]
pub struct ActiveLoan<T: Config> {
schedule: RepaymentSchedule,
collateral: AssetOf<T>,
restrictions: LoanRestrictions,
borrower: T::AccountId,
write_off_percentage: T::Rate,
origination_date: Seconds,
pricing: ActivePricing<T>,
total_borrowed: T::Balance,
total_repaid: RepaidAmount<T::Balance>,
repayments_on_schedule_until: Seconds,
}

impl<T: Config> ActiveLoan<T> {
pub fn migrate(self, with_linear_pricing: bool) -> super::ActiveLoan<T> {
super::ActiveLoan {
schedule: self.schedule,
collateral: self.collateral,
restrictions: self.restrictions,
borrower: self.borrower,
write_off_percentage: self.write_off_percentage,
origination_date: self.origination_date,
pricing: self.pricing.migrate(with_linear_pricing),
total_borrowed: self.total_borrowed,
total_repaid: self.total_repaid,
repayments_on_schedule_until: self.repayments_on_schedule_until,
}
}
}

#[derive(Encode, Decode)]
pub struct CreatedLoan<T: Config> {
info: LoanInfo<T>,
borrower: T::AccountId,
}

impl<T: Config> CreatedLoan<T> {
pub fn migrate(self, with_linear_pricing: bool) -> super::CreatedLoan<T> {
super::CreatedLoan::<T>::new(self.info.migrate(with_linear_pricing), self.borrower)
}
}

#[derive(Encode, Decode)]
pub struct ClosedLoan<T: Config> {
closed_at: BlockNumberFor<T>,
info: LoanInfo<T>,
total_borrowed: T::Balance,
total_repaid: RepaidAmount<T::Balance>,
}

impl<T: Config> ClosedLoan<T> {
pub fn migrate(self, with_linear_pricing: bool) -> super::ClosedLoan<T> {
super::ClosedLoan::<T> {
closed_at: self.closed_at,
info: self.info.migrate(with_linear_pricing),
total_borrowed: self.total_borrowed,
total_repaid: self.total_repaid,
}
}
}

#[derive(Encode, Decode)]
pub struct LoanInfo<T: Config> {
pub schedule: RepaymentSchedule,
pub collateral: AssetOf<T>,
pub interest_rate: InterestRate<T::Rate>,
pub pricing: Pricing<T>,
pub restrictions: LoanRestrictions,
}

impl<T: Config> LoanInfo<T> {
pub fn migrate(self, with_linear_pricing: bool) -> super::LoanInfo<T> {
super::LoanInfo::<T> {
pricing: self.pricing.migrate(with_linear_pricing),
schedule: self.schedule,
collateral: self.collateral,
interest_rate: self.interest_rate,
restrictions: self.restrictions,
}
}
}
}
Loading

0 comments on commit 205fb68

Please sign in to comment.