rippled
Loading...
Searching...
No Matches
LoanDelete.cpp
1#include <xrpld/app/tx/detail/LoanDelete.h>
2//
3#include <xrpld/app/misc/LendingHelpers.h>
4
5namespace xrpl {
6
7bool
12
15{
16 if (ctx.tx[sfLoanID] == beast::zero)
17 return temINVALID;
18
19 return tesSUCCESS;
20}
21
22TER
24{
25 auto const& tx = ctx.tx;
26
27 auto const account = tx[sfAccount];
28 auto const loanID = tx[sfLoanID];
29
30 auto const loanSle = ctx.view.read(keylet::loan(loanID));
31 if (!loanSle)
32 {
33 JLOG(ctx.j.warn()) << "Loan does not exist.";
34 return tecNO_ENTRY;
35 }
36 if (loanSle->at(sfPaymentRemaining) > 0)
37 {
38 JLOG(ctx.j.warn()) << "Active loan can not be deleted.";
39 return tecHAS_OBLIGATIONS;
40 }
41
42 auto const loanBrokerID = loanSle->at(sfLoanBrokerID);
43 auto const loanBrokerSle = ctx.view.read(keylet::loanbroker(loanBrokerID));
44 if (!loanBrokerSle)
45 {
46 // should be impossible
47 return tecINTERNAL; // LCOV_EXCL_LINE
48 }
49 if (loanBrokerSle->at(sfOwner) != account &&
50 loanSle->at(sfBorrower) != account)
51 {
52 JLOG(ctx.j.warn())
53 << "Account is not Loan Broker Owner or Loan Borrower.";
54 return tecNO_PERMISSION;
55 }
56
57 return tesSUCCESS;
58}
59
60TER
62{
63 auto const& tx = ctx_.tx;
64 auto& view = ctx_.view();
65
66 auto const loanID = tx[sfLoanID];
67 auto const loanSle = view.peek(keylet::loan(loanID));
68 if (!loanSle)
69 return tefBAD_LEDGER; // LCOV_EXCL_LINE
70 auto const borrower = loanSle->at(sfBorrower);
71 auto const borrowerSle = view.peek(keylet::account(borrower));
72 if (!borrowerSle)
73 return tefBAD_LEDGER; // LCOV_EXCL_LINE
74
75 auto const brokerID = loanSle->at(sfLoanBrokerID);
76 auto const brokerSle = view.peek(keylet::loanbroker(brokerID));
77 if (!brokerSle)
78 return tefBAD_LEDGER; // LCOV_EXCL_LINE
79 auto const brokerPseudoAccount = brokerSle->at(sfAccount);
80
81 auto const vaultSle = view.peek(keylet ::vault(brokerSle->at(sfVaultID)));
82 if (!vaultSle)
83 return tefBAD_LEDGER; // LCOV_EXCL_LINE
84
85 // Remove LoanID from Directory of the LoanBroker pseudo-account.
86 if (!view.dirRemove(
87 keylet::ownerDir(brokerPseudoAccount),
88 loanSle->at(sfLoanBrokerNode),
89 loanID,
90 false))
91 return tefBAD_LEDGER; // LCOV_EXCL_LINE
92 // Remove LoanID from Directory of the Borrower.
93 if (!view.dirRemove(
94 keylet::ownerDir(borrower),
95 loanSle->at(sfOwnerNode),
96 loanID,
97 false))
98 return tefBAD_LEDGER; // LCOV_EXCL_LINE
99
100 // Delete the Loan object
101 view.erase(loanSle);
102
103 // Decrement the LoanBroker's owner count.
104 // The broker's owner count is solely for the number of outstanding loans,
105 // and is distinct from the broker's pseudo-account's owner count
106 adjustOwnerCount(view, brokerSle, -1, j_);
107 // If there are no loans left, then any remaining debt must be forgiven,
108 // because there is no other way to pay it back.
109 if (brokerSle->at(sfOwnerCount) == 0)
110 {
111 auto debtTotalProxy = brokerSle->at(sfDebtTotal);
112 if (*debtTotalProxy != beast::zero)
113 {
114 XRPL_ASSERT_PARTS(
116 vaultSle->at(sfAsset),
117 debtTotalProxy,
118 getVaultScale(vaultSle),
119 Number::towards_zero) == beast::zero,
120 "xrpl::LoanDelete::doApply",
121 "last loan, remaining debt rounds to zero");
122 debtTotalProxy = 0;
123 }
124 }
125 // Decrement the borrower's owner count
126 adjustOwnerCount(view, borrowerSle, -1, j_);
127
128 return tesSUCCESS;
129}
130
131//------------------------------------------------------------------------------
132
133} // namespace xrpl
Stream warn() const
Definition Journal.h:321
STTx const & tx
ApplyView & view()
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static TER preclaim(PreclaimContext const &ctx)
static bool checkExtraFeatures(PreflightContext const &ctx)
Definition LoanDelete.cpp:8
static NotTEC preflight(PreflightContext const &ctx)
TER doApply() override
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
beast::Journal const j_
Definition Transactor.h:126
ApplyView & view()
Definition Transactor.h:144
ApplyContext & ctx_
Definition Transactor.h:124
Keylet loanbroker(AccountID const &owner, std::uint32_t seq) noexcept
Definition Indexes.cpp:552
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:356
Keylet loan(uint256 const &loanBrokerID, std::uint32_t loanSeq) noexcept
Definition Indexes.cpp:558
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:166
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
Number roundToAsset(A const &asset, Number const &value, std::int32_t scale, Number::rounding_mode rounding=Number::getround())
Round an arbitrary precision Number to the precision of a given Asset.
Definition STAmount.h:722
@ tefBAD_LEDGER
Definition TER.h:151
bool checkLendingProtocolDependencies(PreflightContext const &ctx)
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1134
int getVaultScale(SLE::const_ref vaultSle)
@ temINVALID
Definition TER.h:91
@ tecNO_ENTRY
Definition TER.h:288
@ tecINTERNAL
Definition TER.h:292
@ tecNO_PERMISSION
Definition TER.h:287
@ tecHAS_OBLIGATIONS
Definition TER.h:299
@ tesSUCCESS
Definition TER.h:226
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
ReadView const & view
Definition Transactor.h:64
beast::Journal const j
Definition Transactor.h:69
State information when preflighting a tx.
Definition Transactor.h:16