From 140fd829a067b314d709c02334f8be78a286f83a Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Thu, 1 May 2025 21:11:16 +0100 Subject: [PATCH] Enforce defult rippling in VaultCreate::preclaim --- src/test/app/Vault_test.cpp | 50 ++++++++++++++++++------- src/xrpld/app/tx/detail/VaultCreate.cpp | 13 ++++++- src/xrpld/ledger/detail/View.cpp | 2 +- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index d34bfb7b20..169fa1351d 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -1090,22 +1090,44 @@ class Vault_test : public beast::unit_test::suite { using namespace test::jtx; { - testcase("IOU fail create frozen"); - Env env{*this, supported_amendments() | featureSingleAssetVault}; - Account issuer{"issuer"}; - Account owner{"owner"}; - Account depositor{"depositor"}; - env.fund(XRP(1000), issuer, owner, depositor); - env.close(); - Vault vault{env}; - Asset asset = issuer["IOU"]; + { + testcase("IOU fail create frozen"); + Env env{ + *this, supported_amendments() | featureSingleAssetVault}; + Account issuer{"issuer"}; + Account owner{"owner"}; + env.fund(XRP(1000), issuer, owner); + env.close(); + env(fset(issuer, asfGlobalFreeze)); + env.close(); - auto [tx, keylet] = vault.create({.owner = owner, .asset = asset}); + Vault vault{env}; + Asset asset = issuer["IOU"]; + auto [tx, keylet] = + vault.create({.owner = owner, .asset = asset}); - env(fset(issuer, asfGlobalFreeze)); - env.close(); - env(tx, ter(tecFROZEN)); - env.close(); + env(tx, ter(tecFROZEN)); + env.close(); + } + + { + testcase("IOU fail create no ripling"); + Env env{ + *this, supported_amendments() | featureSingleAssetVault}; + Account issuer{"issuer"}; + Account owner{"owner"}; + env.fund(XRP(1000), issuer, owner); + env.close(); + env(fclear(issuer, asfDefaultRipple)); + env.close(); + + Vault vault{env}; + Asset asset = issuer["IOU"]; + auto [tx, keylet] = + vault.create({.owner = owner, .asset = asset}); + env(tx, ter(terNO_RIPPLE)); + env.close(); + } } { diff --git a/src/xrpld/app/tx/detail/VaultCreate.cpp b/src/xrpld/app/tx/detail/VaultCreate.cpp index b45233d45f..be0993d729 100644 --- a/src/xrpld/app/tx/detail/VaultCreate.cpp +++ b/src/xrpld/app/tx/detail/VaultCreate.cpp @@ -100,7 +100,9 @@ VaultCreate::preclaim(PreclaimContext const& ctx) auto vaultAsset = ctx.tx[sfAsset]; auto account = ctx.tx[sfAccount]; - if (vaultAsset.holds()) + if (vaultAsset.native()) + ; // No special checks for XRP + else if (vaultAsset.holds()) { auto mptID = vaultAsset.get().getMptID(); auto issuance = ctx.view.read(keylet::mptIssuance(mptID)); @@ -109,6 +111,15 @@ VaultCreate::preclaim(PreclaimContext const& ctx) if ((issuance->getFlags() & lsfMPTCanTransfer) == 0) return tecNO_AUTH; } + else if (vaultAsset.holds()) + { + auto const issuer = + ctx.view.read(keylet::account(vaultAsset.getIssuer())); + if (!issuer) + return terNO_ACCOUNT; // LCOV_EXCL_LINE + else if (!issuer->isFlag(lsfDefaultRipple)) + return terNO_RIPPLE; + } // Check for pseudo-account issuers - we do not want a vault to hold such // assets (e.g. MPT shares to other vaults or AMM LPTokens) as they would be diff --git a/src/xrpld/ledger/detail/View.cpp b/src/xrpld/ledger/detail/View.cpp index 22596ab4b7..1084ac5c0b 100644 --- a/src/xrpld/ledger/detail/View.cpp +++ b/src/xrpld/ledger/detail/View.cpp @@ -1147,7 +1147,7 @@ addEmptyHolding( auto const& issuerId = issue.getIssuer(); auto const& currency = issue.currency; if (isGlobalFrozen(view, issuerId)) - return tecFROZEN; + return tecINTERNAL; // LCOV_EXCL_LINE auto const& srcId = issuerId; auto const& dstId = accountID;