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 Dec 23, 2024
1 parent 49e0d54 commit 7c611fe
Show file tree
Hide file tree
Showing 116 changed files with 6,539 additions and 2,479 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& issue1, Asset const& issue2);

/** Calculate LPT Issue from AMM asset pair.
*/
Issue
ammLPTIssue(
Currency const& cur1,
Currency const& cur2,
Asset const& issue1,
Asset const& issue2,
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& issue,
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& issue1,
Asset const& issue2,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);

/** Get time slot of the auction slot.
*/
Expand Down
87 changes: 72 additions & 15 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,8 +30,9 @@
namespace ripple {

inline STAmount
toSTAmount(IOUAmount const& iou, Issue const& iss)
toSTAmount(IOUAmount const& iou, Asset const& iss)
{
XRPL_ASSERT(iss.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());
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& iss)
{
XRPL_ASSERT(
isXRP(iss.account) && isXRP(iss.currency),
"ripple::toSTAmount : is XRP");
XRPL_ASSERT(isXRP(iss), "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& iss)
{
XRPL_ASSERT(iss.holds<MPTIssue>(), "ripple::toSTAmount : is MPT");
return STAmount(mpt, iss.get<MPTIssue>());
}

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

template <>
inline MPTAmount
toAmount<MPTAmount>(STAmount const& amt)
{
XRPL_ASSERT(
amt.holds<MPTIssue>() && amt.mantissa() <= maxMPTokenAmount,
"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,10 +149,21 @@ 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& issue,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
Expand All @@ -137,6 +175,8 @@ toAmount(
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))
Expand All @@ -152,18 +192,31 @@ toAmount(

template <typename T>
T
toMaxAmount(Issue const& issue)
toMaxAmount(Asset const& issue)
{
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);
},
issue.value());
}
else
{
Expand All @@ -174,23 +227,25 @@ toMaxAmount(Issue const& issue)

inline STAmount
toSTAmount(
Issue const& issue,
Asset const& issue,
Number const& n,
Number::rounding_mode mode = Number::getround())
{
return toAmount<STAmount>(issue, 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 +261,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
75 changes: 65 additions & 10 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 Down Expand Up @@ -68,6 +67,12 @@ class Asset
{
}

explicit
operator Issue() const;

explicit
operator MPTIssue() const;

AccountID const&
getIssuer() const;

Expand Down Expand Up @@ -98,6 +103,12 @@ class Asset
return holds<Issue>() && get<Issue>().native();
}

std::variant<
AmountType<XRPAmount>,
AmountType<IOUAmount>,
AmountType<MPTAmount>>
getAmountType() const;

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

Expand Down Expand Up @@ -222,6 +233,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 7c611fe

Please sign in to comment.