xrpld
Loading...
Searching...
No Matches
VaultHelpers.cpp
1#include <xrpl/ledger/helpers/VaultHelpers.h>
2
3#include <xrpl/basics/Number.h>
4#include <xrpl/beast/utility/instrumentation.h>
5#include <xrpl/ledger/ReadView.h>
6#include <xrpl/protocol/AccountID.h>
7#include <xrpl/protocol/Indexes.h>
8#include <xrpl/protocol/LedgerFormats.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STAmount.h>
11#include <xrpl/protocol/STLedgerEntry.h>
12#include <xrpl/protocol/STNumber.h> // IWYU pragma: keep
13
14#include <cstdint>
15#include <optional>
16
17namespace xrpl {
18
19[[nodiscard]] std::optional<STAmount>
21{
22 XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets");
23 XRPL_ASSERT(
24 assets.asset() == vault->at(sfAsset),
25 "xrpl::assetsToSharesDeposit : assets and vault match");
26 if (assets.negative() || assets.asset() != vault->at(sfAsset))
27 return std::nullopt; // LCOV_EXCL_LINE
28
29 Number const assetTotal = vault->at(sfAssetsTotal);
30 STAmount shares{vault->at(sfShareMPTID)};
31 if (assetTotal == 0)
32 {
33 return STAmount{
34 shares.asset(),
35 Number(assets.mantissa(), assets.exponent() + vault->at(sfScale)).truncate()};
36 }
37
38 Number const shareTotal = issuance->at(sfOutstandingAmount);
39 shares = ((shareTotal * assets) / assetTotal).truncate();
40 return shares;
41}
42
43[[nodiscard]] std::optional<STAmount>
45{
46 XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares");
47 XRPL_ASSERT(
48 shares.asset() == vault->at(sfShareMPTID),
49 "xrpl::sharesToAssetsDeposit : shares and vault match");
50 if (shares.negative() || shares.asset() != vault->at(sfShareMPTID))
51 return std::nullopt; // LCOV_EXCL_LINE
52
53 Number const assetTotal = vault->at(sfAssetsTotal);
54 STAmount assets{vault->at(sfAsset)};
55 if (assetTotal == 0)
56 {
57 return STAmount{
58 assets.asset(), shares.mantissa(), shares.exponent() - vault->at(sfScale), false};
59 }
60
61 Number const shareTotal = issuance->at(sfOutstandingAmount);
62 assets = (assetTotal * shares) / shareTotal;
63 return assets;
64}
65
66[[nodiscard]] std::optional<STAmount>
68 SLE::const_ref vault,
69 SLE::const_ref issuance,
70 STAmount const& assets,
71 TruncateShares truncate,
73{
74 XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesWithdraw : non-negative assets");
75 XRPL_ASSERT(
76 assets.asset() == vault->at(sfAsset),
77 "xrpl::assetsToSharesWithdraw : assets and vault match");
78 if (assets.negative() || assets.asset() != vault->at(sfAsset))
79 return std::nullopt; // LCOV_EXCL_LINE
80
81 Number assetTotal = vault->at(sfAssetsTotal);
82 if (waive == WaiveUnrealizedLoss::No)
83 assetTotal -= vault->at(sfLossUnrealized);
84 STAmount shares{vault->at(sfShareMPTID)};
85 if (assetTotal == 0)
86 return shares;
87 Number const shareTotal = issuance->at(sfOutstandingAmount);
88 Number result = (shareTotal * assets) / assetTotal;
89 if (truncate == TruncateShares::Yes)
90 result = result.truncate();
91 shares = result;
92 return shares;
93}
94
95[[nodiscard]] std::optional<STAmount>
97 SLE::const_ref vault,
98 SLE::const_ref issuance,
99 STAmount const& shares,
101{
102 XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsWithdraw : non-negative shares");
103 XRPL_ASSERT(
104 shares.asset() == vault->at(sfShareMPTID),
105 "xrpl::sharesToAssetsWithdraw : shares and vault match");
106 if (shares.negative() || shares.asset() != vault->at(sfShareMPTID))
107 return std::nullopt; // LCOV_EXCL_LINE
108
109 Number assetTotal = vault->at(sfAssetsTotal);
110 if (waive == WaiveUnrealizedLoss::No)
111 assetTotal -= vault->at(sfLossUnrealized);
112 STAmount assets{vault->at(sfAsset)};
113 if (assetTotal == 0)
114 return assets;
115 Number const shareTotal = issuance->at(sfOutstandingAmount);
116 assets = (assetTotal * shares) / shareTotal;
117 return assets;
118}
119
120[[nodiscard]] bool
121isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance)
122{
123 XRPL_ASSERT(
124 issuance && issuance->getType() == ltMPTOKEN_ISSUANCE,
125 "xrpl::isSoleShareholder : valid issuance SLE");
126
127 std::uint64_t const outstanding = issuance->at(sfOutstandingAmount);
128 if (outstanding == 0)
129 return false;
130
131 auto const shareMPTID =
132 makeMptID(issuance->getFieldU32(sfSequence), issuance->getAccountID(sfIssuer));
133 auto const sleToken = view.read(keylet::mptoken(shareMPTID, account));
134 if (!sleToken)
135 return false; // LCOV_EXCL_LINE
136
137 return sleToken->getFieldU64(sfMPTAmount) == outstanding;
138}
139
140} // namespace xrpl
Number is a floating point type that can represent a wide range of values.
Definition Number.h:306
Number truncate() const noexcept
Definition Number.cpp:1062
A view into a ledger.
Definition ReadView.h:31
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
std::uint64_t mantissa() const noexcept
Definition STAmount.h:472
bool negative() const noexcept
Definition STAmount.h:466
Asset const & asset() const
Definition STAmount.h:478
int exponent() const noexcept
Definition STAmount.h:441
std::shared_ptr< STLedgerEntry const > const & const_ref
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:533
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::optional< STAmount > assetsToSharesWithdraw(SLE::const_ref vault, SLE::const_ref issuance, STAmount const &assets, TruncateShares truncate=TruncateShares::No, WaiveUnrealizedLoss waive=WaiveUnrealizedLoss::No)
From the perspective of a vault, return the number of shares to demand from the depositor when they a...
std::optional< STAmount > sharesToAssetsWithdraw(SLE::const_ref vault, SLE::const_ref issuance, STAmount const &shares, WaiveUnrealizedLoss waive=WaiveUnrealizedLoss::No)
From the perspective of a vault, return the number of assets to give the depositor when they redeem a...
TruncateShares
Controls whether to truncate shares instead of rounding.
std::optional< STAmount > sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const &shares)
From the perspective of a vault, return the number of assets to take from depositor when they receive...
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
bool isSoleShareholder(ReadView const &view, AccountID const &account, SLE::const_ref issuance)
Returns true iff account holds all of the vault's outstanding shares — i.e.
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition Indexes.cpp:172
std::optional< STAmount > assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const &assets)
From the perspective of a vault, return the number of shares to give depositor when they offer a fixe...
WaiveUnrealizedLoss
Controls whether the withdraw conversion helpers (assetsToSharesWithdraw and sharesToAssetsWithdraw) ...