mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-19 05:10:55 +00:00
113 lines
3.8 KiB
C++
113 lines
3.8 KiB
C++
#include <xrpl/ledger/helpers/VaultHelpers.h>
|
|
//
|
|
#include <xrpl/basics/Number.h>
|
|
#include <xrpl/protocol/LedgerFormats.h>
|
|
#include <xrpl/protocol/st.h>
|
|
|
|
namespace xrpl {
|
|
|
|
[[nodiscard]] std::optional<STAmount>
|
|
assetsToSharesDeposit(
|
|
std::shared_ptr<SLE const> const& vault,
|
|
MPTokenIssuance 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<STAmount>
|
|
sharesToAssetsDeposit(
|
|
std::shared_ptr<SLE const> const& vault,
|
|
MPTokenIssuance 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<STAmount>
|
|
assetsToSharesWithdraw(
|
|
std::shared_ptr<SLE const> const& vault,
|
|
MPTokenIssuance const& issuance,
|
|
STAmount const& assets,
|
|
TruncateShares truncate)
|
|
{
|
|
XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesWithdraw : 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<STAmount>
|
|
sharesToAssetsWithdraw(
|
|
std::shared_ptr<SLE const> const& vault,
|
|
MPTokenIssuance 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;
|
|
}
|
|
|
|
} // namespace xrpl
|