mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 11:35:53 +00:00
LoanBrokerSet will charge a reserve increment when creating
- Refactor: Add a Transactor base function to make it easier to get the owner reserve increment as a fee. - Refactor: Add an overload jtx::fee(increment) to pay an owner reserve.
This commit is contained in:
@@ -72,7 +72,7 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
|
||||
using namespace loanBroker;
|
||||
// Can't create a loan broker regardless of whether the vault exists
|
||||
env(set(alice, keylet.key), ter(temDISABLED));
|
||||
env(set(alice, keylet.key), fee(increment), ter(temDISABLED));
|
||||
};
|
||||
failAll(all - featureMPTokensV1);
|
||||
failAll(all - featureSingleAssetVault - featureLendingProtocol);
|
||||
@@ -153,62 +153,80 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
{
|
||||
auto badKeylet = keylet::vault(alice.id(), env.seq(alice));
|
||||
// Try some failure cases
|
||||
// insufficient fee
|
||||
env(set(evan, vault.vaultID), ter(telINSUF_FEE_P));
|
||||
// not the vault owner
|
||||
env(set(evan, vault.vaultID), ter(tecNO_PERMISSION));
|
||||
env(set(evan, vault.vaultID),
|
||||
fee(increment),
|
||||
ter(tecNO_PERMISSION));
|
||||
// not a vault
|
||||
env(set(alice, badKeylet.key), ter(tecNO_ENTRY));
|
||||
env(set(alice, badKeylet.key),
|
||||
fee(increment),
|
||||
ter(tecNO_ENTRY));
|
||||
// flags are checked first
|
||||
env(set(evan, vault.vaultID, ~tfUniversal),
|
||||
fee(increment),
|
||||
ter(temINVALID_FLAG));
|
||||
// field length validation
|
||||
// sfData: good length, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
fee(increment),
|
||||
data(std::string(maxDataPayloadLength, 'X')),
|
||||
ter(tecNO_PERMISSION));
|
||||
// sfData: too long
|
||||
env(set(evan, vault.vaultID),
|
||||
fee(increment),
|
||||
data(std::string(maxDataPayloadLength + 1, 'Y')),
|
||||
ter(temINVALID));
|
||||
// sfManagementFeeRate: good value, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
managementFeeRate(maxFeeRate),
|
||||
fee(increment),
|
||||
ter(tecNO_PERMISSION));
|
||||
// sfManagementFeeRate: too big
|
||||
env(set(evan, vault.vaultID),
|
||||
managementFeeRate(maxFeeRate + 1),
|
||||
fee(increment),
|
||||
ter(temINVALID));
|
||||
// sfCoverRateMinimum: good value, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate),
|
||||
fee(increment),
|
||||
ter(tecNO_PERMISSION));
|
||||
// sfCoverRateMinimum: too big
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateMinimum(maxCoverRate + 1),
|
||||
fee(increment),
|
||||
ter(temINVALID));
|
||||
// sfCoverRateLiquidation: good value, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateLiquidation(maxCoverRate),
|
||||
fee(increment),
|
||||
ter(tecNO_PERMISSION));
|
||||
// sfCoverRateLiquidation: too big
|
||||
env(set(evan, vault.vaultID),
|
||||
coverRateLiquidation(maxCoverRate + 1),
|
||||
fee(increment),
|
||||
ter(temINVALID));
|
||||
// sfDebtMaximum: good value, bad account
|
||||
env(set(evan, vault.vaultID),
|
||||
debtMaximum(Number(0)),
|
||||
fee(increment),
|
||||
ter(tecNO_PERMISSION));
|
||||
// sfDebtMaximum: overflow
|
||||
env(set(evan, vault.vaultID),
|
||||
debtMaximum(Number(1, 100)),
|
||||
fee(increment),
|
||||
ter(temINVALID));
|
||||
// sfDebtMaximum: negative
|
||||
env(set(evan, vault.vaultID),
|
||||
debtMaximum(Number(-1)),
|
||||
fee(increment),
|
||||
ter(temINVALID));
|
||||
|
||||
auto keylet = keylet::loanbroker(alice.id(), env.seq(alice));
|
||||
// Successfully create a Loan Broker with all default values.
|
||||
env(set(alice, vault.vaultID));
|
||||
env(set(alice, vault.vaultID), fee(increment));
|
||||
env.close();
|
||||
if (auto broker = env.le(keylet); BEAST_EXPECT(broker))
|
||||
{
|
||||
@@ -339,7 +357,8 @@ class LoanBroker_test : public beast::unit_test::suite
|
||||
managementFeeRate(123),
|
||||
debtMaximum(Number(9)),
|
||||
coverRateMinimum(100),
|
||||
coverRateLiquidation(200));
|
||||
coverRateLiquidation(200),
|
||||
fee(increment));
|
||||
env.close();
|
||||
if (auto broker = env.le(keylet2); BEAST_EXPECT(broker))
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ class fee
|
||||
{
|
||||
private:
|
||||
bool manual_ = true;
|
||||
bool increment_ = false;
|
||||
std::optional<STAmount> amount_;
|
||||
|
||||
public:
|
||||
@@ -44,6 +45,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
explicit fee(increment_t) : increment_(true)
|
||||
{
|
||||
}
|
||||
|
||||
explicit fee(none_t)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -26,13 +26,15 @@ namespace test {
|
||||
namespace jtx {
|
||||
|
||||
void
|
||||
fee::operator()(Env&, JTx& jt) const
|
||||
fee::operator()(Env& env, JTx& jt) const
|
||||
{
|
||||
if (!manual_)
|
||||
return;
|
||||
jt.fill_fee = false;
|
||||
if (increment_)
|
||||
jt[sfFee] = STAmount(env.current()->fees().increment).getJson();
|
||||
if (amount_)
|
||||
jt[jss::Fee] = amount_->getJson(JsonOptions::none);
|
||||
jt[sfFee] = amount_->getJson(JsonOptions::none);
|
||||
}
|
||||
|
||||
} // namespace jtx
|
||||
|
||||
@@ -49,6 +49,16 @@ struct disabled_t
|
||||
};
|
||||
static disabled_t const disabled;
|
||||
|
||||
/** Used for fee() calls that use an owner reserve increment */
|
||||
struct increment_t
|
||||
{
|
||||
increment_t()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static increment_t const increment;
|
||||
|
||||
} // namespace jtx
|
||||
|
||||
} // namespace test
|
||||
|
||||
@@ -1319,21 +1319,16 @@ class Invariants_test : public beast::unit_test::suite
|
||||
auto [tx, vKeylet] =
|
||||
vault.create({.owner = a, .asset = xrpAsset});
|
||||
env(tx);
|
||||
env.close();
|
||||
BEAST_EXPECT(env.le(vKeylet));
|
||||
|
||||
vaultID = vKeylet.key;
|
||||
|
||||
env(vault.deposit(
|
||||
{.depositor = a, .id = vaultID, .amount = xrpAsset(50)}));
|
||||
env.close();
|
||||
|
||||
// Create Loan Broker
|
||||
using namespace loanBroker;
|
||||
|
||||
loanBrokerKeylet = keylet::loanbroker(a.id(), env.seq(a));
|
||||
// Create a Loan Broker with all default values.
|
||||
env(set(a, vaultID));
|
||||
env(set(a, vaultID), fee(increment));
|
||||
|
||||
return BEAST_EXPECT(env.le(loanBrokerKeylet));
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ XRPAmount
|
||||
AMMCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// The fee required for AMMCreate is one owner reserve.
|
||||
return view.fees().increment;
|
||||
return calculateOwnerReserveFee(view, tx);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -70,7 +70,7 @@ XRPAmount
|
||||
DeleteAccount::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// The fee required for AccountDelete is one owner reserve.
|
||||
return view.fees().increment;
|
||||
return calculateOwnerReserveFee(view, tx);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -61,7 +61,7 @@ LedgerStateFix::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// The fee required for LedgerStateFix is one owner reserve, just like
|
||||
// the fee for AccountDelete.
|
||||
return view.fees().increment;
|
||||
return calculateOwnerReserveFee(view, tx);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -92,6 +92,15 @@ LoanBrokerSet::doPreflight(PreflightContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
XRPAmount
|
||||
LoanBrokerSet::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// One reserve increment is typically much greater than one base fee.
|
||||
if (!tx.isFieldPresent(sfLoanBrokerID))
|
||||
return calculateOwnerReserveFee(view, tx);
|
||||
return Transactor::calculateBaseFee(view, tx);
|
||||
}
|
||||
|
||||
TER
|
||||
LoanBrokerSet::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,9 @@ public:
|
||||
static NotTEC
|
||||
doPreflight(PreflightContext const& ctx);
|
||||
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -233,6 +233,18 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
return baseFee + (signerCount * baseFee);
|
||||
}
|
||||
|
||||
// Returns the fee in fee units, not scaled for load.
|
||||
XRPAmount
|
||||
Transactor::calculateOwnerReserveFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// One reserve increment is typically much greater than one base fee.
|
||||
XRPL_ASSERT(
|
||||
view.fees().increment > view.fees().base * 100,
|
||||
"ripple::Transactor::calculateOwnerReserveFee : Owner reserve is much "
|
||||
"greater than base fee");
|
||||
return view.fees().increment;
|
||||
}
|
||||
|
||||
XRPAmount
|
||||
Transactor::minimumFee(
|
||||
Application& app,
|
||||
|
||||
@@ -208,6 +208,10 @@ protected:
|
||||
Fees const& fees,
|
||||
ApplyFlags flags);
|
||||
|
||||
// Returns the fee in fee units, not scaled for load.
|
||||
static XRPAmount
|
||||
calculateOwnerReserveFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
// Base class always returns true
|
||||
static bool
|
||||
isEnabled(PreflightContext const& ctx);
|
||||
|
||||
@@ -91,7 +91,7 @@ XRPAmount
|
||||
VaultCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// One reserve increment is typically much greater than one base fee.
|
||||
return view.fees().increment;
|
||||
return calculateOwnerReserveFee(view, tx);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
Reference in New Issue
Block a user