-
Notifications
You must be signed in to change notification settings - Fork 533
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
XLS-0066d Lending Protocol #240
base: master
Are you sure you want to change the base?
Conversation
Before merging, I'd like to have at least one review by an engineer to ensure everything is in order. In addition, similarly to Single Asset Vault, it is simpler/more convenient to edit a PR with various small design changes (e.g. names), rather than open a new PR for each of them. As a result, keeping a PR open allows to have a spec. that is more readily in-alignment with implementation. |
Makes sense, especially if it's more convenient. Just didn't want you (or anyone reading along) to think that merging here implies "finished product" (that's why we have a |
- Adds VaultNode to LoanBroker object to track in which owner directory of the Vaults pseudo-account the LoanBroker object is referenced. - Adds LoanBrokerNode to Loan object to track in which owner directory of the LoanBroker object the Loan is references. - Replaces CurrentTime to LastClosedLedger.CloseTime. - Changes the LoanBroker.Delete transaction to automatically return any outstanding Cover to the LoanBroker.Owner. - Adds a balance check to the LoanBrokerCoverDeposit transaction when depositing XRP. - Adds a check to LoanBrokerCoverWithdraw to ensure the CoverAvailable does not drop below Mimimum Cover Required.
Co-authored-by: Ed Hennis <[email protected]>
… when the last Loan is delete
… for the missing flc
Hmmm, that would make sense, but let me make sure there are no legitimate
use cases we would block.
…On Tue, Jan 28, 2025, 19:18 Ed Hennis ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In XLS-0066d-lending-protocol/README.md
<#240 (comment)>:
> +$$
+valueChange = (prepaymentPenalty) - (interestOutstanding - accruedInterest)
+$$
+
+Note that `valueChange <= 0` as an early repayment reduces the total value of the Loan.
In theory, yes, it is possible to have valueChange > 0.
Remember: prepaymentPenalty = principalOutstanding \times
closeInterestRate
valueChage > 0 suggests that the borrower would pay MORE to close the
Loan early, than repay the loan in scheduled payments.
Yeah, those would be pretty cruddy terms to accept on a loan. So do we
make valueChange <= 0 a hard requirement to stop loan sharking? 😁
—
Reply to this email directly, view it on GitHub
<#240 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABMDKUYNBBEOX2W5APQBDZ32M7J2BAVCNFSM6AAAAABQGMS3AWVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDKNZZGIYDQNJVGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I prefer to measure a year in cups of coffee ☕
…On Tue, Jan 28, 2025, 19:24 Ed Hennis ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In XLS-0066d-lending-protocol/README.md
<#240 (comment)>:
> +$$
+periodicRate = \frac{interestRate \times paymentInterval}{365 \times 24 \times 60 \times 60}
+$$
If we assume that, by monthly payments you mean every 30 days, then 12%
interest rate then the periodic rate would be (12 * 30) / 365 (the hours
and seconds cancel out) or ~= 0.986`
Ok. Perfect. Thanks! I was imaging a theoretical situation where I make 12
payments equally spaced across the year (i.e. every 365/12 = ~30.417 days
or every 24*365/12 = 730 hours. Since the loans are timed in seconds,
those terms are possible, and actually kinda interesting.) ...And now I'm
humming *Seasons of Love*...
—
Reply to this email directly, view it on GitHub
<#240 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABMDKU2W6CZJOD2BQQSNFRL2M7KOLAVCNFSM6AAAAABQGMS3AWVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDKNZZGIYTSMBRGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updates look good.
Co-authored-by: Ed Hennis <[email protected]>
| ----------------- | :----------------: | :-------: | :-----------: | :-----------: | :------------------------------------------------ | | ||
| `TransactionType` | :heavy_check_mark: | `string` | `UINT16` | **TODO** | The transaction type. | | ||
| `LoanBrokerID` | :heavy_check_mark: | `string` | `HASH256` | `N/A` | The Loan Broker ID to deposit First-Loss Capital. | | ||
| `Amount` | :heavy_check_mark: | `object` | `NUMBER` | 0 | The Fist-Loss Capital amount to deposit. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sfAmount
is an AMOUNT
field, which requires currency, issuer, etc. I assume that's not what you want, in which case, we've got sfNumber
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ximinez I'm just getting to reviewing the comments now. Are you suggesting we rename Amount
field to Number
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tapanito Either
- Change the type of
Amount
toAMOUNT
to match the pre-existing defintion. - OR Change the name of
Amount
to an existingNUMBER
field, or a new field that will be created asNUMBER
. It could beNumber
, but it doesn't have to.
| ----------------- | :----------------: | :-------: | :-----------: | :-----------: | :------------------------------------------------------------ | | ||
| `TransactionType` | :heavy_check_mark: | `string` | `UINT16` | **TODO** | Transaction type. | | ||
| `LoanBrokerID` | :heavy_check_mark: | `string` | `HASH256` | `N/A` | The Loan Broker ID from which to withdraw First-Loss Capital. | | ||
| `Amount` | :heavy_check_mark: | `object` | `NUMBER` | 0 | The amount of Vault asset to withdraw. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here: sfAmount
is an AMOUNT
field, which requires currency, issuer, etc. I assume that's not what you want, in which case, we've got sfNumber
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it's worth keeping it as amount, and chaking the type to amount
too? Just in case, in the future, we want to support depositing different cover assets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it's worth keeping it as amount, and chaking the type to
amount
too? Just in case, in the future, we want to support depositing different cover assets?
But doesn't the deposit go into the Single Asset Vault? That can't hold different types of assets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it's worth keeping it as amount, and chaking the type to
amount
too? Just in case, in the future, we want to support depositing different cover assets?But doesn't the deposit go into the Single Asset Vault? That can't hold different types of assets.
But one possible reason to keep this as an Amount
is to ensure that it's the right kind of amount, and that the broker doesn't get their asset types mixed up. In that case, it would fail if its the wrong kind of asset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ximinez , let's keep it as Amount
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ximinez , what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ximinez , what do you think?
Yeah, I'm fine with keeping it Amount
, but the type MUST be changed to AMOUNT
.
No, since we introduced a pseudo-account for the LoanBroker, the deposit
will go there
…On Wed, 19 Mar 2025 at 23:03, Ed Hennis ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In XLS-0066d-lending-protocol/README.md
<#240 (comment)>:
> +
+##### 3.1.3.3 Invariants
+
+**TBD**
+
+[**Return to Index**](#index)
+
+#### 3.1.4 `LoanBrokerCoverWithdraw`
+
+The `LoanBrokerCoverWithdraw` transaction withdraws the First-Loss Capital from the `LoanBroker`.
+
+| Field Name | Required? | JSON Type | Internal Type | Default Value | Description |
+| ----------------- | :----------------: | :-------: | :-----------: | :-----------: | :------------------------------------------------------------ |
+| `TransactionType` | ✔️ | `string` | `UINT16` | **TODO** | Transaction type. |
+| `LoanBrokerID` | ✔️ | `string` | `HASH256` | `N/A` | The Loan Broker ID from which to withdraw First-Loss Capital. |
+| `Amount` | ✔️ | `object` | `NUMBER` | 0 | The amount of Vault asset to withdraw. |
Perhaps it's worth keeping it as amount, and chaking the type to amount
too? Just in case, in the future, we want to support depositing different
cover assets?
But doesn't the deposit go into the Single Asset Vault? That can't hold
different types of assets.
—
Reply to this email directly, view it on GitHub
<#240 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABMDKUZ7CZWQZZUZKUFZQZD2VHSULAVCNFSM6AAAAABQGMS3AWVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDOMBQGM3TONZRGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Sincerely,
Vytautas Tumas
|
Right, I wasn't thinking about that, but if there is a loan default, and funds have to be paid out of the Cover Amount, wouldn't that go to the SAV? |
Yes, 100%, the cover amount liquidation, in essence, will become a transfer of asset from one pseduo-account to another, with some accounting state changes. |
Right, so they should be the same currency, no? I'm fine with it being an |
| `Flags` | | `string` | `UINT32` | 0 | Specifies the flags for the Lending Protocol. | | ||
| `Data` | | `string` | `BLOB` | None | Arbitrary metadata in hex format. The field is limited to 256 bytes. | | ||
| `ManagementFeeRate` | | `number` | `UINT16` | 0 | The 1/10th basis point fee charged by the Lending Protocol Owner. Valid values are between 0 and 10000 inclusive. | | ||
| `DebtMaximum` | | `number` | `NUMBER` | 0 | The maximum amount the protocol can owe the Vault. The default value of 0 means there is no limit to the debt. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| `DebtMaximum` | | `number` | `NUMBER` | 0 | The maximum amount the protocol can owe the Vault. The default value of 0 means there is no limit to the debt. | | |
| `DebtMaximum` | | `number` | `NUMBER` | 0 | The maximum amount the protocol can owe the Vault. The default value of 0 means there is no limit to the debt. Must not be negative. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should this value have a maximum? Maybe maxMPTokenAmount
?
std::uint64_t constexpr maxMPTokenAmount = 0x7FFF'FFFF'FFFF'FFFFull;
Discussion thread can be found here: #190
Development branch can be found here: TBD