Skip to content

Commit

Permalink
MPT integration into DEX
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatcam committed Feb 3, 2025
1 parent dcc4581 commit a827630
Show file tree
Hide file tree
Showing 152 changed files with 7,566 additions and 5,558 deletions.
20 changes: 10 additions & 10 deletions include/xrpl/protocol/AMMCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include <xrpl/basics/Number.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>

Expand Down Expand Up @@ -59,14 +59,14 @@ ammAccountID(
/** Calculate Liquidity Provider Token (LPT) Currency.
*/
Currency
ammLPTCurrency(Currency const& cur1, Currency const& cur2);
ammLPTCurrency(Asset const& asset1, Asset const& asset2);

/** Calculate LPT Issue from AMM asset pair.
*/
Issue
ammLPTIssue(
Currency const& cur1,
Currency const& cur2,
Asset const& asset1,
Asset const& asset2,
AccountID const& ammAccountID);

/** Validate the amount.
Expand All @@ -77,19 +77,19 @@ ammLPTIssue(
NotTEC
invalidAMMAmount(
STAmount const& amount,
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt,
bool validZero = false);

NotTEC
invalidAMMAsset(
Issue const& issue,
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
Asset const& asset,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);

NotTEC
invalidAMMAssetPair(
Issue const& issue1,
Issue const& issue2,
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
Asset const& asset1,
Asset const& asset2,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);

/** Get time slot of the auction slot.
*/
Expand Down
100 changes: 79 additions & 21 deletions include/xrpl/protocol/AmountConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define RIPPLE_PROTOCOL_AMOUNTCONVERSION_H_INCLUDED

#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/XRPAmount.h>

Expand All @@ -29,11 +30,12 @@
namespace ripple {

inline STAmount
toSTAmount(IOUAmount const& iou, Issue const& iss)
toSTAmount(IOUAmount const& iou, Asset const& asset)
{
XRPL_ASSERT(asset.holds<Issue>(), "ripple::toSTAmount : is Issue");
bool const isNeg = iou.signum() < 0;
std::uint64_t const umant = isNeg ? -iou.mantissa() : iou.mantissa();
return STAmount(iss, umant, iou.exponent(), isNeg, STAmount::unchecked());
return STAmount(asset, umant, iou.exponent(), isNeg, STAmount::unchecked());
}

inline STAmount
Expand All @@ -51,14 +53,25 @@ toSTAmount(XRPAmount const& xrp)
}

inline STAmount
toSTAmount(XRPAmount const& xrp, Issue const& iss)
toSTAmount(XRPAmount const& xrp, Asset const& asset)
{
XRPL_ASSERT(
isXRP(iss.account) && isXRP(iss.currency),
"ripple::toSTAmount : is XRP");
XRPL_ASSERT(isXRP(asset), "ripple::toSTAmount : is XRP");
return toSTAmount(xrp);
}

inline STAmount
toSTAmount(MPTAmount const& mpt)
{
return STAmount(mpt, noMPT());
}

inline STAmount
toSTAmount(MPTAmount const& mpt, Asset const& asset)
{
XRPL_ASSERT(asset.holds<MPTIssue>(), "ripple::toSTAmount : is MPT");
return STAmount(mpt, asset.get<MPTIssue>());
}

template <class T>
T
toAmount(STAmount const& amt) = delete;
Expand Down Expand Up @@ -100,6 +113,21 @@ toAmount<XRPAmount>(STAmount const& amt)
return XRPAmount(sMant);
}

template <>
inline MPTAmount
toAmount<MPTAmount>(STAmount const& amt)
{
XRPL_ASSERT(
amt.holds<MPTIssue>() && amt.mantissa() <= maxMPTokenAmount &&
amt.exponent() == 0,
"ripple::toAmount<MPTAmount> : maximum mantissa");
bool const isNeg = amt.negative();
std::int64_t const sMant =
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();

return MPTAmount(sMant);
}

template <class T>
T
toAmount(IOUAmount const& amt) = delete;
Expand All @@ -122,26 +150,39 @@ toAmount<XRPAmount>(XRPAmount const& amt)
return amt;
}

template <class T>
T
toAmount(MPTAmount const& amt) = delete;

template <>
inline MPTAmount
toAmount<MPTAmount>(MPTAmount const& amt)
{
return amt;
}

template <typename T>
T
toAmount(
Issue const& issue,
Asset const& asset,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
saveNumberRoundMode rm(Number::getround());
if (isXRP(issue))
if (isXRP(asset))
Number::setround(mode);

if constexpr (std::is_same_v<IOUAmount, T>)
return IOUAmount(n);
else if constexpr (std::is_same_v<XRPAmount, T>)
return XRPAmount(static_cast<std::int64_t>(n));
else if constexpr (std::is_same_v<MPTAmount, T>)
return MPTAmount(static_cast<std::int64_t>(n));
else if constexpr (std::is_same_v<STAmount, T>)
{
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(n));
return STAmount(issue, n.mantissa(), n.exponent());
if (isXRP(asset))
return STAmount(asset, static_cast<std::int64_t>(n));
return STAmount(asset, n.mantissa(), n.exponent());
}
else
{
Expand All @@ -152,18 +193,31 @@ toAmount(

template <typename T>
T
toMaxAmount(Issue const& issue)
toMaxAmount(Asset const& asset)
{
if constexpr (std::is_same_v<IOUAmount, T>)
return IOUAmount(STAmount::cMaxValue, STAmount::cMaxOffset);
else if constexpr (std::is_same_v<XRPAmount, T>)
return XRPAmount(static_cast<std::int64_t>(STAmount::cMaxNativeN));
else if constexpr (std::is_same_v<MPTAmount, T>)
return MPTAmount(maxMPTokenAmount);
else if constexpr (std::is_same_v<STAmount, T>)
{
if (isXRP(issue))
return STAmount(
issue, static_cast<std::int64_t>(STAmount::cMaxNativeN));
return STAmount(issue, STAmount::cMaxValue, STAmount::cMaxOffset);
return std::visit(
[]<ValidIssueType TIss>(TIss const& issue) {
if constexpr (std::is_same_v<TIss, Issue>)
{
if (isXRP(issue))
return STAmount(
issue,
static_cast<std::int64_t>(STAmount::cMaxNativeN));
return STAmount(
issue, STAmount::cMaxValue, STAmount::cMaxOffset);
}
else
return STAmount(issue, maxMPTokenAmount);
},
asset.value());
}
else
{
Expand All @@ -174,23 +228,25 @@ toMaxAmount(Issue const& issue)

inline STAmount
toSTAmount(
Issue const& issue,
Asset const& asset,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
return toAmount<STAmount>(issue, n, mode);
return toAmount<STAmount>(asset, n, mode);
}

template <typename T>
Issue
getIssue(T const& amt)
Asset
getAsset(T const& amt)
{
if constexpr (std::is_same_v<IOUAmount, T>)
return noIssue();
else if constexpr (std::is_same_v<XRPAmount, T>)
return xrpIssue();
else if constexpr (std::is_same_v<MPTAmount, T>)
return noMPT();
else if constexpr (std::is_same_v<STAmount, T>)
return amt.issue();
return amt.asset();
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
Expand All @@ -206,6 +262,8 @@ get(STAmount const& a)
return a.iou();
else if constexpr (std::is_same_v<XRPAmount, T>)
return a.xrp();
else if constexpr (std::is_same_v<MPTAmount, T>)
return a.mpt();
else if constexpr (std::is_same_v<STAmount, T>)
return a;
else
Expand Down
88 changes: 77 additions & 11 deletions include/xrpl/protocol/Asset.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,20 @@
#define RIPPLE_PROTOCOL_ASSET_H_INCLUDED

#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/Concepts.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>

namespace ripple {

class Asset;

template <typename TIss>
concept ValidIssueType =
std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;

template <typename A>
concept AssetType =
std::is_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
template <typename T>
requires(
std::is_same_v<T, XRPAmount> || std::is_same_v<T, IOUAmount> ||
std::is_same_v<T, MPTAmount>)
struct AmountType
{
using amount_type = T;
};

/* Asset is an abstraction of three different issue types: XRP, IOU, MPT.
* For historical reasons, two issue types XRP and IOU are wrapped in Issue
Expand All @@ -46,6 +45,10 @@ class Asset
{
public:
using value_type = std::variant<Issue, MPTIssue>;
using AmtType = std::variant<
AmountType<XRPAmount>,
AmountType<IOUAmount>,
AmountType<MPTAmount>>;

private:
value_type issue_;
Expand Down Expand Up @@ -92,12 +95,15 @@ class Asset
void
setJson(Json::Value& jv) const;

bool
constexpr bool
native() const
{
return holds<Issue>() && get<Issue>().native();
}

constexpr AmtType
getAmountType() const;

friend constexpr bool
operator==(Asset const& lhs, Asset const& rhs);

Expand Down Expand Up @@ -145,6 +151,22 @@ Asset::value() const
return issue_;
}

constexpr Asset::AmtType
Asset::getAmountType() const
{
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> AmtType {
constexpr AmountType<XRPAmount> xrp;
constexpr AmountType<IOUAmount> iou;
constexpr AmountType<MPTAmount> mpt;
if constexpr (std::is_same_v<TIss, Issue>)
return native() ? AmtType(xrp) : AmtType(iou);
else
return AmtType(mpt);
},
issue_);
}

constexpr bool
operator==(Asset const& lhs, Asset const& rhs)
{
Expand Down Expand Up @@ -222,6 +244,50 @@ assetFromJson(Json::Value const& jv);
Json::Value
to_json(Asset const& asset);

inline bool
isConsistent(Asset const& issue)
{
return std::visit(
[&]<typename TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, Issue>)
return isConsistent(issue_);
else
return true;
},
issue.value());
}

inline bool
validAsset(Asset const& issue)
{
return std::visit(
[&]<typename TIss>(TIss const& issue_) {
if constexpr (std::is_same_v<TIss, Issue>)
return isConsistent(issue_) && issue_.currency != badCurrency();
else
return true;
},
issue.value());
}

template <class Hasher>
void
hash_append(Hasher& h, Asset const& r)
{
using beast::hash_append;
std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) {
if constexpr (std::is_same_v<TIss, Issue>)
hash_append(h, issue);
else
hash_append(h, issue);
},
r.value());
}

std::ostream&
operator<<(std::ostream& os, Asset const& x);

} // namespace ripple

#endif // RIPPLE_PROTOCOL_ASSET_H_INCLUDED
Loading

0 comments on commit a827630

Please sign in to comment.