0066 XLS - 66d: A XRP Ledger-native Lending Protocol #190
Replies: 6 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.
-
XRP Ledger-native Lending Protocol
Abstract
1. Introduction
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 fixed-term loans, utilizing pooled funds with pre-set terms for interest-accruing loans. The current design bypasses the need for collateral, relying instead on off-chain underwriting, risk management, and a First-Loss Capital protection scheme.
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.
At a glance Liquidity Providers (or lenders) deposit XRP or Fungible Tokens into a Lending Pool to earn interest in the Lending Pool's asset. Loan terms determine the interest earned agreed between the Borrower and the Lending Pool Delegate.
A Pool Delegate may manage one or more Lending Pools. The Pool Delegates' responsibility is to attract capital and provide funding to vetted Borrowers while earning various fees.
A Lending Pool is managed by a single Pool Delegate. The Pool Delegate is responsible for negotiating loan terms with borrowers, performing diligence, and managing the Loan. To evaluate the loan terms, Pool Delegate reviews a Borrower's reputation, expertise, and performance. Once the Borrower and Pool Delegate agree to the interest, Pool Delegate funds the loans from their managed Lending Pool. The current protocol supports multiple-lender-single-borrower Lending Pools for Fixed-Term Loans.
1.1 Modular Protocol Design
The primary objective of these specifications is to introduce an XRP Ledger-native Lending Protocol. The design's guiding principles are flexibility and reusability.
flexibility: A Lending Protocol is a relatively complex system with multiple mechanisms, such as loans, loan collateral, risk management and incentives, asset pooling, fees, etc. Therefore, it must be upgradeable and extensible while maintaining backward compatibility to facilitate iterative design and development.
reusability: A Lending Protocol requires a way to Pool a single asset from one or more Liquidity Providers, track balances between multiple accounts, manage loan states, etc, requiring various new ledger entries. However, instead of specific single-use entries, we introduce general objects that are reusable across multiple future protocols.
This work introduces the following three specifications:
LedgerEntries
field to theAccountRoot
object allowing to associate a single pseudo-account with one or more other ledger entries. A pseudo-account is responsible for tracking various balances and issuing tokens on behalf of associated objects.Pool
ledger entry representing a single tokenized asset pool. The specification introduces a minimal, extendable ledger entry and flexible transactions to interact with the object.1.1.1 Modular Design
The figure below illustrates the modular design of this proposal. From the left, the pseudo-account tracks various balances and issues tokens associated with the
Pool
ledger entry. ThePool
ledger entry defines a minimal interface and transactions to pool liquidity from one or more LPs. The Liquidity Providers' share of thePool
is represented asLPTokens
, issued by the pseudo-account. Finally, multiple protocols can use thePool
ledger entry and the pseudo-account for their needs. In this proposal, we will use it for the Lending Protocol specification.1.1.2 Pseudo-Account
The term pseudo-account identifies an account created as part of some protocol. No user can control, send funds, or sign transactions on behalf of the pseudo-account. ONLY protocols can alter the state of the pseudo-account. When writing this specification, there are three applications for pseudo-accounts: AMM, Single Asset Tokenized Vault, and Lending Protocol.
The figure below outlines the architecture of a pseudo-account. A single account can be associated with multiple objects in the same protocol.
1.2 Terminology
1.2.1 Actors
Pool Delegate: An entity responsible for issuing and managing Loans.
Borrower: An entity seeking to borrow Fungible Tokens from a Lending Pool. Borrowers make loan payments composed of principal and interest, which accumulate in the lending pool.
Liquidity Provider: Entities that deposit a single asset in the Lending Pool in return for pool shares in the form of
LPTokens
. The Lending Pool Delegate can lend the assets to a potential Borrower.1.2.2 Entities
Lending Pool: A construct that locks user-deposited assets in a shared yield-bearing pool. The Lending Pool accrues interest payments made by the borrowers.
Loan: A construct that captures the terms of a Loan on-chain. It also maintains information essential for day-to-day Loan book-keeping. A Borrower and a Pool Delegate create a Loan using a multi-signature transaction.
LPTokens: An asset representing the Liquidity Provider's share of the Lending Pool instance. The Lending Pool [pseudo-account] issues
LPTokens
upon depositing liquidity. TheLPTokens
are destroyed upon liquidity removal.1.2.3 Concepts
Principal: The Loan principal is the initial amount of Fungible Tokens borrowed or lent in a Loan Agreement, excluding any interest or fees that may accrue over time. It represents the core amount of capital that the Lender and Borrower exchanged at the Loan's inception, and it serves as the basis for calculating interest payments and determining the overall repayment obligation.
Interest: Interest is the additional amount of Fungible Tokens charged by a lender for using borrowed funds, expressed as a percentage of the Loan principal. It represents the cost of borrowing and compensates the Liquidity Provider for the risk incurred and the opportunity cost of lending out funds.
Fees: Fees are additional charges incurred by the Borrower beyond the interest rate. The Pool Delegate is the primary receiver of the fees.
1.3 Overview of the Lending Pool features
1.3.1 Lending Pool Representation
A Lending Pool is a specific implementation of the Pool specification.
PoolCreate
,PoolUpdate
andPoolDelete
transactions are used to manage the state of the ledger entry.1.3.2 Liquidity Management
Liquidity Providers may use
Deposit
,Withdraw
, orRedeem
transactions to provision and remove liquidity and any accrued interest from the Pool. They may only withdraw assets from the Pool that are not lent. In this version, we only support a first-come-first-serve withdrawal strategy.1.3.3 Issuing a Loan
_
A new
Loan
ledger entry represents a Loan. The Pool Delegate is responsible for finding borrowers and underwriting Loans. Loan underwriting is an off-chain process between the Borrower and the Lender, potentially facilitated by the Pool Delegate. However, the Loan terms are saved on-chain. A Borrower and Lender can create a newLoan
with a multi-signature transaction,LoanCreate
. The multi-signature transaction ensures that both parties agree on the Loan terms before making the Loan. This version only supports a single Borrower Fixed-Term Loan. However, the design allows for new Loan types.FixedTermLoan
:Fixed-term Loans have a predefined maturity date, such as 180 days, established at the time of creation. These Loans offer certainty for lenders and borrowers, ensuring a clear timeframe for financial planning.
1.3.4 Managing a Loan
Borrower:
LoanPayment
andDrawdown
. TheLoanPayment
transaction is used to make a Loan payment, including any interest, close the Loan early or return borrowed funds. TheDrawdown
transaction is used to withdraw the lent funds.Pool Delegate:
UpdateLoan
orDeleteLoan
transactions. The Update transaction is used only to default to a Loan after a late payment grace period. The Delete transaction is used to Delete the Loan object once the Loan has matured or defaulted.1.3.5 Risk Management
In this version, we propose only using Pool Delegate Cover as a mechanism to manage the risk of a Loan default. The Pool Delegate Cover is a first-loss capital deposited by the Pool Delegate. In case of a Loan default, the Pool Delegate Cover covers some of the lost assets. The Pool Delegate may add and remove deposits with
CoverDeposit
andCoverWithdraw
transactions.1.3.6 Loan Fees
The fees are separated into three categories:
1.3.7 Origination Fee
Origination Fee is paid during Loan funding and refinance operations of a
Fixed-Term
Loan. The Origination Fee is calculated in the following way:delegateOriginationFee
is a term specified during Loan instantiation as a nominal amount.1.3.8 Service Fee
Service fees are paid during Loan payments and added to gross interest. They are calculated in the following way:
delegateServiceFee
is aLoan
term specified as a nominal amount, e.g.,10XRP
. The Borrower and the Pool Delegate agree on the fee.1.3.9 Management Fee
Management fees are paid during Loan payments. The fees are deducted from the gross interest paid by the Borrower using the following formula:
The$grossInterest - managementFee$ goes to the Liquidity Providers.
managementFee
goes to thePoolDelegate
, and the remaining2. A Lending Pool Instance
2.1 On-Ledger Objects
The Lending Pool Protocol implements the Single Asset Tokenized Pool specification. An
AccountRoot
and aPool
object represents aLendingPool
instance. Both objects are created using thePoolCreate
transaction. TheLendingPool
state can be updated using thePoolUpdate
transaction. Finally, an empty Lending Pool can be deleted using thePoolDelete
transaction. A Lending Pool is considered empty when there are no outstanding Loans, assets, orLPTokens
in the underlying Pool object.2.1.1 Lending Pool pseudo-account
In addition to standard the pseudo-account parameters, the Lending Pool
AccountRoot
must have the following set:asfRequireAuth
enabled to ensure that only authorized entities can holdLPTokens
.lsfDefaultRipple
disabled to ensure thatLPToken
holders cannot transferLPTokens
among themselves.2.1.2 LendingPool
LPTokens
The Lending Pool Liquidity Provider Tokens
LPTokens
are a type of PoolLPTokens
. Their balance is tracked via an Authorized Trust Line.Only the Lenders, i.e. accounts that have deposited assets into the Lending Pool, are authorized to hold
LPTokens
.TBD
Some users of the Lending Protocol may want to allow the transfer of
LPTokens
between different users. Perhaps it is wise to make the transferability ofLPTokens
configurable.2.1.3 Lending Pool Access Control
The Pool Delegate can control who may provide liquidity and withdraw funds from the Lending Pool via a Lending Pool's
Permissions
field, which contains `Allowlists of accounts that can provide liquidity or borrow funds from the Lending Pool.2.1.4 LendingPool Accounting
Total Pool Value (
TotalValue
)The
TotalValue
variable represents the total Lending Pool value. The current proposal is for a single-borrower Lending Pool. Therefore, thetotalValue
of a Lending Pool is calculated as follows:where:
The total Loan interest is calculated as follows:
For example, the total interest for a Loan of 1,000,000$ with 15% interest and a 30-day payment interval would be:
At any given time, we can calculate the outstanding interest of a Loan as follows:
Continuing the above example, given that the Borrower made a payment in time on the 30th day, the interest due on the 31st day would be:
The above computation would be costly in a multi-loan system, where a single Lending Pool can have an unbounded number of associated Loans. Therefore, a more efficient solution will be needed for such a system.
2.1.5 Pool Delegate Cover
Pool Delegate Cover is a first-loss capital deposited by the Pool Delegate for a given Lending Pool. First-loss capital protects the Liquidity Providers in case of a Loan default.
Pool Delegate Cover is NOT enforced. For example, a Pool Delegate may create a Lending Pool with zero Pool Delegate Cover. However, a Liquidity Provider (Lender) may be reluctant to deposit assets in an uncovered Lending Pool.
Two variables control the Pool Delegate Cover:
MinCoverPercentage
is the percentage ofTotalValue
that must be covered by the Liquidity Pool Delegate.MaxCoverLiquidationPercentage
is the percentage of the Pool Delegate Cover covering the Pools loss.If the available Pool Cover falls below the
MinCoverPercentage
, two consequences occur:Examples
2.1.6 LendingPool Withdrawal
A Liquidity Provider (Lender) can make a
Withdraw
request anytime. Currently, the Lending Protocol ONLY supports aFirstComeFirstServe
based withdrawal.The requests are served on a first-come-first-serve basis. Multiple withdrawal requests occurring in the same ledger will execute in a non-deterministic order due to the Canonical Transaction Execution Order. In case of insufficient liquidity, only a portion of the
LPTokens
from the withdrawal request will be redeemed.2.1.7 LendingPool fields
The
LendingPool
is a specialized instance of thePool
ledger entry. It adds the following fields to theDetails
field of aPool
:Permissions
STObject
The
Permissions
field contains two members:Lenders
STObject
Borrowers
STObject
A single
STObject
object contains two members:IsPublic
bool
Accounts
MUST BE ignored. The default value is false.Accounts
Vector256
Withdraw
STObject
Note:
Withdraw
is purposefully an object to have the flexibility to introduce new fields configuring withdrawal parameters without affecting the base object.The
Withdraw
object contains the following member:Type
UINT16
LiquidityCap
AMOUNT
LiquidityCap
exists, the default maximum value isFees
STObject
ManagementFeeRate
UINT16
PoolDelegateCover
STObject
The
PoolDelegateCover
configures aspects of the first-loss capital posted by thePoolDelegate
for a given Pool.MinCoverPercentage
UINT16
MaxCoverLiquidationPercentage
UINT16
CoverDeposited
AMOUNT
2.2
CUD
LendingPool
transactionsThe Lending Pool creates an instance of a
Pool
ledger entry. It implements thePool
interface. TheCUD
transactions of thePool
object take additional fields and behaviour.2.2.1
PoolCreate
transactionThe
PoolCreate
transaction creates newPool
and pseudo-account (AccountRoot
) objects.Notes:
PoolCreate
is not allowed withLPTokens.
Fields
Pool
Instance Specific FieldsType
UINT16
Type
specifies the concrete type of the Pool. The value for a Lending Pool is1
.Details
STObject
Details
specifies the protocol-specific values for thePool
.Lending Pool
Specific FieldsPermissions
STObject
This configures the borrowers and lenders who are allowed to interact with the Pool. When the
Permissions
field is NOT specified, the Pool is private. For example,IsPublic
in theLenders
andBorrowers
objects is set tofalse
, and theAccounts
field is empty.The
Permissions
field contains two members:Lenders
STObject
Borrowers
STObject
Each object contains two members:
IsPublic
bool
Accounts
MUST BE ignored. The default value is false.Accounts
Vector256
Withdraw
STObject
The
Withdraw
object contains the following member:Type
UINT16
Currently, only
FirstComeFirstServe
withdrawal is supported. Theuint16
value is1
.LiquidityCap
AMOUNT
LiquidityCap
exists, the default maximum value isFees
STObject
ManagementFeeRate
UINT16
PoolDelegateCover
STObject
MinCoverPercentage
UINT16
MaxCoverLiquidationPercentage
UINT16
Failure Conditions
In addition to the default failure conditions, the
PoolCreate
transaction MUST fail when:Accounts
field for theBorrowers
orLenders
objects.State Changes
If the transaction is successful:
Pool
,AccountRoot
,DirectoryNode
] are created.LPTokens
.PoolDelegateCover
.issuer
of the Pools Fungible Token and the Pool Delegate's account. This trustline is later used to transfer fees to the Pool Delegate.2.2.2
PoolUpdate
transactionFields
In addition to mandatory
Pool
fields, the following information may be provided.Details
struct
BLOB
Modifiable Fields
Permissions
STObject
Configures the borrowers and lenders that are allowed to interact with the Pool. The new
Permissions
value WILL OVERWRITE the existingPermissions
value.If a Liquidity Provider access is removed, they WILL NOT be able to Deposit new assets. However, they WILL be able to Redeem/Withdraw assets from the Lending Pool.
If a Borrower's access is removed, they WILL NOT be able to request a new Loan. However, this DOES NOT affect existing Loans.
LiquidityCap
AMOUNT
LiquidityCap
exists, the default maximum value isConfigures the maximum Liquidity Cap of a Lending Pool.
Details
is a struct with the modifiable Lending Pool fields.Failure Conditions
The transaction MUST fail when:
PoolDelegateID
.State Changes
Details
structure.2.2.3
PoolDelete
transactionFields
The transaction MUST provide mandatory
Pool
fields to identify the instance.Failure Conditions
PoolDelegateID
.LPTokenBalance
of the Pool is NOT zero.Loan
objects are associated with the Lending Pool.PoolDelegateCover
Trust Line is not empty. I.e. the Pool Delegate still needs to withdraw their cover.State Changes
Pool
ledger entry.AccountRoot
object.DirectoryNode
object.2.3 Liquidity Provider Transaction
2.3.1
Deposit
transactionThe Liquidity Providers use the
Deposit
transaction to add liquidity to the Lending Pool in exchange for the Lending PoolLPTokens
.Fields
There are no additional fields.
Failure Conditions
In addition to
Pool
specification failures, the transaction MUST fail when:LiquidityCap
.State Changes
There are no additional state changes.
2.3.2
Withdraw
transactionWithdraw request for a
Lending Pool
is currently disabled.2.3.3
Redeem
transactionTBD
The
Redeem
transaction requires further thought. Please see Appendix A.The
Redeem
transaction burns Liquidity ProvidersLPTokens
in exchange for assets from the Lending Pool. The Liquidity Provider may only redeem the Pool'sAvailableLiquidity
. Any lent assets are not redeemable. The maximum asset amount that a Liquidity Provider can withdraw at a given time is based on the proportion ofLPTokens
the Provider owns. For example, assuming a Liquidity Provider owns 50% of all LPTokens, they may redeem up to 50% of the available liquidity.Redeem Limits
The following formula computes the maximum amount of LPTokens a Liquidity Provider can redeem at the current time:
where:
Example Calculation
Fields
There are no additional fields.
Failure Conditions
TBD
Exact failure conditions depend on the redemption mechanism in place. Once the redemption mechanism is finalized, the exact failure conditions will be described.
State Changes
TBD
Exact state changes depend on the redeem mechanism. Once the logic is finalized, the exact state changes will be described.
2.4 Pool Delegate Cover transactions
2.4.1
CoverDeposit
TransactionA PoolDelegate can submit a
CoverDeposit
transaction to add Pool Delegate Cover into a single Lending Pool Instance.Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is61
.Account
AccountID
Indicates the account that initiated the transaction.
Fee
AMOUNT
Fee
specifies the integer amount of XRP, in drops, to be destroyed as a cost of depositing assets to the Pool.Amount
AMOUNT
Amount
specifies the amount of the pool asset to deposit.Amount
is a String when the Pool asset is XRP. Otherwise, it is anAMOUNT
Object.PoolSequence
number
UINT32
Sequence
number of thePool
instance.PoolDelegateID
AccountID
The
PoolDelegateID
of the Pool.Failure Conditions
The transaction MUST fail when:
PoolDelegateID
.State Changes
AccountRoot
of thePool
, updating theBalance
field of both accounts.Pool
instance account and theissuer
account is adjusted.CoverDeposited
of the Pool.2.4.2
CoverWithdraw
TransactionA Pool Delegate can submit a
CoverWithdraw
transaction to remove the Pool Delegate Cover. However, the cover amount can never be removed below theMinCoverPercentage
threshold.Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is62
.Account
AccountID
Indicates the account that initiated the transaction.
Fee
AMOUNT
Fee
specifies the integer amount of XRP, in drops, to be destroyed as a cost of withdrawing assets from the Pool.Amount
AMOUNT
Amount
specifies the amount of the pool asset to withdraw.Amount
is a String when the pool asset is XRP. Otherwise, it is anAMOUNT
Object.PoolSequence
number
UINT32
Sequence
number of thePool
instance.PoolDelegateID
AccountID
The
PoolDelegateID
of the Pool.Failure Conditions
The transaction MUST fail when:
PoolDelegateID
.CoverDeposited
amount would be less thanState Changes
Pool
instance account to the account initiating the transaction, updating each account'sBalance
field.Pool
instance account and theissuer
account is adjusted.CoverDeposited
of the Pool.3. Loan Instance
The Borrower and the Pool Delegate agree on the Loan terms off-chain and save these terms on-chain. We track a Loan agreement between the Borrower and a lender through a new
Loan
object. A Loan object is used to:Loan
object supports upgradability via theType
field. Currently, onlyFixedTermLoanV1
is supported.The
Loan
object uses theAccountRoot
entry of the associated Lending Pool to track XRP or Fungible Token balances.3.1 Creating a Loan
The Borrower and a Lending Pool Delegate can create a new Loan by submitting a Multi-Signature transaction
LoanCreate
. The transaction contains the Loan terms and the signatures of the Borrower and the Lending Pool Delegate. We chose a multi-signature approach to ensure that no one party could create a Loan object.3.1.1 Loan Creation Pre-Requisites
Permissions.Borrowers
field of the Lending Pool.3.2 Fixed-Term-Loan
A fixed-term Loan has a fixed, agreed-upon due date set at the Loan creation.
3.2.1 Asset Definitions
A Fixed Term Loan manages two assets:
FundsAsset
: This represents XRP or the Fungible Token that is funded, drawn down and paid during the Loan lifecycle.3.2.2 Loan Accounting
The following variables are used to track the amount of a given asset in the Loan:
DrawableFunds
Represents the amount of
FundsAsset
that can be drawn from the Loan by the Borrower.The value is incremented ONLY when:
FundsAsset
. The excess is added to theDrawableFunds
.FundsAsset
. The excess is added to theDrawableFunds
.FundsAsset
back into the Loan to reduce the outstanding principal.The value is decremented ONLY when:
3.3 Default
3.3.1 Overview
A Loan has a defined payment interval, which determines when the Borrower is expected to make payments. If the Borrower does not make a payment before the expected due date, there is a grace period during which they can make a late payment. After the grace period passes, the Loan is considered in default, and the pool delegate can repossess it by defaulting on it.
3.3.2 Fund Recovery
When a Loan defaults, capital is recovered through the mechanics of delegate pool cover. The Pool Delegate does not recover any fees owed during a Loan default.
3.3.3 First-Loss Capital
Each Pool maintains a reserved amount of liquidity whose primary purpose is to serve as first-loss capital in case a Loan defaults. This capital is provided by the Pool Delegate and is used to make up for the losses after a Loan Default. This mechanism is in place to align incentives between the Pool Delegate and Liquidity Providers. The
MaxCoverLiquidationPercentage
is set at the Lending Pool level, which defines the percentage of Pool cover used when covering for losses.First-loss capital is liquidated atomically. The losses owed to the Pool are calculated, and the Pool Delegate cover is liquidated to the
MaxCoverLiquidationPercentage
. The remaining losses are represented to the Liquidity Providers as a decrease inTotalValue
.3.4 On-Ledger Objects
3.4.1 Loan ID
We propose to use a similar technique to generate a
Loan ID
as is used to create anOffer
Object ID:SHA512-Half
of the following values:Loan
space key0x004C
(capital L)AccountID
of the Borrower account.AccountID
of the Pool Delegate account.Sequence
number of theLoanCreate
transaction. If the transaction used a Ticket, use theTicketSequence
value.3.4.2 Loan States
A Loan may be in one of the three states:
Active
: Once a Loan is created, it is considered active. The Borrower may draw down funds and make payments according to the terms of a Loan Agreement.Mature
: Once the Borrower pays the principal and interest, the Loan is considered Mature. It is an end-of-life state, at which point the Loan object can be deleted, given that all assets related to the Loan have been settled.Default
: If the Borrower fails to pay in time, the Pool Delegate may mark the Loan as defaulted. A Pool Delegate can claim all assets of a defaulted Loan.3.4.3 Loan Fields
Type
UINT8
LoanSequence
UINT32
Sequence
number of theLoan
instance. It is used to generate a Loan ID.Borrower
AccountID
Lender
AccountID
PoolID
UINT256
FundsAsset
ISSUE
State
UINT8
Active
,Mature
, andDefault
.Fees
STObject
The
Fees
object is composed of the following fields:DelegateOriginationFee
UINT16
DelegateServiceFee
UINT16
Rates
STObject
The
Rates
object is composed of the following fields:InterestRate
UINT16
ClosingFeeRate
UINT16
LateFeeRate
UINT16
LateInterestRate
UINT16
Details
STObject
The
Details
object is composed of the following fields:GracePeriod
UINT16
PaymentInterval
UINT16
LoanStartDate
UINT32
NextPaymentDueDate
UINT32
LastPaymentDate
UINT32
TotalPayments
UINT16
PaymentsRemaining
UINT16
|
PrincipalRequested
| Yes | Yes | String or Object |AMOUNT
| The nominal amount of principal asset. ||
EndingPrincipal
| Yes | Yes | String or Object |AMOUNT
| The expected principal amount to be paid at the end of the Loan term. ||
DrawableFunds
| Yes | No | String or Object |AMOUNT
| The amount ofFundsAsset
available to the Borrower. |3.5
Loan
CUD
Transactions3.5.1
LoanCreate
transactionThe
LoanCreate
transaction creates a new instance of the Loan object. It is a multi-signature transaction signed by the Borrower and the Pool Delegate.Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is61
.Type
UINT8
Borrower
AccountID
Lender
AccountID
PoolID
UINT256
FundsAsset
ISSUE
Fees
STObject
The
Fees
object is composed of the following fields:DelegateOriginationFee
UINT16
DelegateServiceFee
UINT16
Rates
STObject
The
Rates
object is composed of the following fields:InterestRate
UINT16
ClosingFeeRate
UINT16
LateFeeRate
UINT16
LateInterestRate
UINT16
Details
STObject
The
Details
object is composed of the following fields:PaymentInterval
UINT16
TotalPayments
UINT16
PrincipalRequested
AMOUNT
EndingPrincipal
AMOUNT
Multi-Signature Specific Fields
Signers
STArray
The
Signers
field contains a multi-signature from exactly two key pairs. For further details on the field content, see Signers Field.One of the key pairs MUST belong to the Pool Delegate of the Lending Pool.
The second key:
Permissions.Borrower.IsPublic == True
the key can belong to any other account.Account
of the key must be a member of thePermissions.Borrower.Accounts
array.Failure Conditions
The
LoanCreate
transaction MUST fail when:CoverDeposited
is less thanPoolDelegateID
is NOT one of the signers, OR theBorrower
is NOT one of the signers.Borrower
is not on thePermissions.Borrower.Accounts
list.AvailableLiquidity
is less thanPrincipalRequested
.FundsAsset
does not match the asset of the Lending Pool.Type
is not a supported Loan type.Loan Object Initial Values
The following attributes must have the following initial values:
State
: The initial value isActive
.Details.NextPaymentDueDate
: The initial value is:Details.DrawableFunds
: The initial value is equal toState Changes
If the transaction is successful:
Two new ledger entries [
Loan
,DirectoryNode
] are created.The
LoanID
is added to theLedgerEntries
field of Lending Pool'sAccountRoot
.AvailableLiquidity
of the Lending Pool is decremented byPrincipalRequested
.IF the
fundsAsset
is XRP:Balance
field of the Lending Pool'sAccountRoot
is decremented byDelegateOriginationFee
.Balance
field of the Pool DelegatesAccountRoot
is incremented byDelegateOriginationFee
.IF the
fundsAsset
is a Fungible Token:AccountRoot
and theissuer
account is decremented byDelegateOriginationFee
.AccountRoot
and theissuer
account is incremented byDelegateOriginationFee
.3.5.2
LoanUpdate
transactionThe
LoanUpdate
transaction updates the Loan state. Currently, only defaulting on the Loan is supported.Defaulting a Loan
The Pool Delegate may default a Loan only when:
Details.NextPaymentDueDate + Details.GracePeriod
is greater than theclose_time
of the latest validated ledger.Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is62
.LoanSequence
UINT32
Borrower
AccountID
Account
AccountID
The ID of the account submitting the transaction. It MUST be equal to
Lender
.State
UINT8
Note:
Default
state is supported.Failure Conditions
The transaction MUST fail when:
Details.NextPaymentDueDate + Details.GracePeriod
is less than theclose_time
of the latest validated ledger.Mature
.State Changes
Upon defaulting on the Loan, the following state changes occur:
TBD
3.5.3
LoanDelete
transactionThe
LoanDelete
transaction deletes a Loan that has reached maturity or has defaulted. All balances associated with the Loan must be settled.Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is63
.LoanSequence
UINT32
Borrower
AccountID
Account
AccountID
The ID of the account submitting the transaction MUST be equal to
Lender
.Failure Conditions
The transaction MUST fail when:
State
of the Loan is NOTMature
orDefault
.State Changes
LoanID
entry from theAccountRoot
of the Lending Pool.Loan
ledger entry.DirectoryNode
object.3.5.4
LoanPayment
transactionThe
LoanPayment
transaction is used to make a payment against a Loan. The transaction can take one of the following types:Close
: A payment to close the Loan early.ReturnFunds
: A payment to returnfundsAsset
to the Loan.Payment
: A standard Loan repayment.The transaction type is controlled via the
Flags
transaction parameter.tfClose
tfReturnFunds
tfPayment
Payments
A Borrower can make a Payment on their Loand by sending a
LoanPayment
transaction with typePayment
.Amortization
On Loan instantiation, the following Loan attributes are set. These attributes affect the payment calculation of a Loan:
PrincipalRequested
: Total principal amount owed on the Loan.EndingPrinciple
: Principal balance remaining at the end of the Loan. This amount is zero if the Loan is fully amortized. The Loan is interest-only if this amount equalsPrincipalRequested
and partially amortized if it is anything in between.InterestRate
: The annualized interest rate used throughout the Loan.PaymentInterval
: Time between payments in seconds.PaymentsRemaining
: Total number of payments made throughout the Loan.The payment schedule is calculated with a standard amortization formula.
Late Payments
When a Borrower makes a payment after the
nextPaymentDueDate
timestamp, it is considered late. There are tworate
attributes used to calculate late fees:LateInterestPremiumRate
: Additional Premium charged for late payments. For example, if the premium is 5% and the interest rate is 10%, the Borrower must pay 15% interest.LateFeeRate
: Fee charged as a percentage of the outstanding principal at the time of payment.A total late payment is calculated as follows:
where
defaultInterest
is:where
secondsInDay
is the number of seconds in 24 hours. I.e. 86400.Closing a Loan
A Borrower can close a Loan early by sending a
LoanPayment
transaction with the typeClose
. Allowing the Borrower to pay back the whole principal and interest in a single transaction. There is onerate
attribute used to calculate the total amount due:ClosingRate
: Fee charged as a percentage of the outstanding principal at the time of payment.The total due is calculated as follows:
Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is64
.LoanSequence
UINT32
Lender
AccountID
Account
AccountID
The ID of the account submitting the transaction MUST equal the
Borrower
field of the Loan.Amount
STAmount
Failure Conditions
The transaction MUST fail when:
Loan
state isMature
orDefault
.Amount
field.Close
paymentPayment
paymentReturnFunds
paymentState Changes
IF the
fundsAsset
is XRP:Balance
field of all affectedAccountRoot
objects. In other words, transfer the funds from the Borrower to the pseudo-account of the Lending Pool.IF the
fundsAsset
is a Fungible Token:AccountRoot
objects. In other words, transfer the funds from the Borrower to the pseudo-account of the Lending Pool.Close
transaction typeLoan
state changesPaymentsRemaining
to zero.NextPaymentDueDate
toLoanStartDate + PaymentInterval * TotalPayments
.LastPaymentDate
to the current timestamp.State
toMature
.LendingPool
state changesAvailableLiquidity
of the Lending Pool.Payment
transaction typeThe Payment
Amount
comprisesprincipal + interest
, the total is calculated using the amortization function.Decrement the
PaymentsRemaining
field.Update
NextPaymentDueDate
toNextPaymentDueDate + PaymentInterval
.Update
LastPaymentDate
to the current timestamp.IF
PaymentsRemaining
is zero:State
toMature
.LendingPool
state changesAvailableLiquidity
of the Lending Pool.Fee management for
Payment
andClose
transactionsService Fees:
DrawableFunds
of the Loan.TBD
Management Fees:
TBD
ReturnFunds
transaction typeIF the
fundsAsset
is XRP:Balance
field of the Lending Pool'sAccountRoot
is incremented byAmount
.Balance
field of the Borrower'sAccountRoot
is decremented byAmount
.IF the
fundsAsset
is a Fungible Token:AccountRoot
and theissuer
account is incremented byAmount
.AccountRoot
and theissuer
account is decremented byAmount
.DrawableFunds
of the Loan Object is incremented byAmount
.3.5.6
Drawdown
transactionThe
Drawdown
transaction withdraws the principal lent to the Borrower.Fields
TransactionType
UINT16
TransactionType
specifies the new transaction type. The integer value is65
.LoanSequence
UINT32
Lender
AccountID
Account
AccountID
The ID of the account submitting the transaction MUST equal the
Borrower
field of the Loan.Amount
STAmount
The
Amount
of funds to drawdown from the Loan.Failure Conditions
The transaction MUST fail when:
Amount
is greater than theDrawableFunds
of the Loan.Loan
State isDefault
.State Changes
IF the
fundsAsset
is XRP:Balance
field of the pseudo-account of the Lending Pool is decremented byAmount
.Balance
field of the BorrowersAccountRoot
is incremented byAmount
.IF the
fundsAsset
is a Fungible Token:issuer
account is decremented byAmount
.AccountRoot
and theissuer
account is incremented byAmount
.Decrement
DrawableFunds
of the Loan object byAmount
.Appendix A - Outstanding decision points
A-1 Redeeming
LPTokens
The strategy to redeem
LPTokens
must balance implementation complexity and usability. TheFirst-Come-First-Serve
approach is NOT fair. It provides Liquidity Providers with inside knowledge an advantage. For example, a Liquidity Provider with advanced knowledge of an impending Default to minimize losses may try to quickly redeem as manyLPTokens
before a Loan default.Therefore, we propose additional ideas on how redeeming could be done.
A-1.1 End-of-life redeeming
Once a Loan is created, Liquidity Providers may not add or remove funds from the Lending Pool, effectively freezing the Pool until the Loan reaches end-of-life. Once the Loan finishes, Liquidity Providers may withdraw lent funds plus any accrued interest.
Pros:
Cons:
A-1.2 Queue-based redeeming
Liquidity Providers submit
Redeem
requests to a Lending Pool, where these requests are Queued. Periodically, at fixed intervals, eachRedeem
request is processed. A Liquidity Provider may have zero or one pendingRedeem
request at any time. In addition, to prevent greedy Liqudity Providers, at any given time, a Liqudity Provider may withdraw NO MORE than their portion of the accumulated funds. For example, if a Liquidity Provider provides 50% of total liquidity, they can redeem only up to 50% of funds at any stage.Pros:
Cons:
LoanPayment
.A-1.3 Immediate payout
Instead of accumulating yield and principal in the Lending Pool, the funds are distributed at the time of payment. The Loan object maintains the portion of funds each Liquidity Provider contributed. For example, if Alice and Bob deposited 10,000 and 90,000 into the Lending Pool, And the Loan is for 10,000, then the Loan object will maintain a constant value stating that Alice owns 10% of any funds from this Loan and Bob owns 90% of any funds from this Loan. Thus, every time the Borrower makes a payment, 10% goes to Alice and 90% to Bob.
Pros:
Cons:
A-2 Liquidity Provider Voting
Currently, only a Pool Delegate may default a Loan. However, in doing so, they would lose the Pool Delegate Cover. Therefore, there is no on-chain intrinsic incentive for a Pool Delegate to default a Loan. There might be off-chain incentives about which we cannot make any assumptions.
To address this issue, Liquidity Providers may vote to Default a Loan (once Default conditions are met). The weight of each vote is proportional to the
LPTokens
the Liquidity Provider holds.Beta Was this translation helpful? Give feedback.
All reactions