diff --git a/include/xrpl/ledger/View.h b/include/xrpl/ledger/View.h index d6f3bdfe5e..a485f8decc 100644 --- a/include/xrpl/ledger/View.h +++ b/include/xrpl/ledger/View.h @@ -945,51 +945,6 @@ deleteAMMTrustLine( std::optional const& ammAccountID, beast::Journal j); -// From the perspective of a vault, return the number of shares to give the -// depositor when they deposit a fixed amount of assets. Since shares are MPT -// this number is integral and always truncated in this calculation. -[[nodiscard]] std::optional -assetsToSharesDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets); - -// From the perspective of a vault, return the number of assets to take from -// depositor when they receive a fixed amount of shares. Note, since shares are -// MPT, they are always an integral number. -[[nodiscard]] std::optional -sharesToAssetsDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares); - -enum class TruncateShares : bool { no = false, yes = true }; - -// From the perspective of a vault, return the number of shares to demand from -// the depositor when they ask to withdraw a fixed amount of assets. Since -// shares are MPT this number is integral, and it will be rounded to nearest -// unless explicitly requested to be truncated instead. -[[nodiscard]] std::optional -assetsToSharesWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets, - TruncateShares truncate = TruncateShares::no); - -// From the perspective of a vault, return the number of assets to give the -// depositor when they redeem a fixed amount of shares. Note, since shares are -// MPT, they are always an integral number. -[[nodiscard]] std::optional -sharesToAssetsWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares); - -// Determine if a vault is insolvent. A vault is considered insolvent when -// the total assets in the vault are zero, and outstanding shares are non-zero. -[[nodiscard]] bool -isVaultInsolvent(std::shared_ptr const& vault, std::shared_ptr const& shareIssuance); - /** Has the specified time passed? @param now the current time diff --git a/include/xrpl/tx/transactors/Vault/VaultClawback.h b/include/xrpl/tx/transactors/Vault/VaultClawback.h index 131a1d87e7..3a38a0661b 100644 --- a/include/xrpl/tx/transactors/Vault/VaultClawback.h +++ b/include/xrpl/tx/transactors/Vault/VaultClawback.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace xrpl { diff --git a/include/xrpl/tx/transactors/Vault/VaultDeposit.h b/include/xrpl/tx/transactors/Vault/VaultDeposit.h index 0943596f20..43fa4566b3 100644 --- a/include/xrpl/tx/transactors/Vault/VaultDeposit.h +++ b/include/xrpl/tx/transactors/Vault/VaultDeposit.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace xrpl { diff --git a/include/xrpl/tx/transactors/Vault/VaultHelpers.h b/include/xrpl/tx/transactors/Vault/VaultHelpers.h new file mode 100644 index 0000000000..fd5f9b7b95 --- /dev/null +++ b/include/xrpl/tx/transactors/Vault/VaultHelpers.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include + +namespace xrpl { + +enum class TruncateShares : bool { no = false, yes = true }; + +// From the perspective of a vault, return the number of shares to give the +// depositor when they deposit a fixed amount of assets. Since shares are MPT +// this number is integral and always truncated in this calculation. +[[nodiscard]] std::optional +assetsToSharesDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets); + +// From the perspective of a vault, return the number of assets to take from +// depositor when they receive a fixed amount of shares. Note, since shares are +// MPT, they are always an integral number. +[[nodiscard]] std::optional +sharesToAssetsDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares); + +// From the perspective of a vault, return the number of shares to demand from +// the depositor when they ask to withdraw a fixed amount of assets. Since +// shares are MPT this number is integral, and it will be rounded to nearest +// unless explicitly requested to be truncated instead. +[[nodiscard]] std::optional +assetsToSharesWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets, + TruncateShares truncate = TruncateShares::no); + +// From the perspective of a vault, return the number of assets to give the +// depositor when they redeem a fixed amount of shares. Note, since shares are +// MPT, they are always an integral number. +[[nodiscard]] std::optional +sharesToAssetsWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares); + +// Determine if a vault is insolvent. A vault is considered insolvent when +// the total assets in the vault are zero, and outstanding shares are non-zero. +[[nodiscard]] bool +isVaultInsolvent(std::shared_ptr const& vault, std::shared_ptr const& shareIssuance); + +} // namespace xrpl diff --git a/include/xrpl/tx/transactors/Vault/VaultWithdraw.h b/include/xrpl/tx/transactors/Vault/VaultWithdraw.h index ffe14a7141..154fa2d09b 100644 --- a/include/xrpl/tx/transactors/Vault/VaultWithdraw.h +++ b/include/xrpl/tx/transactors/Vault/VaultWithdraw.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace xrpl { diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index 01f7dcf881..444443fdea 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -3103,94 +3103,6 @@ rippleCredit( saAmount.asset().value()); } -[[nodiscard]] std::optional -assetsToSharesDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets) -{ - XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); - XRPL_ASSERT(assets.asset() == vault->at(sfAsset), "xrpl::assetsToSharesDeposit : assets and vault match"); - if (assets.negative() || assets.asset() != vault->at(sfAsset)) - return std::nullopt; // LCOV_EXCL_LINE - - Number const assetTotal = vault->at(sfAssetsTotal); - STAmount shares{vault->at(sfShareMPTID)}; - if (assetTotal == 0) - return STAmount{shares.asset(), Number(assets.mantissa(), assets.exponent() + vault->at(sfScale)).truncate()}; - - Number const shareTotal = issuance->at(sfOutstandingAmount); - shares = ((shareTotal * assets) / assetTotal).truncate(); - return shares; -} - -[[nodiscard]] std::optional -sharesToAssetsDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares) -{ - XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); - XRPL_ASSERT(shares.asset() == vault->at(sfShareMPTID), "xrpl::sharesToAssetsDeposit : shares and vault match"); - if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) - return std::nullopt; // LCOV_EXCL_LINE - - Number const assetTotal = vault->at(sfAssetsTotal); - STAmount assets{vault->at(sfAsset)}; - if (assetTotal == 0) - return STAmount{assets.asset(), shares.mantissa(), shares.exponent() - vault->at(sfScale), false}; - - Number const shareTotal = issuance->at(sfOutstandingAmount); - assets = (assetTotal * shares) / shareTotal; - return assets; -} - -[[nodiscard]] std::optional -assetsToSharesWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets, - TruncateShares truncate) -{ - XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); - XRPL_ASSERT(assets.asset() == vault->at(sfAsset), "xrpl::assetsToSharesWithdraw : assets and vault match"); - if (assets.negative() || assets.asset() != vault->at(sfAsset)) - return std::nullopt; // LCOV_EXCL_LINE - - Number assetTotal = vault->at(sfAssetsTotal); - assetTotal -= vault->at(sfLossUnrealized); - STAmount shares{vault->at(sfShareMPTID)}; - if (assetTotal == 0) - return shares; - Number const shareTotal = issuance->at(sfOutstandingAmount); - Number result = (shareTotal * assets) / assetTotal; - if (truncate == TruncateShares::yes) - result = result.truncate(); - shares = result; - return shares; -} - -[[nodiscard]] std::optional -sharesToAssetsWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares) -{ - XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); - XRPL_ASSERT(shares.asset() == vault->at(sfShareMPTID), "xrpl::sharesToAssetsWithdraw : shares and vault match"); - if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) - return std::nullopt; // LCOV_EXCL_LINE - - Number assetTotal = vault->at(sfAssetsTotal); - assetTotal -= vault->at(sfLossUnrealized); - STAmount assets{vault->at(sfAsset)}; - if (assetTotal == 0) - return assets; - Number const shareTotal = issuance->at(sfOutstandingAmount); - assets = (assetTotal * shares) / shareTotal; - return assets; -} - TER rippleLockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, beast::Journal j) { @@ -3438,13 +3350,4 @@ after(NetClock::time_point now, std::uint32_t mark) return now.time_since_epoch().count() > mark; } -[[nodiscard]] bool -isVaultInsolvent(std::shared_ptr const& vault, std::shared_ptr const& shareIssuance) -{ - auto const assetsTotal = vault->at(sfAssetsTotal); - auto const sharesOutstanding = shareIssuance->at(sfOutstandingAmount); - - return assetsTotal == 0 && sharesOutstanding > 0; -} - } // namespace xrpl diff --git a/src/libxrpl/tx/transactors/Vault/VaultClawback.cpp b/src/libxrpl/tx/transactors/Vault/VaultClawback.cpp index 4be1b52eb7..89932d6907 100644 --- a/src/libxrpl/tx/transactors/Vault/VaultClawback.cpp +++ b/src/libxrpl/tx/transactors/Vault/VaultClawback.cpp @@ -1,4 +1,5 @@ -#include +#include +// #include #include #include @@ -8,7 +9,6 @@ #include #include #include -#include #include diff --git a/src/libxrpl/tx/transactors/Vault/VaultCreate.cpp b/src/libxrpl/tx/transactors/Vault/VaultCreate.cpp index c911c496ff..40192a56b6 100644 --- a/src/libxrpl/tx/transactors/Vault/VaultCreate.cpp +++ b/src/libxrpl/tx/transactors/Vault/VaultCreate.cpp @@ -1,3 +1,5 @@ +#include +// #include #include #include @@ -12,7 +14,6 @@ #include #include #include -#include namespace xrpl { diff --git a/src/libxrpl/tx/transactors/Vault/VaultDelete.cpp b/src/libxrpl/tx/transactors/Vault/VaultDelete.cpp index 7d8bf35e5f..c1be184d16 100644 --- a/src/libxrpl/tx/transactors/Vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/Vault/VaultDelete.cpp @@ -1,3 +1,5 @@ +#include +// #include #include #include @@ -5,7 +7,6 @@ #include #include #include -#include namespace xrpl { diff --git a/src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp b/src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp index 029b36c2cb..3837e35a54 100644 --- a/src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp +++ b/src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp @@ -1,3 +1,5 @@ +#include +// #include #include #include @@ -10,7 +12,6 @@ #include #include #include -#include namespace xrpl { diff --git a/src/libxrpl/tx/transactors/Vault/VaultHelpers.cpp b/src/libxrpl/tx/transactors/Vault/VaultHelpers.cpp new file mode 100644 index 0000000000..82b04cdbe5 --- /dev/null +++ b/src/libxrpl/tx/transactors/Vault/VaultHelpers.cpp @@ -0,0 +1,123 @@ +#include + +namespace xrpl { + +[[nodiscard]] std::optional +assetsToSharesDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets) +{ + XRPL_ASSERT(vault && vault->getType() == ltVAULT, "xrpl::assetsToSharesDeposit : Vault sle"); + XRPL_ASSERT( + issuance && issuance->getType() == ltMPTOKEN_ISSUANCE, "xrpl::assetsToSharesDeposit : MPTokenIssuance sle"); + + XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); + XRPL_ASSERT(assets.asset() == vault->at(sfAsset), "xrpl::assetsToSharesDeposit : assets and vault match"); + if (assets.negative() || assets.asset() != vault->at(sfAsset)) + return std::nullopt; // LCOV_EXCL_LINE + + Number const assetTotal = vault->at(sfAssetsTotal); + STAmount shares{vault->at(sfShareMPTID)}; + if (assetTotal == 0) + return STAmount{shares.asset(), Number(assets.mantissa(), assets.exponent() + vault->at(sfScale)).truncate()}; + + Number const shareTotal = issuance->at(sfOutstandingAmount); + shares = ((shareTotal * assets) / assetTotal).truncate(); + return shares; +} + +[[nodiscard]] std::optional +sharesToAssetsDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares) +{ + XRPL_ASSERT(vault && vault->getType() == ltVAULT, "xrpl::sharesToAssetsDeposit : Vault sle"); + XRPL_ASSERT( + issuance && issuance->getType() == ltMPTOKEN_ISSUANCE, "xrpl::sharesToAssetsDeposit : MPTokenIssuance sle"); + + XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); + XRPL_ASSERT(shares.asset() == vault->at(sfShareMPTID), "xrpl::sharesToAssetsDeposit : shares and vault match"); + if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) + return std::nullopt; // LCOV_EXCL_LINE + + Number const assetTotal = vault->at(sfAssetsTotal); + STAmount assets{vault->at(sfAsset)}; + if (assetTotal == 0) + return STAmount{assets.asset(), shares.mantissa(), shares.exponent() - vault->at(sfScale), false}; + + Number const shareTotal = issuance->at(sfOutstandingAmount); + assets = (assetTotal * shares) / shareTotal; + return assets; +} + +[[nodiscard]] std::optional +assetsToSharesWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets, + TruncateShares truncate) +{ + XRPL_ASSERT(vault && vault->getType() == ltVAULT, "xrpl::assetsToSharesWithdraw : Vault sle"); + XRPL_ASSERT( + issuance && issuance->getType() == ltMPTOKEN_ISSUANCE, "xrpl::assetsToSharesWithdraw : MPTokenIssuance sle"); + + XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); + XRPL_ASSERT(assets.asset() == vault->at(sfAsset), "xrpl::assetsToSharesWithdraw : assets and vault match"); + if (assets.negative() || assets.asset() != vault->at(sfAsset)) + return std::nullopt; // LCOV_EXCL_LINE + + Number assetTotal = vault->at(sfAssetsTotal); + assetTotal -= vault->at(sfLossUnrealized); + STAmount shares{vault->at(sfShareMPTID)}; + if (assetTotal == 0) + return shares; + Number const shareTotal = issuance->at(sfOutstandingAmount); + Number result = (shareTotal * assets) / assetTotal; + if (truncate == TruncateShares::yes) + result = result.truncate(); + shares = result; + return shares; +} + +[[nodiscard]] std::optional +sharesToAssetsWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares) +{ + XRPL_ASSERT(vault && vault->getType() == ltVAULT, "xrpl::sharesToAssetsWithdraw : Vault sle"); + XRPL_ASSERT( + issuance && issuance->getType() == ltMPTOKEN_ISSUANCE, "xrpl::sharesToAssetsWithdraw : MPTokenIssuance sle"); + + XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); + XRPL_ASSERT(shares.asset() == vault->at(sfShareMPTID), "xrpl::sharesToAssetsWithdraw : shares and vault match"); + if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) + return std::nullopt; // LCOV_EXCL_LINE + + Number assetTotal = vault->at(sfAssetsTotal); + assetTotal -= vault->at(sfLossUnrealized); + STAmount assets{vault->at(sfAsset)}; + if (assetTotal == 0) + return assets; + Number const shareTotal = issuance->at(sfOutstandingAmount); + assets = (assetTotal * shares) / shareTotal; + return assets; +} + +[[nodiscard]] bool +isVaultInsolvent(std::shared_ptr const& vault, std::shared_ptr const& shareIssuance) +{ + XRPL_ASSERT(vault && vault->getType() == ltVAULT, "xrpl::isVaultInsolvent : Vault sle"); + XRPL_ASSERT( + shareIssuance && shareIssuance->getType() == ltMPTOKEN_ISSUANCE, + "xrpl::isVaultInsolvent : MPTokenIssuance sle"); + + auto const assetsTotal = vault->at(sfAssetsTotal); + auto const sharesOutstanding = shareIssuance->at(sfOutstandingAmount); + + return assetsTotal == 0 && sharesOutstanding > 0; +} + +} // namespace xrpl diff --git a/src/libxrpl/tx/transactors/Vault/VaultSet.cpp b/src/libxrpl/tx/transactors/Vault/VaultSet.cpp index 17064977a7..03bf3fc686 100644 --- a/src/libxrpl/tx/transactors/Vault/VaultSet.cpp +++ b/src/libxrpl/tx/transactors/Vault/VaultSet.cpp @@ -34,13 +34,13 @@ VaultSet::getFlagsMask(PreflightContext const& ctx) static bool isValidVaultUpdate(PreflightContext const& ctx) { - auto const shouldCheckFlags = ctx.rules.enabled(fixLendingProtocolV1_1); - auto const atLeastOneFieldPresent = ctx.tx.isFieldPresent(sfDomainID) || ctx.tx.isFieldPresent(sfAssetsMaximum) || ctx.tx.isFieldPresent(sfData); - return atLeastOneFieldPresent || - (shouldCheckFlags && (ctx.tx.isFlag(tfVaultDepositBlock) || ctx.tx.isFlag(tfVaultDepositUnblock))); + auto const shouldCheckFlags = ctx.rules.enabled(fixLendingProtocolV1_1); + auto const expectedFlags = ~(VaultSet::getFlagsMask(ctx) | tfUniversal); + + return atLeastOneFieldPresent || (shouldCheckFlags && (ctx.tx.getFlags() & expectedFlags)); } NotTEC diff --git a/src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp index 4d0a3c20a5..95a576052a 100644 --- a/src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp @@ -1,3 +1,5 @@ +#include +// #include #include #include @@ -7,7 +9,6 @@ #include #include #include -#include namespace xrpl {