1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
// Copyright 2023 Centrifuge Foundation (centrifuge.io).
// This file is part of Centrifuge chain project.
// Centrifuge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version (see http://www.gnu.org/licenses).
// Centrifuge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//! Contains base types without Config references
use frame_support::{pallet_prelude::RuntimeDebug, PalletError};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::{traits::EnsureAdd, ArithmeticError};
pub mod cashflow;
pub mod policy;
pub mod valuation;
/// Error related to loan creation
#[derive(Encode, Decode, TypeInfo, PalletError)]
pub enum CreateLoanError {
/// Emits when valuation method is incorrectly specified
InvalidValuationMethod,
/// Emits when repayment schedule is incorrectly specified
InvalidRepaymentSchedule,
/// Emits when a borrow restriction is incorrect
InvalidBorrowRestriction,
/// Emits when a repay restriction is incorrect
InvalidRepayRestriction,
}
/// Error related to loan borrowing
#[derive(Encode, Decode, TypeInfo, PalletError)]
pub enum BorrowLoanError {
/// Emits when the borrowed amount is more than the allowed amount
MaxAmountExceeded,
/// Emits when the loan can not be borrowed because of a restriction
Restriction,
/// Emits when maturity has passed and borrower tried to borrow more
MaturityDatePassed,
/// Emits when the cashflow payment is overdue
PaymentOverdue,
}
/// Error related to loan borrowing
#[derive(Encode, Decode, TypeInfo, PalletError)]
pub enum RepayLoanError {
/// Emits when the loan can not be borrowed because of a restriction
Restriction,
/// Emits when the principal amount is more than the borrowed amount
MaxPrincipalAmountExceeded,
}
/// Error related to loan borrowing
#[derive(Encode, Decode, TypeInfo, PalletError)]
pub enum WrittenOffError {
/// Emits when a write off action tries to write off the more than the
/// policy allows
LessThanPolicy,
}
/// Error related to loan closing
#[derive(Encode, Decode, TypeInfo, PalletError)]
pub enum CloseLoanError {
/// Emits when close a loan that is not fully repaid
NotFullyRepaid,
}
/// Error related to loan modifications
#[derive(Encode, Decode, TypeInfo, PalletError)]
pub enum MutationError {
/// Emits when a modification expect the loan to have a discounted cash flow
/// valuation method
DiscountedCashFlowExpected,
/// Emits when a modification expect the loan to have an iternal pricing.
InternalPricingExpected,
/// Maturity extensions exceed max extension allowed.
MaturityExtendedTooMuch,
}
/// Specify how offer a loan can be borrowed
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub enum BorrowRestrictions {
/// The loan can not be borrowed if it has been written off.
NotWrittenOff,
/// You only can borrow the full loan value once.
FullOnce,
/// The externally priced loan can only be borrowed
/// once an oracle price exists.
OraclePriceRequired,
}
/// Specify how offer a loan can be repaid
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub enum RepayRestrictions {
/// No restrictions
None,
/// You only can repay the full loan value.
Full,
}
/// Define the loan restrictions
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct LoanRestrictions {
/// How offen can be borrowed
pub borrows: BorrowRestrictions,
/// How offen can be repaid
pub repayments: RepayRestrictions,
}
#[derive(Default, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebug, MaxEncodedLen)]
pub struct RepaidAmount<Balance> {
pub principal: Balance,
pub interest: Balance,
pub unscheduled: Balance,
}
impl<Balance: EnsureAdd + Copy> RepaidAmount<Balance> {
pub fn effective(&self) -> Result<Balance, ArithmeticError> {
self.principal.ensure_add(self.interest)
}
pub fn total(&self) -> Result<Balance, ArithmeticError> {
self.principal
.ensure_add(self.interest)?
.ensure_add(self.unscheduled)
}
pub fn ensure_add_assign(&mut self, other: &Self) -> Result<(), ArithmeticError> {
self.principal.ensure_add_assign(other.principal)?;
self.interest.ensure_add_assign(other.interest)?;
self.unscheduled.ensure_add_assign(other.unscheduled)
}
}