Switch sfAmount in VaultClawback from defaulted to optional

This commit is contained in:
Bronek Kozicki
2025-03-06 13:55:07 +00:00
parent ac6d26a8b3
commit 1756fa7d08
5 changed files with 44 additions and 12 deletions

View File

@@ -505,7 +505,7 @@ TRANSACTION(ttVAULT_WITHDRAW, 68, VaultWithdraw, ({
TRANSACTION(ttVAULT_CLAWBACK, 69, VaultClawback, ({
{sfVaultID, soeREQUIRED},
{sfHolder, soeREQUIRED},
{sfAmount, soeDEFAULT, soeMPTSupported},
{sfAmount, soeOPTIONAL, soeMPTSupported},
}))
/** This system-generated transaction type is used to update the status of the various amendments.

View File

@@ -203,26 +203,45 @@ class Vault_test : public beast::unit_test::suite
}
{
testcase(prefix + " clawback");
testcase(prefix + " clawback some");
auto code = asset.raw().native() ? ter(tecNO_PERMISSION)
: ter(tesSUCCESS);
auto tx = vault.clawback(
{.issuer = issuer,
.id = keylet.key,
.holder = depositor,
.amount = asset(50)});
.amount = asset(10)});
env(tx, code);
}
// TODO: redeem.
{
testcase(prefix + " clawback all");
auto code = asset.raw().native() ? ter(tecNO_PERMISSION)
: ter(tesSUCCESS);
auto tx = vault.clawback(
{.issuer = issuer,
.id = keylet.key,
.holder = depositor,
.amount = std::nullopt});
env(tx, code);
}
if (!asset.raw().native())
{
testcase(prefix + " deposit again");
auto tx = vault.deposit(
{.depositor = depositor,
.id = keylet.key,
.amount = asset(200)});
env(tx);
}
{
testcase(prefix + " withdraw non-zero assets");
auto number = asset.raw().native() ? 200 : 150;
auto tx = vault.withdraw(
{.depositor = depositor,
.id = keylet.key,
.amount = asset(number)});
.amount = asset(200)});
env(tx);
}

View File

@@ -94,7 +94,8 @@ Vault::clawback(ClawbackArgs const& args)
jv[jss::Account] = args.issuer.human();
jv[jss::VaultID] = to_string(args.id);
jv[jss::Holder] = args.holder.human();
jv[jss::Amount] = to_json(args.amount);
if (args.amount)
jv[jss::Amount] = to_json(*args.amount);
return jv;
}

View File

@@ -95,7 +95,7 @@ struct Vault
Account issuer;
uint256 id;
Account holder;
STAmount amount;
std::optional<STAmount> amount;
};
Json::Value

View File

@@ -22,6 +22,7 @@
#include <xrpld/ledger/View.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
@@ -41,7 +42,8 @@ VaultClawback::preflight(PreflightContext const& ctx)
return temINVALID_FLAG;
// Note, zero amount is valid, it means "all". It is also the default.
if (ctx.tx[sfAmount] < beast::zero)
auto const amount = ctx.tx[~sfAmount];
if (amount && *amount < beast::zero)
return temBAD_AMOUNT;
return preflight2(ctx);
@@ -61,8 +63,8 @@ VaultClawback::preclaim(PreclaimContext const& ctx)
else if (asset.getIssuer() != account)
return tecNO_PERMISSION; // Only issuers can clawback.
STAmount const amount = ctx.tx[sfAmount];
if (asset != amount.asset())
auto const amount = ctx.tx[~sfAmount];
if (amount && asset != amount->asset())
return tecWRONG_ASSET;
return tesSUCCESS;
@@ -76,7 +78,17 @@ VaultClawback::doApply()
if (!vault)
return tecOBJECT_NOT_FOUND;
STAmount const amount = tx[sfAmount];
Asset const asset = vault->at(sfAsset);
STAmount const amount = [&]() -> STAmount {
auto const maybeAmount = tx[~sfAmount];
if (maybeAmount)
return *maybeAmount;
return {sfAmount, asset, 0};
}();
XRPL_ASSERT(
amount.asset() == asset,
"ripple::VaultClawback::doApply : matching asset");
AccountID holder = tx[sfHolder];
STAmount assets, shares;
if (amount == beast::zero)