mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-31 19:10:25 +00:00
fix: Add checkDepositFreeze and relax vault deposit freeze semantics
Add checkDepositFreeze that checks the depositor for regular freeze and the destination pseudo-account for deep freeze only. A regular freeze on the vault account's trust line no longer blocks deposits. Update checkWithdrawFreezes to skip the submitter freeze check when submitter == destination (withdrawing to self). Gate VaultDeposit with fixCleanup3_3_0; pre-fix path preserves the old isFrozen-based checks. Use checkDepositFreeze in LoanBrokerCoverDeposit.
This commit is contained in:
@@ -150,6 +150,18 @@ checkWithdrawFreezes(
|
||||
AccountID const& dstAcct,
|
||||
Asset const& asset);
|
||||
|
||||
/**
|
||||
* Checks freeze compliance for a pseudo-account deposit.
|
||||
* - The source pseudo-account is not deep frozen for the asset
|
||||
* - The submitting account is not individually frozen for the asset
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkDepositFreeze(
|
||||
ReadView const& view,
|
||||
AccountID const& sourceAcct,
|
||||
AccountID const& dstAcct,
|
||||
Asset const& asset);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Account balance functions (Asset-based dispatchers)
|
||||
|
||||
@@ -167,13 +167,13 @@ checkDeepFrozen(ReadView const& view, AccountID const& account, Asset const& ass
|
||||
TER
|
||||
checkWithdrawFreezes(
|
||||
ReadView const& view,
|
||||
AccountID const& sourceAcct,
|
||||
AccountID const& srcAcct,
|
||||
AccountID const& submitterAcct,
|
||||
AccountID const& dstAcct,
|
||||
Asset const& asset)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
isPseudoAccount(view, sourceAcct),
|
||||
isPseudoAccount(view, srcAcct),
|
||||
"xrpl::checkWithdrawFreezes : source must be a pseudo-account");
|
||||
|
||||
// No matter what, funds can be sent to the issuer
|
||||
@@ -182,16 +182,39 @@ checkWithdrawFreezes(
|
||||
|
||||
// The transfer is from Submitter to Destination via Source (pseudo-account)
|
||||
// Both Source and Submitter must not be frozen to allow sending funds
|
||||
if (auto const ret = checkFrozen(view, sourceAcct, asset))
|
||||
if (auto const ret = checkFrozen(view, srcAcct, asset))
|
||||
return ret;
|
||||
|
||||
if (auto const ret = checkFrozen(view, submitterAcct, asset))
|
||||
return ret;
|
||||
// Check submitter's individual freeze only when Submitter != Destination (a regular freeze
|
||||
// should not block self-withdrawal).
|
||||
if (submitterAcct != dstAcct)
|
||||
{
|
||||
if (auto const ret = checkFrozen(view, submitterAcct, asset))
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The destination account must not be deep frozen to receive the funds
|
||||
return checkDeepFrozen(view, dstAcct, asset);
|
||||
}
|
||||
|
||||
[[nodiscard]] TER
|
||||
checkDepositFreeze(
|
||||
ReadView const& view,
|
||||
AccountID const& srcAcct,
|
||||
AccountID const& dstAcct,
|
||||
Asset const& asset)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
isPseudoAccount(view, dstAcct),
|
||||
"xrpl::checkDepositFreeze : destination must be a pseudo-account");
|
||||
|
||||
if (auto const ret = checkFrozen(view, srcAcct, asset))
|
||||
return ret;
|
||||
|
||||
// Pseudo-account cannot receive if asset is deep frozen
|
||||
return checkDeepFrozen(view, dstAcct, asset);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Account balance functions
|
||||
|
||||
@@ -77,12 +77,10 @@ LoanBrokerCoverDeposit::preclaim(PreclaimContext const& ctx)
|
||||
// Cannot transfer a non-transferable Asset
|
||||
if (auto const ret = canTransfer(ctx.view, vaultAsset, account, pseudoAccountID))
|
||||
return ret;
|
||||
// Cannot transfer a frozen Asset
|
||||
if (auto const ret = checkFrozen(ctx.view, account, vaultAsset))
|
||||
return ret;
|
||||
// Pseudo-account cannot receive if asset is deep frozen
|
||||
if (auto const ret = checkDeepFrozen(ctx.view, pseudoAccountID, vaultAsset))
|
||||
|
||||
if (auto const ret = checkDepositFreeze(ctx.view, account, pseudoAccountID, vaultAsset))
|
||||
return ret;
|
||||
|
||||
// Cannot transfer unauthorized asset
|
||||
if (auto const ret = requireAuth(ctx.view, vaultAsset, account, AuthType::StrongAuth))
|
||||
return ret;
|
||||
|
||||
@@ -107,13 +107,21 @@ VaultDeposit::preclaim(PreclaimContext const& ctx)
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
// Cannot deposit inside Vault an Asset frozen for the depositor
|
||||
if (isFrozen(ctx.view, account, vaultAsset))
|
||||
return vaultAsset.holds<Issue>() ? tecFROZEN : tecLOCKED;
|
||||
if (ctx.view.rules().enabled(fixCleanup3_3_0))
|
||||
{
|
||||
if (auto const ret = checkDepositFreeze(ctx.view, account, vaultAccount, vaultAsset))
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cannot deposit inside Vault an Asset frozen for the depositor
|
||||
if (isFrozen(ctx.view, account, vaultAsset))
|
||||
return vaultAsset.holds<Issue>() ? tecFROZEN : tecLOCKED;
|
||||
|
||||
// Cannot deposit if the shares of the vault are frozen
|
||||
if (isFrozen(ctx.view, account, vaultShare))
|
||||
return tecLOCKED;
|
||||
// Cannot deposit if the shares of the vault are frozen
|
||||
if (isFrozen(ctx.view, account, vaultShare))
|
||||
return tecLOCKED;
|
||||
}
|
||||
|
||||
if (vault->isFlag(lsfVaultPrivate) && account != vault->at(sfOwner))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user