0066 XLS - 66d: XRP Ledger-native Lending Protocol #190
Replies: 8 comments 19 replies
-
Personally I would have designed all of this to abide by the current security laws in the US but thats just me. As these proposals sit, one could invest into a pool, then the managers of that pool could make investment decisions that they don't agree with. This is why we have the current laws set up the way we do in the US. I.E. A prospectus is created, an N-1 is filed, then citizens can invest into the These proposals, imo, add complex risk and will likely violate current securities laws but don't let that stop you, I still like the ideas. |
Beta Was this translation helpful? Give feedback.
-
I feel like a pool should have the option to have some type of uri/data field that it can use to link to external resources, you could put a bunch of usefull stuff behind that like a contacts page of the fund management, page informing about registration (i think lending will almost likely lead to it needing to be registered with the gov in some form) etc |
Beta Was this translation helpful? Give feedback.
-
I like how you included This makes it very clear what the results of each transaction are. |
Beta Was this translation helpful? Give feedback.
-
It seems to me that a malicious account could take away a user's funds by controlling both the delegator and the borrower, is that correct? Users have to fully evaluate the delegator. |
Beta Was this translation helpful? Give feedback.
-
I'm particularly interested in how we're planning to tackle potential fraud or manipulation by borrowers or pool delegates. Given the off-chain underwriting and the significant responsibilities pool delegates hold, how are we making sure everything stays above board? |
Beta Was this translation helpful? Give feedback.
-
Are we also thinking of flash loans, leverage or settlement loans? How will this integrate with escrow as some of the basic functionality for lending could be applied or borrowed. Cheers |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Is the outstanding principal the principal amount - drawable amount? This might create issues on a term loan if you allow multiple draw down events. Doing an "Open Ended" Loan Pool makes things much more complex. Iterating through both Contributors and Composition is alot of work. If the composition is submitted as part of the transactor, is it possible that the loan provider can choose whoever they want? Is this a legal issue? Could that loan/borrower always choose 100% of UserA assets thereby avoiding interest to specific liquidity providers in the pool? Updating every contributor is a lot for every deposit/loan/withdraw transaction. Not a big deal if the number is limited but at 1000 contributors thats not going to work well. Even more so, allowing withdraw/deposit of amounts "pledged" during a loan will make things very complex. You can calculate the withdraw amount in the transactor if you have the total outstanding loans on an object but this means that the user couldn't withdraw any amount "pledged" until the loan is closed. This is how I would structure it. Allowing the User to withdraw after each payment is adding complexity that I really dont believe is needed. Ex. You and I deposit 100 each. A loan is made for 100. Thats 50% you and 50% me. I can withdraw 50 now and 50 + interest when the loan closes (or if the loan defaults then less). By allowing rolling withdraws you also open the door for users to each month pull the interest + principal they pledged. Max Cover doesnt make any sense. In general the pool delegate doesn't make sense to me. GracePeriod & PaymentInterval are UINT32. Some additional notes: Loans take awhile to underwrite so by the time the loan is finalized, there may not be liquidity in the pool. Underwriters would need to manage this. You could solve this by having another transaction for LoanProposal to "lock" funds so that its clear when underwriting how much funds are available. The idea you have is that more liquidity could be deposited, which would require asking the pool or others to deposit more liquidity. This makes sense in theory but imo its backwards. In practice you would write a loan application, then seek liquidity or underwrite the loan and that would then receive approval from the liquidity providers.
I would do this.
Imo this makes it much more peer to peer. The borrower can create their application and submit that to the ledger for any pool to approve of. |
Beta Was this translation helpful? Give feedback.
-
Lending Protocol
Abstract
Decentralized Finance (DeFi) lending represents a transformative force within the blockchain ecosystem. It revolutionizes traditional financial services by offering a peer-to-peer alternative without intermediaries like banks or financial institutions. At its core, DeFi lending platforms empower users to borrow and lend digital assets directly, fostering financial inclusion, transparency, and efficiency.
This proposal introduces fundamental primitives for an XRP Ledger-native Lending Protocol. The protocol offers straightforward on-chain uncollateralized fixed-term loans, utilizing pooled funds with pre-set terms for interest-accruing loans. The design relies on off-chain underwriting and risk management to assess the creditworthiness of the borrowers. However, the First-Loss Capital protection scheme absorbs some losses in case of a Loan Default.
This version intentionally skips the complex mechanisms of automated on-chain collateral and liquidation management. Instead, it focuses on the primitives and the essential components for on-chain credit origination. Therefore, the primary design principle is flexibility and reusability to enable the introduction of additional complex features in the future.
1. Introduction
1.1 Overview
The Lending Protocol uses the Vault on-chain object to provision assets from one or more depositors. A Loan Broker is responsible for managing the Lending Protocol and the associated Vault. The Vault Owner and Loan Broker must be on the same account, but this may change in the future.
The specification introduces two new ledger entries:
LoanBroker
andLoan
. TheLoanBroker
object captures the Lending Protocol-specific details, such as fees and First-Loss Capital cover. Furthermore, it tracks the funds taken from theVault
. TheLoan
object captures the Loan agreement between the Loan Broker and the Borrower.The specification introduces the following transactions:
LoanBrokerSet
: A transaction to create a newLoanBroker
object.LoanBrokerDelete
: A transaction to delete an existingLoanBroker
object.LoanBrokerCollateralDeposit
: A transaction to deposit First-Loss Capital.LoanBrokerCollateralWithdraw
: A transaction to withdraw First-Loss Capital.LoanSet
: A transaction to create a newLoan
object.LoanDelete
: A transaction to delete an existingLoan
object.LoanManage
: A transaction to manage an existingLoan
.LoanDraw
: A transaction to drawdownLoan
funds.LoanPay
: A transaction to make aLoan
payment.The flow of the lending protocol is as follows:
Vault
ledger entry.LoanBroker
ledger entry with aLoanBrokerSet
transaction.Vault
.LoanBroker
with theLoanBrokerCollateralDeposit
transaction.Loan
object with aLoanSet
transaction.LoanDraw
transaction and make payments with theLoanPay
.Loan
using theLoanManage
transaction.LoanDelete
transaction.LoanBrokerCollateralWithdraw
transaction.Loan
objects are deleted, the Loan Broker can delete theLoanBroker
object with aLoanBrokerDelete
transaction.LoanBroker
objects are deleted, the Loan Broker can delete theVault
object.1.2 Compliance Features
1.2.1 Clawback
Clawback is a mechanism by which an asset Issuer (IOU or MPT, not XRP) claws back the funds. It can be performed on the Vault, not the Lending Protocol.
1.2.2 Freeze
Freeze is a mechanism by which an asset Issuer (IOUT or MPT, not XRP) freezes an
Account
, preventing that account from sending or receiving the Asset. Furthermore, an Issuer may enact a global freeze, which prevents everyone from sending or receiving the Asset. Note that in both single-account and global freezes, the Asset can be sent to the Issuer.If the Issuer freezes a Borrower's account, the Borrower cannot make loan payments or draw down funds. A frozen account does not lift the obligation to repay a Loan.
If a Loan Broker's account is frozen, the Broker will not receive any Loan fees. They will be able to create new loans, and existing loans will not be affected. However, the Loan Broker cannot deposit or withdraw First-Loss Capital.
Finally, the exact behaviour has yet to be defined in a global freeze. TBD
1.3 Risk Management
Risk management involves mechanisms that mitigate the risks associated with lending. To protect investors' assets, we have introduced an optional first-loss capital protection scheme. This scheme requires the Loan Broker to deposit a fund that can be partially liquidated to cover losses in the event of a loan default. The amount of first-loss capital required is a percentage of the total debt owed to the Vault. In case of a default, a portion of the first-loss capital will be liquidated based on the minimum required cover. The liquidated capital is placed back into the Vault to cover some of the loss.
1.4 Interest Rates
There are three basic interest rates associated with a Loan:
Interest Rate
: The regular interest rate based on the principal amount. It is the cost of borrowing funds.Late Interest Rate
: A higher interest rate charged for a late payment.Full Payment Rate
: An interest rate charged for repaying the total Loan early.1.5 Fees
The lending protocol charges a number of fees that the Loan Broker can configure. The protocol will not charge the fees if the Loan Broker has not deposited enough First-Loss Capital.
Management Fee
: This is a percentage of interest charged by the Loan Broker. Intuitively, the Vault depositors pay this fee.Loan Origination Fee
: A nominal fee paid to the Loan Broker taken from the principal lent.Loan Service Fee
: A nominal fee paid on top of each loan payment.Late Payment Fee
: A nominal fee paid on top of a late payment.Early Payment Fee
: A nominal fee paid on top of an early payment.1.6 Terminology
1.6.1 Terms
Fixed-Term Loan
: A type of Loan with a known end date and a constant periodic payment schedule.Principal
: The original sum of money borrowed that must be repaid, excluding interest or other fees.Interest
: The cost of borrowing the Asset, calculated as a percentage of the loan principal, which the Borrower pays to the Lender over time.Drawdown
: The process where a borrower accesses part or all of the loan funds after the Loan has been created.Default
: The failure by the Borrower to meet the obligations of a loan, such as missing payments.First-Loss Capital
: The portion of capital that absorbs initial losses in case of a Default, protecting the Vault from loss.Term
: The period over which a Borrower must repay the Loan.Amortization
: The gradual repayment of a loan through scheduled payments that cover both interest and principal over time.Repayment Schedule
: A detailed plan that outlines when and how much a borrower must pay to repay the Loan fLoan.Grace Period
: A set period after the Loan's due date after which the Loan Broker can default the LoanOrigination Fee
: A nominal one-time fee the loan broker charges for processing a new loan application.Service Fee
: A recurring nominal charge the Borrower pays during Loan payment.Management Fee
: A percentage fee charged by the Borrower on the loan interest before returning the interest to the Vault.Late Payment Fee
: A penalty charged to the Borrower for failing to make a payment on or before its due date.Interest Rate
: The percentage charged by the loan broker on the loan principal, representing the cost of borrowing.Late Interest Rate
: A higher interest rate applied to overdue loan payments as a penalty for late repayment.Closing Interest Rate
: The final interest rate charged when the Loan is closed or fully repaid.1.6.2 Actors
LoanBroker
: The entity issuing the Loan.Borrower
: The account that is borrowing funds.1.7 System Diagram
2. Ledger Entries
2.1. LoanBroker Ledger Entry
The
LoanBroker
object captures attributes of the Lending Protocol.2.1.1 Object Identifier
The key of the
LoanBroker
object is the result ofSHA512-Half
of the following values concatenated in order:LoanBroker
space key0x006C
(Lower-casel
).AccountID
(https://xrpl.org/docs/references/protocol/binary-format/#accountid-fields) of the account submitting theLoanBrokerSet
transaction, i.e.Lender
.Sequence
number. If the transaction used a Ticket, use theTicketSequence
value.2.1.2 Fields
The
LoanBroker
object has the following fields:LedgerEntryType
N/A
string
UINT16
LedgerIndex
N/A
string
UINT16
N/A
Flags
Yes
string
UINT32
PreviousTxnID
N/A
string
HASH256
N/A
PreviousTxnLgrSeq
N/A
number
UINT32
N/A
Sequence
N/A
number
UINT32
N/A
LoanBroker
.OwnerNode
N/A
number
UINT64
N/A
VaultID
No
string
HASH256
N/A
Owner
No
string
AccountID
N/A
Data
Yes
string
BLOB
ManagementFeeRate
No
number
UINT16
OwnerCount
N/A
number
UINT32
LoanBroker
.DebtTotal
N/A
number
NUMBER
DebtMaximum
Yes
number
NUMBER
CoverAvailable
N/A
number
NUMBER
CoverRateMinimum
No
number
UINT16
DebtTotal
that the first loss capital must cover. Valid values are between 0 and 100000 inclusive. A value of 1 is equivalent to 1/10 bps or 0.001%.CoverRateLiquidation
No
number
UINT16
2.1.3 Lending Protocol
_pseudo-account_
The Lending Protocol uses the
_pseudo-account_
of the associatedVault
object to hold the First-Loss Capital.2.1.4 Ownership
The lending protocol object is stored in the ledger and tracked in an Owner Directory owned by the account submitting the
LoanBrokerSet
transaction. Furthermore, the object is also tracked in theOwnerDirectory
of thepseudo-account
.The
LoanBroker
requires tracking associatedLoan
objects to prevent theLoanBroker
object from being deleted while loans are active as well as future RPC endpoints. Therefore, theLoanBroker
has an associated Owner Directory object.The
RootIndex
of theDirectoryNode
object is the result ofSHA512-Half
of the following values concatenated in order:OwnerDirectory
space key0x004F
LoanBrokerID
2.1.5 Reserves
The
LoanBroker
object costs one owner reserve for the account creating it.2.1.6 Accounting
The Lending Protocol tracks the funds owed to the associated Vault in the$DebtTotal \geq DebtMaximum$ , the Lender cannot issue new loans until some of the debt is cleared. Furthermore, the Lender may not issue a loan that would cause the
DebtTotal
attribute. It captures the principal amount taken from the Vault and the interest due, excluding all fees. TheDebtMaximum
attribute controls the maximum debt a Lending Protocol may incur. Whenever the Lender issues a Loan,DebtTotal
is incremented by the Loan principal and interest, excluding fees. WhenDebtTotal
to exceedDebtMaximum
.Example
2.1.7 First-Loss Capital
The First-Loss Capital is an optional mechanism to protect the Vault depositors from incurring a loss in case of a Loan default. The first loss of capital absorbs some of the loss. The following parameters control the First-Loss Capital:
CoverAvailable
- the total amount of cover deposited by the Lending Protocol Owner.CoverRateMinimum
- the percentage ofDebtTotal
that must be covered by theCoverAvailable
.CoverRateLiquidation
- the maximum percentage of the minimum required cover (Whenever the available cover falls below the minimum cover required, two consequences occur:
Examples
2.2.
Loan
Ledger EntryA Loan ledger entry captures various Loan terms on-chain. It is an agreement between the Borrower and the loan issuer.
2.2.1 Object Identifier
The
LoanID
is calculated as follows:SHA512-Half
of the following values:Loan
space key0x004C
(capital L)AccountID
of the Borrower account.LoanBrokerID
of the associatedLoanBroker
object.Sequence
number of theLoanSet
transaction. If the transaction used a Ticket, use theTicketSequence
value.2.2.2 Fields
LedgerEntryType
N/A
string
UINT16
LedgerIndex
N/A
string
UINT16
N/A
Flags
Yes
string
UINT32
PreviousTxnID
N/A
string
HASH256
N/A
PreviousTxnLgrSeq
N/A
number
UINT32
N/A
Sequence
N/A
number
UINT32
N/A
OwnerNode
N/A
number
UINT64
N/A
LoanBrokerID
No
string
HASH256
N/A
LoanBroker
associated with this Loan Instance.Borrower
No
string
AccountID
N/A
LoanOriginationFee
No
number
NUMBER
N/A
LoanBroker.Owner
when the Loan is created.LoanServiceFee
No
number
NUMBER
N/A
LoanBroker.Owner
with every Loan payment.LatePaymentFee
No
number
NUMBER
N/A
LoanBroker.Owner
when a payment is late.FullPaymentFee
No
number
NUMBER
N/A
LoanBroker.Owner
when a payment full payment is made.InterestRate
No
number
UINT16
N/A
LateInterestRate
No
number
UINT16
N/A
ClosingInterestRate
No
number
UINT16
N/A
PrincipalRequested
No
number
NUMBER
N/A
StartDate
No
number
UINT32
N/A
PaymentsTotal
No
number
UINT32
N/A
PaymentInterval
No
number
UINT32
N/A
GracePeriod
No
number
UINT32
N/A
NextPaymentDueDate
N/A
number
UINT32
N/A
PaymentsRemaining
N/A
number
UINT32
PaymentsTotal
AssetsAvailable
N/A
number
NUMBER
PrincipalRequested
2.2.2.1 Flags
The
Loan
object supports the following flags:lsfDefault
0x0001
No
lsfImpaired
0x0002
Yes
2.2.3 Ownership
The
Loan
objects are stored in the ledger and tracked in an Owner Directory owned by theBorrower
.Furthermore, to facilitate the
Loan
object lookup from theLoanBroker
, the object is also tracked in theOwnerDirectory
associated with theLoanBroker
object.2.2.4 Reserves
The
Loan
object costs one owner reserve for theBorrower
.3. Transactions
3.1. LoanBroker Transactions
In this section we specify the transactions associated with the
LoanBroker
ledger entry.3.1.1
LoanBrokerSet
The transaction creates a new
LoanBroker
object or updates an existing one.TransactionType
string
UINT16
VaultID
string
HASH256
N/A
LoanBrokerID
string
HASH256
N/A
Flags
string
UINT32
Data
string
BLOB
ManagementFeeRate
number
UINT16
DebtMaximum
number
NUMBER
CoverRateMinimum
number
UINT16
DebtTotal
that the first loss capital must cover. Valid values are between 0 and 100000 inclusive.CoverRateLiquidation
number
UINT16
3.1.1.1 Failure Conditions
VaultID
does not exist.Owner
of the associatedVault
object.LoanBroker
object with the specified ID does not exist.3.1.1.2 State Changes
IF transaction creates a new object:
LoanBrokerID
to theOwnerDirectory
of the submitting account.LoanBrokerID
to theOwnerDirectory
of the Vault's_pseudo-account_
.IF transaction updates an existing object:
3.1.1.3 Invariants
TBD
3.1.2
LoanBrokerDelete
TransactionType
string
UINT16
LoanBrokerID
string
HASH256
N/A
3.1.2.1 Failure Conditions
LoanBroker
object with the specified ID does not exist.Owner
of theLoanBroker
.OwnerCount
field is greater than zero.CoverAvailable
is greater than zero.3.1.2.2 State Changes
LoanBrokerID
from theOwnerDirectory
of the submitting account.LoanBrokerID
from theOwnerDirectory
of the Vault's_pseudo-account_
.OwnerDirectory
associated with theLoanBroker
object.3.1.2.3 Invariants
TBD
3.1.3
LoanBrokerCollateralDeposit
The transaction creates a new
LoanBroker
object or updates an existing one.TransactionType
string
UINT16
LoanBrokerID
string
HASH256
N/A
Amount
object
STAmount
3.1.3.1 Failure Conditions
LoanBroker
object withLoanBrokerID
does not exist.Owner
of the associatedLoanBroker
object.Issuer
of the Asset has placed a global freeze, or theLoanBroker.Owner
account is frozen.3.1.3.2 State Changes
IF
Amount
isXRP
:Balance
field of the submitter'sAccountRoot
byAmount
.Balance
field of the Vault's_pseudo-account_
.IF
Amount
isIOU
:TrustLine
between theIssuer
and submittersAccountRoot
byAmount
.TrustLine
theIssuer
and the Vault's_pseudo-account_
.IF
Amount
isMPT
:MPToken
of the submitterAccount
byAmount
.MPToken
of the Vault's_pseudo-account_
byAmount
.Increment
LoanBroker.CoverAvailable
byAmount
.3.1.3.3 Invariants
TBD
3.1.4
LoanBrokerCollateralWithdraw
The
LoanBrokerCollateralWithdraw
transaction withdraws the First-Loss Capital from theLoanBroker
.TransactionType
string
UINT16
LoanBrokerID
string
HASH256
N/A
Amount
object
STAmount
3.2.2.1 Failure conditions
LoanBroker
object withLoanBrokerID
does not exist.Owner
of the associatedLoanBroker
object.LoanBroker.CoverAvailable
is less than theAmount
.Issuer
of the Asset has placed a global freeze, or theLoanBroker.Owner
account is frozen.3.2.2.2 State Changes
IF
Amount
isXRP
:Balance
field of the Vault's_pseudo-account_
.Balance
field of the submitter's orAccountRoot
byAmount
.IF
Amount
isIOU
:TrustLine
between theIssuer
and submittersAccountRoot
byAmount
.TrustLine
theIssuer
and the Vault's_pseudo-account_
.IF
Amount
isMPT
:MPToken
of the submitterAccount
byAmount
.MPToken
of the Vault's_pseudo-account_
byAmount
.Decrement
LoanBroker.CoverAvailable
byAmount
.3.2. Loan Transactions
In this section we specify transactions associated with the
Loan
ledger entry.3.2.1
LoanSet
TransactionThe transaction creates a new
Loan
object.TransactionType
string
UINT16
LoanBrokerID
string
HASH256
N/A
Flags
string
UINT32
Data
string
BLOB
Borrower
string
AccountID
N/A
LoanOriginationFee
number
NUMBER
LoanBroker.Owner
when the Loan is created.LoanServiceFee
number
NUMBER
LoanBroker.Owner
with every Loan payment.LatePaymentFee
number
NUMBER
LoanBroker.Owner
when a payment is late.FullPaymentFee
number
NUMBER
LoanBroker.Owner
when an early full repayment is made.InterestRate
number
UINT16
LateInterestRate
number
UINT16
ClosingInterestRate
number
UINT16
PrincipalRequested
number
NUMBER
N/A
StartDate
number
UINT32
N/A
PaymentsTotal
number
UINT32
PaymentInterval
number
UINT32
GracePeriod
number
UINT32
Lender
object
STObject
N/A
3.2.1.1
Lender
An inner object that contains the signature of the Lender over the transaction. The fields contained in this object are:
SigningPubKey
string
STBlob
N/A
Signature
string
STBlob
N/A
Signature
of the Borrower.Signers
list
STArray
N/A
LoanBroker.Owner
signers to indicate their approval of this transaction.The final transaction must include
Signature
orSigners
.If the$(|signatures| + 1) \times base_fee$
Signers
field is necessary, then the total fee for the transaction will be increased due to the extra signatures that need to be processed, similar to the additional fees for multisigning. The minimum fee will beThe total fee calculation for signatures will now be$(1 + |tx.Signers| + |tx.Lender.Signers|) \times base_fee$ .
This field is not a signing field (it will not be included in transaction signatures, though the
Signature
orSigners
field will be included in the stored transaction).3.2.1.2 Multi-Signing
The
LoanSet
transaction is a mutual agreement between theBorrower
and theLoanBroke.Owner
to create a Loan. Therefore, theLoanSet
transaction must be signed by both parties. The multi-signature flow is as follows:Borrower
creates a new transaction with the pre-agreed terms of the Loan and signs the transaction.Lender
signs over all signing fields, including the signature of theBorrower
.3.2.1.3 Failure Conditions
The
LoanBroker
object associated withLoanBrokerID
does not exist.The
Account
submitting the transaction is not theLoanBroker.Owner
.The
Issuer
account of the Asset is frozen (Global Freeze). No changes can be made to a Loan for a globally frozen asset.Lender. Signature
is invalid.Either of the
tfDefault
,tfImpair
ortfUnimpair
flags are set.The
Borrower
account does not exist.The
Trustline
orMPToken
between the Borrower and the Issuer is frozen.The
Borrower
is not Authorized to hold the Loan asset.PaymentInterval
is less than60
seconds.GracePeriod
is greater than thePaymentInterval
.The Loan Start Date is in the past:
StartDate < CurrentTime
.Insufficient assets in the Vault:
Vault(LoanBroker(LoanBrokerID).VaultID).AssetsAvailable
<Loan.PrincipalRequested
.Exceeds maximum Debt of the LoanBroker:
LoanBroker(LoanBrokerID).DebtMaximum
<LoanBroker(LoanBrokerID).DebtTotal + Loan.PrincipalRequested
Insufficient First-Loss Capital:
LoanBroker(LoanBrokerID).CoverAvailable
<(LoanBroker(LoanBrokerID).DebtTotal + Loan.PrincipalRequested) x LoanBroker(LoanBrokerID).CoverRateMinimum
3.2.1.4 State Changes
If the Loan Asset is an
IOU
:Trustline
between theIssuer
and theBorrower
if one does not exist.If the Loan Asset is an
MPT
:MPToken
object for theBorrower
if one does not exist.Vault(LoanBroker(LoanBrokerID).VaultID)
object state changes:Decrease Assets Available in the Vault:
Vault.AssetsAvailable -= Loan.PrincipalRequested
.Increase the Total Value of the Vault:
Vault.AssetsTotal += LoanInterest - (LoanInterest x LoanBroker.ManagementFeeRate)
whereLoanInterest
is the Loan's total interest.LoanBroker(LoanBrokerID)
object changes:LoanBroker.DebtTotal +=
Loan.PrincipalRequested +
(LoanInterest - (LoanInterest x LoanBroker.ManagementFeeRate)
Increase the number of active Loans:
LoanBroker.OwnerCount += 1
If the
DirectoryNode
for theLoanBroker
does not exist, create one.LoanID
toDirectoryNode.Indexes
.3.2.1.4 Invariants
TBD
3.2.2
LoanDelete
TransactionThe transaction deletes an existing
Loan
object.TransactionType
string
UINT16
LoanID
string
HASH256
N/A
3.2.2.1 Failure Conditions
Loan
object with the specifiedLoanID
does not exist.LoanDelete
is not theLoanBroker.Owner
or theLoan.Borrower
.Loan.PaymentsRemaining > 0
3.2.2.2 State Changes
LoanID
from the Owner Directory associated with theLoanBroker
.LoanBroker.OwnerCount
by1
.Loan
object.3.2.3
LoanManage
TransactionTransactionType
string
UINT16
LoanID
string
HASH256
N/A
Flags
string
UINT32
3.2.3.1
Flags
tfDefault
0x0001
tfImpair
0x0002
tfUnimpair
0x0003
3.2.3.1 Failure Conditions
A
Loan
object with the specifiedLoanID
does not exist.The
Account
submitting the transaction is not theLoanBroker.Owner
.The
lsfDefault
flag is set on the Loan object. Once a Loan is defaulted, it cannot be modified.The Loan has been repaid:
Loan.PaymentsRemaining == 0
.The
tfDefault
flag is specified AND:CurrentTime
<Loan.NextPaymentDueDate + Loan.GracePeriod
.3.2.3.2 State Changes
If the
tfDefault
flag is specified:Calculate the amount of the Default that First-Loss Capital covers:
DefaultAmount = (Loan.PrincipalOutstanding + Loan.InterestOutstanding) - Loan.AssetsAvailable
.DefaultCovered = min((LoanBroker(Loan.LoanBrokerID).DebtTotal x LoanBroker(Loan.LoanBrokerID).CoverRateMinimum) x LoanBroker(Loan.LoanBrokerID).CoverRateLiquidation, DefaultAmount)
DefaultAmount -= DefaultCovered
Update the Vault:
Vault(LoanBroker(LoanBrokerID).VaultID).AssetsTotal -= DefaultAmount
.Vault(LoanBroker(LoanBrokerID).VaultID).AssetsAvailable += DefaultCovered + Loan.AssetsAvailable
.Update the LoanBroker:
LoanBroker(LoanBrokerID).DebtTotal -=
Loan.PrincipalOutstanding + Loan.InterestOutstanding + Loan.AssetsAvailable
LoanBroker(LoanBrokerID).CoverAvailable -= DefaultCovered
.LoanBroker(LoanBrokerID).OwnerCount -= 1
Update the Loan:
Loan(LoanID).Flags = lsfDefault
.Loan(LoanID).PaymentsRemaining = 0
.Loan(LoanID).AssetsAvailable = 0
.3.2.3.3 Invariants
TBD
3.2.4
LoanDraw
TransactionThe Borrower submits a
LoanDraw
transaction to draw funds from the Loan.TransactionType
string
UINT16
LoanID
string
HASH256
N/A
Amount
number
NUMBER
N/A
3.2.4.1 Failure Conditions
StartDate > CurrentTime
.Loan
object with the specifiedLoanID
does not exist.Loan. Borrower
.Loan.AssetsAvailable
<Amount
.Loan
has eitherlsfImpaired
orlsfDefault
flags.Issuer
of the Vault's Asset enacted a Global Freeze or a freeze on theBorrower
account.Borrower
missed a payment: the current ledger time is greater thanLoan.NextPaymentDueDate
.3.2.4.2 State Changes
IF Loan asset is
XRP
:Balance
field of the Vault's_pseudo-account_
AccountRoot
by amount.Balance
field of the Borrower'sAccountRoot
by amount.IF Loan asset is
IOU
:Trustline
between the Vault's_pseudo-account_
and theIssuer
byAmount
.Trustline
between theBorrower
and theIssuer
byAmount
.IF Loan asset is
MPT
:MPToken
of the Vault's_pseudo-account_
byAmount
.MPToken
of theBorrower
byAmount
.Decrease
Loan.AssetsAvailable
byAmount
.3.2.4.3 Invariants
TBD
3.2.5
LoanPay
TransactionThe Borrower submits a
LoanPayment
transaction to make a Payment on the Loan.TransactionType
string
UINT16
LoanID
string
HASH256
N/A
Amount
number
NUMBER
N/A
3.2.5.1 Payment Types
A Loan payment can fall into one of the three categories:
Regular payment is made on time, where the payment size and schedule are calculated with a standard amortization formula.
A late payment, when a Borrower makes a payment after
netxPaymentDueDate
. Late payments include aLatePaymentFee
andLateInterestRate
.An early full payment is when a Borrower pays the outstanding principal. A
ClosingInterestRate
is charged on the outstanding principal.The payment amount and timing determine the type of payment. A payment made before the
Loan.NextPaymentDueDate
is a regular payment and follows the standard amortization calculation. Any payment made after this date is considered a late payment.Each payment comprises three parts,
principal
,interest
andfee
. Theprincipal
is an amount paid against the principal of the Loan,interest
is the interest portion of the Loan, andfee
is the fee part paid by the Borrower on top ofprincipal
andinterest
.Payments below the minimum amount are automatically rejected. The minimum amount is determined by the payment's timeliness. Any funds exceeding the minimum payment are applied to the Loan principal. If the Borrower submits the entire amount, the Loan is paid off. No additional funds are charged.
Late payments take priority over full payments. A Borrower cannot make a full payment when their payment is late. The Borrower must make the late payment and only then make a full payment.
3.2.5.1.1 Regular Payment
A single payment is calculated using the amortization payment formula:
where the periodic interest rate is the interest rate charged per payment period:
The
principal
andinterest
portions can be derived as follows:3.2.5.1.2 Early Full Repayment
A Borrower can close a Loan early by submitting the total amount needed to do so. This amount is the sum of the remaining balance, any accrued interest, a prepayment penalty, and a prepayment fee.
Accrued interest up to the point of early closure is calculated as follows:
Finally, the Lender may charge a prepayment penalty for paying a loan early, which is calculated as follows:
An early payment pays less interest than calculated when increasing the Vault value in the
LoanSet
transaction. Therefore, the Vault value (captured byVault.AssetsTotal
) must be recalculated after an early payment. Assume a functionCurrentValue()
that returnsprincipalOutstanding
andinterestOutstanding
of the Loan. Furthermore, assume a functionFullPayment()
that implements the Full Payment calculation. The function returns the total full payment due split intoprincipal
andinterest
.The value change for an early full repayment is calculated as follows:
Note that
valueChange <= 0
as an early repayment reduces the total value of the Loan.3.2.5.1.3 Late Payment
When a Borrower makes a payment after
NextPaymentDueDate
, they must pay a nominal late payment fee and an additional interest rate charged on the overdue amount for the unpaid period. The formula is as follows:A special, late payment interest rate is applied for the over-due period:
A late payment pays more interest than calculated when increasing the Vault value in the
LoanSet
transaction. Therefore, the total Vault value captured byVault.AssetsTotal
must be recalculated.Assume the function
PeriodicPayment()
returns the expected periodic payment, split intoprincipalPeriodic
andinterestPeriodic
. Furthermore, assume the functionLatePayment()
that implements the Late Payment formula. The function returns the late payment split intoprincipalLate
andinterestLate
, whereinterestLate
is calculated using the formula above. Note thatprincipalPeriodic == principalLate
andinterestLate > interestPeriodic
are used only when the payment is late. Otherwise,interestLate == interestPeriodic
.Note that
valueChange >= 0
.3.2.5.1.4 Management Fee Calculations
The
LoanBroker
Management fee is charged against the interest portion of the Loan and subtracted from the total Loan value at Loan creation. However, the fee is charged only during Loan payments. Early and Late payments change the total value of the Loan by decreasing or increasing the value of total interest. Therefore, when an early or late payment is made, the management fee must be updated.To update the management fee, we need to compute the new total management fee based on the new total interest after executing the early or late payment. Therefore, we need to capture the Loan value before the payment is made and the new value after the payment is made.
For the calculation, assume the following variables:
Assume$f(\mathcal{v})$ is a Loan payment, $f(\mathcal{v}) = \mathcal{v'}$ , the new outstanding loan value is equal to the application of the payment transaction to the current outstanding value. Furthermore, assume $\mathcal{V} \xrightarrow{f(\mathcal{v})} \mathcal{V'}$ , is the change in the Loan total value as the result of applying $f(\mathcal{v})$ .
we say that$\mathcal{V'} = \mathcal{P'} + \mathcal{I'}$ . It's important to note that a payment transaction must never change the total principal. I.e. $\mathcal{P} = \mathcal{P'}$ , the change in total value is caused by the change in total principal only.
The total management fee is calculated as follows:
We compute the management fee paid so far as follows:
Finally, we compute the change in management fee as follows:
The above calculation can be simplified to:
When the management fee change is negative, the Loan's value decreases, and thus, the Loan Broker's debt decreases.
Intuitively, a negative fee change suggests that the fee must be returned, increasing the loan broker's debt.
In contrast, if the management fee change is positive, the Loan's value increases, and a further fee must be deducted from the debt.
Intuitively, a positive fee change suggests that an additional fee must be paid due to the increase in the interest paid.
The LoanBroker debt is then updated as:
3.2.5.2 Failure Conditions
A
Loan
object with specifiedLoanID
does not exist.The Loan has not started yet:
Loan.StartDate > CurrentTime
.The account making a payment is NOT the
Loan.Borrower
.Loan.PaymentsRemaining
orLoan.PrincipalOutstanding
is0
.The
_pseudo-account_
of theVault(LoanBroker(Loan.LoanBrokerID).VaultID)
is frozen.The
Borrower
Trustline
or theMPToken
is frozen.The
Issuer
of the Vault's Asset enacted a global freeze.If the payment is late:
CurrentTime > Loan.NextPaymentDueDate
AND:Amount
<LatePaymentAmount()
If the payment is on time:
CurrentTime <= Loan.NextPaymentDueDate
AND:Amount
<PeriodicPaymentAmount()
3.2.5.3 State Changes
Assume the payment is split into
principal
,interest
andfee
, andtotalDue = principal + interest + fee
.If the loan payment is late, use
CurrentTime > Loan.NextPaymentDueDate
:principal
,interest
andfee
using the Late Payment formula.If the Loan payment is on time:
principal
,interest
andfee
using Periodic Payment formula.If the
Amount
paid is greater or equal to Full Payment Amount:principal
,interest
andfee
using the Full Payment formula.Compute
overflow = Amount - totalDue
.Compute
totalPaid = totalDue
.Loan
object state changes:Loan.PaymentsRemaining
by1
.Loan.PrincipalOutstanding
byprincipal
.overflow
>0
:Loan.PaymentsRemaining > 0
andLoanLoanncipalOutstanding > 0
:LoanLoantPaymentDueDate += Loan.PaymentInterval
.LoanBroker(Loan.LoanBrokerID)
object state changes:Compute the management fee:
feeManagement = interest x LoanBroker.ManagementFeeRate
If there is not enough first-loss capital:
LoanBroker.CoverAvailable < LoanBroker.DebtTotal x LoanBroker.CoverRateMinimum
:LoanBroker.DebtTotal += feeManagement
If there is enough first-loss capital:
LoanBroker.CoverAvailable >= LoanBroker.DebtTotal x LoanBroker.CoverRateMinimum
:Decrement the management fee from totalPaid amount:
totalPaid = totalPaid - feeManagement
Decrement LoanBroker Debt by the amount paid:
LoanBroker.DebtTotal -= totalPaid
Update the LoanBroker Debt by the Loan value change:
LoanBroker.DebtTotal += valueChange
Update the LoanBroker Debt by the change in the management fee:
LoanBroker.DebtTotal -= (valueChange x LoanBroker.ManagementFeeRate)
If the loanLoanpaid off:
LoanLoanmentsRemaining == 0
andLoanLoanncipalOutstanding == 0
:LoanBroker.OwnerCount = LoanBroker.OwnerCount - 1
Vault(LoanBroker(Loan.LoanBrokerID).VaultID)
state changes:Increment available assets in the Vault by the amount paid:
Vault.AssetsAvailable = Vault.AssetsAvailable + totalPaid
Update the Vault total value by the change in the Loan total value:
Vault.AssetsTotal = Vault.AssetsTotal + valueChange
Update the Vault total value by the change in the management fee:
Vault.AssetsTotal = Vault.AssetsTotal - (vaultChange x LoanBroker.managementFeeRate)
If there is not enough first-loss capital:
LoanBroker.CoverAvailable < LoanBroker.DebtTotal x LoanBroker.CoverRateMinimum
:Loan.AssetsTotal = Loan.AssetsTotal + feeManagement
3.2.5.4 Invariants
TBD
Appendix
Beta Was this translation helpful? Give feedback.
All reactions