mirror of
https://github.com/XRPLF/rippled.git
synced 2026-01-28 18:45:35 +00:00
Compare commits
1 Commits
develop
...
tapanito/l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9448d82fd1 |
@@ -514,7 +514,6 @@ LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
|
||||
{sfDebtMaximum, soeDEFAULT},
|
||||
{sfCoverAvailable, soeDEFAULT},
|
||||
{sfCoverRateMinimum, soeDEFAULT},
|
||||
{sfCoverRateLiquidation, soeDEFAULT},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a loan between a Borrower and a Loan Broker
|
||||
|
||||
@@ -108,7 +108,6 @@ TYPED_SFIELD(sfPaymentRemaining, UINT32, 59)
|
||||
TYPED_SFIELD(sfPaymentTotal, UINT32, 60)
|
||||
TYPED_SFIELD(sfLoanSequence, UINT32, 61)
|
||||
TYPED_SFIELD(sfCoverRateMinimum, UINT32, 62) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfCoverRateLiquidation, UINT32, 63) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfOverpaymentFee, UINT32, 64) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfInterestRate, UINT32, 65) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfLateInterestRate, UINT32, 66) // 1/10 basis points (bips)
|
||||
|
||||
@@ -941,7 +941,6 @@ TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
|
||||
{sfManagementFeeRate, soeOPTIONAL},
|
||||
{sfDebtMaximum, soeOPTIONAL},
|
||||
{sfCoverRateMinimum, soeOPTIONAL},
|
||||
{sfCoverRateLiquidation, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction deletes a Loan Broker */
|
||||
|
||||
@@ -2738,8 +2738,7 @@ class Batch_test : public beast::unit_test::suite
|
||||
env(set(lender, vaultKeylet.key),
|
||||
managementFeeRate(TenthBips16(100)),
|
||||
debtMaximum(debtMaximumValue),
|
||||
coverRateMinimum(TenthBips32(percentageToTenthBips(10))),
|
||||
coverRateLiquidation(TenthBips32(percentageToTenthBips(25))));
|
||||
coverRateMinimum(TenthBips32(percentageToTenthBips(10))));
|
||||
|
||||
env(coverDeposit(lender, brokerKeylet.key, coverDepositValue));
|
||||
|
||||
|
||||
@@ -1850,9 +1850,6 @@ class Invariants_test : public beast::unit_test::suite
|
||||
sle->at(sfManagementFeeRate) += 1;
|
||||
},
|
||||
[](SLE::pointer& sle) { sle->at(sfCoverRateMinimum) += 1; },
|
||||
[](SLE::pointer& sle) {
|
||||
sle->at(sfCoverRateLiquidation) += 1;
|
||||
},
|
||||
[](SLE::pointer& sle) { sle->at(sfLedgerEntryType) += 1; },
|
||||
[](SLE::pointer& sle) {
|
||||
sle->at(sfLedgerIndex) = sle->at(sfVaultID).value();
|
||||
|
||||
@@ -667,39 +667,13 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
env(set(evan, vault.vaultID),
|
||||
managementFeeRate(maxManagementFeeRate + TenthBips16(10)),
|
||||
ter(temINVALID));
|
||||
// sfCoverRateMinimum and sfCoverRateLiquidation are linked
|
||||
// Cover: good value, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate),
|
||||
coverRateLiquidation(maxCoverRate),
|
||||
ter(tecNO_PERMISSION));
|
||||
// CoverMinimum: too big
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate + 1),
|
||||
coverRateLiquidation(maxCoverRate + 1),
|
||||
ter(temINVALID));
|
||||
// CoverLiquidation: too big
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate / 2),
|
||||
coverRateLiquidation(maxCoverRate + 1),
|
||||
ter(temINVALID));
|
||||
// Cover: zero min, non-zero liquidation - implicit and
|
||||
// explicit zero values.
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateLiquidation(maxCoverRate),
|
||||
ter(temINVALID));
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(tenthBipsZero),
|
||||
coverRateLiquidation(maxCoverRate),
|
||||
ter(temINVALID));
|
||||
// Cover: non-zero min, zero liquidation - implicit and
|
||||
// explicit zero values.
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate),
|
||||
ter(temINVALID));
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate),
|
||||
coverRateLiquidation(tenthBipsZero),
|
||||
ter(temINVALID));
|
||||
// sfDebtMaximum: good value, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
@@ -730,13 +704,10 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
// Extra checks
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfManagementFeeRate));
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfCoverRateMinimum));
|
||||
BEAST_EXPECT(
|
||||
!broker->isFieldPresent(sfCoverRateLiquidation));
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfData));
|
||||
BEAST_EXPECT(!broker->isFieldPresent(sfDebtMaximum));
|
||||
BEAST_EXPECT(broker->at(sfDebtMaximum) == 0);
|
||||
BEAST_EXPECT(broker->at(sfCoverRateMinimum) == 0);
|
||||
BEAST_EXPECT(broker->at(sfCoverRateLiquidation) == 0);
|
||||
|
||||
BEAST_EXPECT(
|
||||
env.ownerCount(alice) == aliceOriginalCount + 4);
|
||||
@@ -776,12 +747,6 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
coverRateMinimum(maxManagementFeeRate),
|
||||
ter(temINVALID),
|
||||
THISLINE);
|
||||
// CoverRateLiquidation
|
||||
env(set(alice, vault.vaultID),
|
||||
loanBrokerID(broker->key()),
|
||||
coverRateLiquidation(maxManagementFeeRate),
|
||||
ter(temINVALID),
|
||||
THISLINE);
|
||||
|
||||
// fields that can be changed
|
||||
testData = "Test Data 1234";
|
||||
@@ -846,14 +811,12 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
data(testData),
|
||||
managementFeeRate(TenthBips16(123)),
|
||||
debtMaximum(Number(9)),
|
||||
coverRateMinimum(TenthBips32(100)),
|
||||
coverRateLiquidation(TenthBips32(200)));
|
||||
coverRateMinimum(TenthBips32(100)));
|
||||
},
|
||||
[&](SLE::const_ref broker) {
|
||||
// Extra checks
|
||||
BEAST_EXPECT(broker->at(sfManagementFeeRate) == 123);
|
||||
BEAST_EXPECT(broker->at(sfCoverRateMinimum) == 100);
|
||||
BEAST_EXPECT(broker->at(sfCoverRateLiquidation) == 200);
|
||||
BEAST_EXPECT(broker->at(sfDebtMaximum) == Number(9));
|
||||
BEAST_EXPECT(checkVL(broker->at(sfData), testData));
|
||||
},
|
||||
|
||||
@@ -83,7 +83,6 @@ protected:
|
||||
TenthBips32 coverRateMin = percentageToTenthBips(10);
|
||||
int coverDeposit = 1000;
|
||||
TenthBips16 managementFeeRate{100};
|
||||
TenthBips32 coverRateLiquidation = percentageToTenthBips(25);
|
||||
std::string data{};
|
||||
std::uint32_t flags = 0;
|
||||
|
||||
@@ -490,8 +489,7 @@ protected:
|
||||
data(params.data),
|
||||
managementFeeRate(params.managementFeeRate),
|
||||
debtMaximum(debtMaximumValue),
|
||||
coverRateMinimum(coverRateMinValue),
|
||||
coverRateLiquidation(TenthBips32(params.coverRateLiquidation)));
|
||||
coverRateMinimum(coverRateMinValue));
|
||||
|
||||
if (coverDepositValue != beast::zero)
|
||||
env(coverDeposit(lender, keylet.key, coverDepositValue));
|
||||
@@ -2119,10 +2117,8 @@ protected:
|
||||
broker.asset,
|
||||
std::min(
|
||||
tenthBipsOfValue(
|
||||
tenthBipsOfValue(
|
||||
brokerSle->at(sfDebtTotal),
|
||||
broker.params.coverRateMin),
|
||||
broker.params.coverRateLiquidation),
|
||||
brokerSle->at(sfDebtTotal),
|
||||
broker.params.coverRateMin),
|
||||
state.totalValue - state.managementFeeOutstanding),
|
||||
state.loanScale);
|
||||
return std::make_pair(defaultAmount, brokerSle->at(sfOwner));
|
||||
@@ -6396,8 +6392,7 @@ protected:
|
||||
BrokerParameters brokerParams{
|
||||
.vaultDeposit = 10000,
|
||||
.debtMax = Number{0},
|
||||
.coverRateMin = TenthBips32{1000},
|
||||
.coverRateLiquidation = TenthBips32{2500}};
|
||||
.coverRateMin = TenthBips32{1000}};
|
||||
|
||||
auto broker = createVaultAndBroker(env, asset, lender, brokerParams);
|
||||
|
||||
@@ -6529,9 +6524,7 @@ protected:
|
||||
BrokerParameters const brokerParams{
|
||||
.vaultDeposit = 100000,
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32{0},
|
||||
// .managementFeeRate = TenthBips16{5919},
|
||||
.coverRateLiquidation = TenthBips32{0}};
|
||||
.coverRateMin = TenthBips32{0}};
|
||||
LoanParameters const loanParams{
|
||||
.account = lender,
|
||||
.counter = borrower,
|
||||
@@ -6560,8 +6553,10 @@ protected:
|
||||
auto state = getCurrentState(env, broker, loanKeylet);
|
||||
if (auto loan = env.le(loanKeylet); BEAST_EXPECT(loan))
|
||||
{
|
||||
env.close(tp{d{
|
||||
loan->at(sfNextPaymentDueDate) + loan->at(sfGracePeriod) + 1}});
|
||||
env.close(
|
||||
tp{
|
||||
d{loan->at(sfNextPaymentDueDate) + loan->at(sfGracePeriod) +
|
||||
1}});
|
||||
}
|
||||
|
||||
topUpBorrower(
|
||||
@@ -6606,8 +6601,7 @@ protected:
|
||||
.vaultDeposit = 200'000,
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32{0},
|
||||
.managementFeeRate = TenthBips16{500},
|
||||
.coverRateLiquidation = TenthBips32{0}};
|
||||
.managementFeeRate = TenthBips16{500}};
|
||||
LoanParameters const loanParams{
|
||||
.account = lender,
|
||||
.counter = borrower,
|
||||
@@ -6827,8 +6821,7 @@ protected:
|
||||
.vaultDeposit = 10,
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32{0},
|
||||
.managementFeeRate = TenthBips16{0},
|
||||
.coverRateLiquidation = TenthBips32{0}};
|
||||
.managementFeeRate = TenthBips16{0}};
|
||||
LoanParameters const loanParams{
|
||||
.account = lender,
|
||||
.counter = borrower,
|
||||
@@ -7005,8 +6998,7 @@ protected:
|
||||
.vaultDeposit = 100'000,
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32{0},
|
||||
.managementFeeRate = TenthBips16{0},
|
||||
.coverRateLiquidation = TenthBips32{0}};
|
||||
.managementFeeRate = TenthBips16{0}};
|
||||
LoanParameters const loanParams{
|
||||
.account = lender,
|
||||
.counter = issuer,
|
||||
@@ -7055,8 +7047,7 @@ protected:
|
||||
.vaultDeposit = 100'000,
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32{0},
|
||||
.managementFeeRate = TenthBips16{0},
|
||||
.coverRateLiquidation = TenthBips32{0}};
|
||||
.managementFeeRate = TenthBips16{0}};
|
||||
LoanParameters const loanParams{
|
||||
.account = lender,
|
||||
.counter = borrower,
|
||||
@@ -7554,8 +7545,7 @@ protected:
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32(20000), // 20%
|
||||
.coverDeposit = 21'000,
|
||||
.managementFeeRate = TenthBips16(100), // 0.1%
|
||||
.coverRateLiquidation = TenthBips32(100000),
|
||||
.managementFeeRate = TenthBips16(100),
|
||||
});
|
||||
auto const brokerKeylet = brokerInfo.brokerKeylet();
|
||||
|
||||
@@ -7813,8 +7803,7 @@ class LoanArbitrary_test : public LoanBatch_test
|
||||
.vaultDeposit = 10000,
|
||||
.debtMax = 0,
|
||||
.coverRateMin = TenthBips32{0},
|
||||
.managementFeeRate = TenthBips16{0},
|
||||
.coverRateLiquidation = TenthBips32{0}};
|
||||
.managementFeeRate = TenthBips16{0}};
|
||||
LoanParameters const loanParams{
|
||||
.account = Account("lender"),
|
||||
.counter = Account("borrower"),
|
||||
|
||||
@@ -755,9 +755,6 @@ auto const debtMaximum = simpleField<SF_NUMBER>(sfDebtMaximum);
|
||||
auto const coverRateMinimum =
|
||||
valueUnitWrapper<SF_UINT32, unit::TenthBipsTag>(sfCoverRateMinimum);
|
||||
|
||||
auto const coverRateLiquidation =
|
||||
valueUnitWrapper<SF_UINT32, unit::TenthBipsTag>(sfCoverRateLiquidation);
|
||||
|
||||
auto const destination = JTxFieldWrapper<accountIDField>(sfDestination);
|
||||
|
||||
} // namespace loanBroker
|
||||
|
||||
@@ -2270,8 +2270,7 @@ NoModifiedUnmodifiableFields::finalize(
|
||||
fieldChanged(before, after, sfAccount) ||
|
||||
fieldChanged(before, after, sfOwner) ||
|
||||
fieldChanged(before, after, sfManagementFeeRate) ||
|
||||
fieldChanged(before, after, sfCoverRateMinimum) ||
|
||||
fieldChanged(before, after, sfCoverRateLiquidation);
|
||||
fieldChanged(before, after, sfCoverRateMinimum);
|
||||
break;
|
||||
case ltLOAN:
|
||||
/*
|
||||
@@ -2707,8 +2706,9 @@ ValidVault::visitEntry(
|
||||
// At this moment we have no way of telling if this object holds
|
||||
// vault shares or something else. Save it for finalize.
|
||||
afterMPTs_.push_back(Shares::make(*after));
|
||||
balanceDelta -= Number(static_cast<std::int64_t>(
|
||||
after->getFieldU64(sfOutstandingAmount)));
|
||||
balanceDelta -= Number(
|
||||
static_cast<std::int64_t>(
|
||||
after->getFieldU64(sfOutstandingAmount)));
|
||||
sign = 1;
|
||||
break;
|
||||
case ltMPTOKEN:
|
||||
|
||||
@@ -25,8 +25,6 @@ LoanBrokerSet::preflight(PreflightContext const& ctx)
|
||||
return temINVALID;
|
||||
if (!validNumericRange(tx[~sfCoverRateMinimum], maxCoverRate))
|
||||
return temINVALID;
|
||||
if (!validNumericRange(tx[~sfCoverRateLiquidation], maxCoverRate))
|
||||
return temINVALID;
|
||||
if (!validNumericRange(
|
||||
tx[~sfDebtMaximum], Number(maxMPTokenAmount), Number(0)))
|
||||
return temINVALID;
|
||||
@@ -36,8 +34,7 @@ LoanBrokerSet::preflight(PreflightContext const& ctx)
|
||||
// Fixed fields can not be specified if we're modifying an existing
|
||||
// LoanBroker Object
|
||||
if (tx.isFieldPresent(sfManagementFeeRate) ||
|
||||
tx.isFieldPresent(sfCoverRateMinimum) ||
|
||||
tx.isFieldPresent(sfCoverRateLiquidation))
|
||||
tx.isFieldPresent(sfCoverRateMinimum))
|
||||
return temINVALID;
|
||||
|
||||
if (tx[sfLoanBrokerID] == beast::zero)
|
||||
@@ -50,17 +47,6 @@ LoanBrokerSet::preflight(PreflightContext const& ctx)
|
||||
return temINVALID;
|
||||
}
|
||||
|
||||
{
|
||||
auto const minimumZero = tx[~sfCoverRateMinimum].value_or(0) == 0;
|
||||
auto const liquidationZero =
|
||||
tx[~sfCoverRateLiquidation].value_or(0) == 0;
|
||||
// Both must be zero or non-zero.
|
||||
if (minimumZero != liquidationZero)
|
||||
{
|
||||
return temINVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -260,8 +246,6 @@ LoanBrokerSet::doApply()
|
||||
broker->at(sfDebtMaximum) = *debtMax;
|
||||
if (auto const coverMin = tx[~sfCoverRateMinimum])
|
||||
broker->at(sfCoverRateMinimum) = *coverMin;
|
||||
if (auto const coverLiq = tx[~sfCoverRateLiquidation])
|
||||
broker->at(sfCoverRateLiquidation) = *coverLiq;
|
||||
|
||||
view.insert(broker);
|
||||
|
||||
|
||||
@@ -151,8 +151,6 @@ LoanManage::defaultLoan(
|
||||
|
||||
// Apply the First-Loss Capital to the Default Amount
|
||||
TenthBips32 const coverRateMinimum{brokerSle->at(sfCoverRateMinimum)};
|
||||
TenthBips32 const coverRateLiquidation{
|
||||
brokerSle->at(sfCoverRateLiquidation)};
|
||||
auto const defaultCovered = [&]() {
|
||||
// Always round the minimum required up.
|
||||
NumberRoundModeGuard mg(Number::upward);
|
||||
@@ -166,9 +164,7 @@ LoanManage::defaultLoan(
|
||||
* Changes), specifically "if the `tfLoanDefault` flag is set" /
|
||||
* "Apply the First-Loss Capital to the Default Amount"
|
||||
*/
|
||||
std::min(
|
||||
tenthBipsOfValue(minimumCover, coverRateLiquidation),
|
||||
totalDefaultAmount),
|
||||
std::min(minimumCover, totalDefaultAmount),
|
||||
loanScale);
|
||||
auto const coverAvailable = *brokerSle->at(sfCoverAvailable);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user