mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
135 lines
4.0 KiB
C++
135 lines
4.0 KiB
C++
#include <xrpl/protocol/AMMCore.h>
|
|
|
|
#include <xrpl/basics/base_uint.h>
|
|
#include <xrpl/beast/utility/Zero.h>
|
|
#include <xrpl/beast/utility/instrumentation.h>
|
|
#include <xrpl/protocol/AccountID.h>
|
|
#include <xrpl/protocol/Asset.h>
|
|
#include <xrpl/protocol/Concepts.h>
|
|
#include <xrpl/protocol/Feature.h>
|
|
#include <xrpl/protocol/Issue.h>
|
|
#include <xrpl/protocol/MPTIssue.h>
|
|
#include <xrpl/protocol/Rules.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STAmount.h>
|
|
#include <xrpl/protocol/STObject.h>
|
|
#include <xrpl/protocol/TER.h>
|
|
#include <xrpl/protocol/UintTypes.h>
|
|
#include <xrpl/protocol/digest.h>
|
|
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <utility>
|
|
#include <variant>
|
|
|
|
namespace xrpl {
|
|
|
|
Currency
|
|
ammLPTCurrency(Asset const& asset1, Asset const& asset2)
|
|
{
|
|
// AMM LPToken is 0x03 plus 19 bytes of the hash
|
|
std::int32_t constexpr AMMCurrencyCode = 0x03;
|
|
auto const& [minA, maxA] = std::minmax(asset1, asset2);
|
|
uint256 const hash = std::visit(
|
|
[](auto&& issue1, auto&& issue2) {
|
|
auto fromIss = []<ValidIssueType T>(T const& issue) {
|
|
if constexpr (std::is_same_v<T, Issue>)
|
|
return issue.currency;
|
|
if constexpr (std::is_same_v<T, MPTIssue>)
|
|
return issue.getMptID();
|
|
};
|
|
return sha512Half(fromIss(issue1), fromIss(issue2));
|
|
},
|
|
minA.value(),
|
|
maxA.value());
|
|
Currency currency;
|
|
*currency.begin() = AMMCurrencyCode;
|
|
std::copy(hash.begin(), hash.begin() + currency.size() - 1, currency.begin() + 1);
|
|
return currency;
|
|
}
|
|
|
|
Issue
|
|
ammLPTIssue(Asset const& asset1, Asset const& asset2, AccountID const& ammAccountID)
|
|
{
|
|
return Issue(ammLPTCurrency(asset1, asset2), ammAccountID);
|
|
}
|
|
|
|
NotTEC
|
|
invalidAMMAsset(Asset const& asset, std::optional<std::pair<Asset, Asset>> const& pair)
|
|
{
|
|
auto const err = asset.visit(
|
|
[](MPTIssue const& issue) -> std::optional<NotTEC> {
|
|
if (issue.getIssuer() == beast::zero)
|
|
return temBAD_MPT;
|
|
return std::nullopt;
|
|
},
|
|
[](Issue const& issue) -> std::optional<NotTEC> {
|
|
if (badCurrency() == issue.currency)
|
|
return temBAD_CURRENCY;
|
|
if (isXRP(issue) && issue.getIssuer().isNonZero())
|
|
return temBAD_ISSUER;
|
|
return std::nullopt;
|
|
});
|
|
if (err)
|
|
return *err;
|
|
if (pair && asset != pair->first && asset != pair->second)
|
|
return temBAD_AMM_TOKENS;
|
|
return tesSUCCESS;
|
|
}
|
|
|
|
NotTEC
|
|
invalidAMMAssetPair(
|
|
Asset const& asset1,
|
|
Asset const& asset2,
|
|
std::optional<std::pair<Asset, Asset>> const& pair)
|
|
{
|
|
if (asset1 == asset2)
|
|
return temBAD_AMM_TOKENS;
|
|
if (auto const res = invalidAMMAsset(asset1, pair))
|
|
return res;
|
|
if (auto const res = invalidAMMAsset(asset2, pair))
|
|
return res;
|
|
return tesSUCCESS;
|
|
}
|
|
|
|
NotTEC
|
|
invalidAMMAmount(
|
|
STAmount const& amount,
|
|
std::optional<std::pair<Asset, Asset>> const& pair,
|
|
bool validZero)
|
|
{
|
|
if (auto const res = invalidAMMAsset(amount.asset(), pair))
|
|
return res;
|
|
if (amount < beast::zero || (!validZero && amount == beast::zero))
|
|
return temBAD_AMOUNT;
|
|
return tesSUCCESS;
|
|
}
|
|
|
|
std::optional<std::uint8_t>
|
|
ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
|
|
{
|
|
// It should be impossible for expiration to be < TOTAL_TIME_SLOT_SECS,
|
|
// but check just to be safe
|
|
auto const expiration = auctionSlot[sfExpiration];
|
|
XRPL_ASSERT(
|
|
expiration >= TOTAL_TIME_SLOT_SECS, "xrpl::ammAuctionTimeSlot : minimum expiration");
|
|
if (expiration >= TOTAL_TIME_SLOT_SECS)
|
|
{
|
|
if (auto const start = expiration - TOTAL_TIME_SLOT_SECS; current >= start)
|
|
{
|
|
if (auto const diff = current - start; diff < TOTAL_TIME_SLOT_SECS)
|
|
return diff / AUCTION_SLOT_INTERVAL_DURATION;
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
bool
|
|
ammEnabled(Rules const& rules)
|
|
{
|
|
return rules.enabled(featureAMM);
|
|
}
|
|
|
|
} // namespace xrpl
|