Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fix linear pricing migration #1838

Merged
merged 10 commits into from
May 23, 2024
98 changes: 98 additions & 0 deletions pallets/loans/src/entities/loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,3 +582,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::{LoanRestrictions, RepaidAmount, RepaymentSchedule},
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,
}
}
}
}
92 changes: 92 additions & 0 deletions pallets/loans/src/entities/pricing/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,95 @@ impl<T: Config> ExternalActivePricing<T> {
Ok(())
}
}

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

use crate::{
entities::{
interest::ActiveInterestRate,
pricing::{external::MaxBorrowAmount, internal, internal::InternalActivePricing},
},
Config,
};

#[derive(Encode, Decode)]
pub enum Pricing<T: Config> {
Internal(internal::InternalPricing<T>),
External(ExternalPricing<T>),
}

impl<T: Config> Pricing<T> {
pub fn migrate(self, with_linear_pricing: bool) -> crate::entities::pricing::Pricing<T> {
match self {
Pricing::Internal(i) => crate::entities::pricing::Pricing::Internal(i),
Pricing::External(e) => {
crate::entities::pricing::Pricing::External(e.migrate(with_linear_pricing))
}
}
}
}

#[derive(Encode, Decode)]
pub struct ExternalPricing<T: Config> {
pub price_id: T::PriceId,
pub max_borrow_amount: MaxBorrowAmount<T::Quantity>,
pub notional: T::Balance,
pub max_price_variation: T::Rate,
}

#[derive(Encode, Decode)]
pub enum ActivePricing<T: Config> {
Internal(InternalActivePricing<T>),
External(ExternalActivePricing<T>),
}

impl<T: Config> ActivePricing<T> {
pub fn migrate(
self,
with_linear_pricing: bool,
) -> crate::entities::pricing::ActivePricing<T> {
match self {
ActivePricing::Internal(i) => crate::entities::pricing::ActivePricing::Internal(i),
ActivePricing::External(e) => crate::entities::pricing::ActivePricing::External(
e.migrate(with_linear_pricing),
),
}
}
}

#[derive(Encode, Decode)]
pub struct ExternalActivePricing<T: Config> {
info: ExternalPricing<T>,
outstanding_quantity: T::Quantity,
pub interest: ActiveInterestRate<T>,
latest_settlement_price: T::Balance,
settlement_price_updated: Seconds,
}

impl<T: Config> ExternalActivePricing<T> {
pub fn migrate(self, with_linear_pricing: bool) -> super::ExternalActivePricing<T> {
super::ExternalActivePricing {
info: self.info.migrate(with_linear_pricing),
outstanding_quantity: self.outstanding_quantity,
interest: self.interest,
latest_settlement_price: self.latest_settlement_price,
settlement_price_updated: self.settlement_price_updated,
lemunozm marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

impl<T: Config> ExternalPricing<T> {
pub fn migrate(self, with_linear_pricing: bool) -> super::ExternalPricing<T> {
super::ExternalPricing {
price_id: self.price_id,
max_borrow_amount: self.max_borrow_amount,
notional: self.notional,
max_price_variation: self.max_price_variation,
with_linear_pricing,
}
}
}
}
6 changes: 3 additions & 3 deletions pallets/loans/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub mod pallet {
pub type AssetOf<T> = (<T as Config>::CollectionId, <T as Config>::ItemId);
pub type PriceOf<T> = (<T as Config>::Balance, <T as Config>::Moment);

const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(4);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
Expand Down Expand Up @@ -232,7 +232,7 @@ pub mod pallet {

/// Storage for loans that has been created but are not still active.
#[pallet::storage]
pub(crate) type CreatedLoan<T: Config> = StorageDoubleMap<
pub type CreatedLoan<T: Config> = StorageDoubleMap<
_,
Blake2_128Concat,
T::PoolId,
Expand All @@ -259,7 +259,7 @@ pub mod pallet {
/// No mutations are expected in this storage.
/// Loans are stored here for historical purposes.
#[pallet::storage]
pub(crate) type ClosedLoan<T: Config> = StorageDoubleMap<
pub type ClosedLoan<T: Config> = StorageDoubleMap<
_,
Blake2_128Concat,
T::PoolId,
Expand Down
1 change: 1 addition & 0 deletions runtime/centrifuge/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ pub type UpgradeCentrifuge1029 = (
runtime_common::migrations::increase_storage_version::Migration<OraclePriceFeed, 0, 1>,
runtime_common::migrations::increase_storage_version::Migration<OraclePriceCollection, 0, 1>,
pallet_collator_selection::migration::v1::MigrateToV1<crate::Runtime>,
runtime_common::migrations::loans::AddWithLinearPricing<crate::Runtime>,
);
Loading
Loading