Skip to content

Commit

Permalink
feat: fix linear pricing migration (#1838)
Browse files Browse the repository at this point in the history
  • Loading branch information
wischli authored May 23, 2024
1 parent 2a691e9 commit 45be927
Show file tree
Hide file tree
Showing 7 changed files with 390 additions and 3 deletions.
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,
}
}
}

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

0 comments on commit 45be927

Please sign in to comment.