From 4726ab823db10bcbe71b691a17ca4abbc4b888a3 Mon Sep 17 00:00:00 2001 From: Richard Holland Date: Fri, 25 Mar 2022 13:47:39 +0000 Subject: [PATCH] prevent trustlines being spent below spendable balance --- src/ripple/ledger/impl/View.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ripple/ledger/impl/View.cpp b/src/ripple/ledger/impl/View.cpp index e7b033432..a7dcf4e9c 100644 --- a/src/ripple/ledger/impl/View.cpp +++ b/src/ripple/ledger/impl/View.cpp @@ -247,6 +247,29 @@ accountHolds( // Put balance in account terms. amount.negate(); } + + // If tokens can be escrowed then they can be locked in the trustline + // which means we must never spend them until the escrow is released. + if (view.rules().enabled(featurePaychanAndEscrowForTokens) + && sle->isFieldPresent(sfLockedBalance)) + { + STAmount lockedBalance = sle->getFieldAmount(sfLockedBalance); + STAmount spendableBalance = amount - + (account > issuer ? -lockedBalance : lockedBalance); + + // RH NOTE: this is defensively programmed, it should never fire + // if something bad does happen the trustline acts as a frozen line. + if (spendableBalance < beast::zero || spendableBalance > amount) + { + JLOG(j.error()) + << "SpendableBalance has illegal value in accountHolds " + << spendableBalance; + amount.clear(Issue{currency, issuer}); + } + else + amount = spendableBalance; + } + amount.setIssuer(issuer); } JLOG(j.trace()) << "accountHolds:"