mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-22 06:40:53 +00:00
fix: Assorted MPT/DEX fixes (#7299)
Co-authored-by: Valentin Balaschenko <13349202+vlntb@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
6ca2fb84d4
commit
26cc683ec1
@@ -226,7 +226,7 @@ getAMMOfferStartWithTakerGets(
|
||||
|
||||
auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerGets is XRP.
|
||||
// This has the most impact when takerGets is integral.
|
||||
auto const takerGets =
|
||||
toAmount<TOut>(getAsset(pool.out), nTakerGetsProposed, Number::RoundingMode::Downward);
|
||||
return TAmounts<TIn, TOut>{swapAssetOut(pool, takerGets, tfee), takerGets};
|
||||
@@ -294,7 +294,7 @@ getAMMOfferStartWithTakerPays(
|
||||
|
||||
auto getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerPays is XRP.
|
||||
// This has the most impact when takerPays is integral.
|
||||
auto const takerPays =
|
||||
toAmount<TIn>(getAsset(pool.in), nTakerPaysProposed, Number::RoundingMode::Downward);
|
||||
return TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||
@@ -313,11 +313,11 @@ getAMMOfferStartWithTakerPays(
|
||||
* is equal to LOB quality (in this case AMM offer quality is
|
||||
* better than LOB quality) or AMM offer is equal to LOB quality
|
||||
* (in this case SPQ is better than LOB quality).
|
||||
* Pre-amendment code calculates takerPays first. If takerGets is XRP,
|
||||
* it is rounded down, which results in worse offer quality than
|
||||
* LOB quality, and the offer might fail to generate.
|
||||
* Post-amendment code calculates the XRP offer side first. The result
|
||||
* is rounded down, which makes the offer quality better.
|
||||
* Pre-amendment code calculates takerPays first. If takerGets is the
|
||||
* economically coarser integral side, it is rounded down, which results in
|
||||
* worse offer quality than LOB quality, and the offer might fail to generate.
|
||||
* Post-amendment code calculates the economically coarser integral offer side
|
||||
* first. The result is rounded down, which makes the offer quality better.
|
||||
* It might not be possible to match either SPQ or AMM offer to LOB
|
||||
* quality. This generally happens at higher fees.
|
||||
* @param pool AMM pool balances
|
||||
@@ -396,10 +396,18 @@ changeSpotPriceQuality(
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Generate the offer starting with XRP side. Return seated offer amounts
|
||||
// if the offer can be generated, otherwise nullopt.
|
||||
auto amounts = [&]() {
|
||||
if (isXRP(getAsset(pool.out)))
|
||||
bool const inIntegral = getAsset(pool.in).integral();
|
||||
bool const outIntegral = getAsset(pool.out).integral();
|
||||
|
||||
// Preserve historical behavior for fractional pairs and XRP/IOU-style
|
||||
// one-integral-side pairs. For two integral assets, pick the side whose
|
||||
// minimum unit is economically coarser at this quality.
|
||||
//
|
||||
// Quality::rate() is input units per output unit, so one output unit is
|
||||
// coarser when it costs at least one input unit. Ties use takerGets,
|
||||
// matching the historical XRP-output behavior.
|
||||
if (outIntegral && (!inIntegral || Number(quality.rate()) >= 1))
|
||||
return getAMMOfferStartWithTakerGets(pool, quality, tfee);
|
||||
return getAMMOfferStartWithTakerPays(pool, quality, tfee);
|
||||
}();
|
||||
|
||||
@@ -261,6 +261,14 @@ checkCreateMPT(
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
SLE::ref sponsorSle,
|
||||
std::uint32_t flags,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
checkCreateMPT(
|
||||
xrpl::ApplyView& view,
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
beast::Journal j);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -154,7 +154,7 @@ T
|
||||
toAmount(Asset const& asset, Number const& n, Number::RoundingMode mode = Number::getround())
|
||||
{
|
||||
SaveNumberRoundMode const rm(Number::getround());
|
||||
if (isXRP(asset))
|
||||
if (asset.integral())
|
||||
Number::setround(mode);
|
||||
|
||||
if constexpr (std::is_same_v<IOUAmount, T>)
|
||||
|
||||
@@ -60,6 +60,15 @@ public:
|
||||
std::optional<Number>
|
||||
outFromAvgQ(Quality const& quality);
|
||||
|
||||
/**
|
||||
* Return whether `out` produces at least the requested
|
||||
* average quality.
|
||||
* @param quality requested average quality (quality limit)
|
||||
* @param out output amount to test
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
satisfiesAvgQ(Quality const& quality, Number const& out) const;
|
||||
|
||||
/**
|
||||
* Return true if the quality function is constant
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
@@ -373,7 +374,7 @@ qualityUpperBound(ReadView const& v, Strand const& strand)
|
||||
* increases quality of AMM steps, increasing the strand's composite
|
||||
* quality as the result.
|
||||
*/
|
||||
template <typename TOutAmt>
|
||||
template <StepAmount TOutAmt>
|
||||
inline TOutAmt
|
||||
limitOut(
|
||||
ReadView const& v,
|
||||
@@ -411,21 +412,29 @@ limitOut(
|
||||
auto const out = qf->outFromAvgQ(limitQuality);
|
||||
if (!out)
|
||||
return remainingOut;
|
||||
if constexpr (std::is_same_v<TOutAmt, XRPAmount>)
|
||||
if constexpr (std::is_same_v<TOutAmt, XRPAmount> || std::is_same_v<TOutAmt, MPTAmount>)
|
||||
{
|
||||
return XRPAmount{*out};
|
||||
auto const roundedOut = TOutAmt{*out};
|
||||
// Integral outputs that round above the continuous target can
|
||||
// realize worse average quality than the requested limit. Keep the
|
||||
// default rounded value when it still satisfies the limit, since it
|
||||
// is the largest matching offer; otherwise round down.
|
||||
if (v.rules().enabled(featureMPTokensV2) && roundedOut > *out &&
|
||||
!qf->satisfiesAvgQ(limitQuality, roundedOut))
|
||||
{
|
||||
NumberRoundModeGuard const g(Number::RoundingMode::Downward);
|
||||
return TOutAmt{*out};
|
||||
}
|
||||
return roundedOut;
|
||||
}
|
||||
else if constexpr (std::is_same_v<TOutAmt, IOUAmount>)
|
||||
{
|
||||
return IOUAmount{*out};
|
||||
}
|
||||
else if constexpr (std::is_same_v<TOutAmt, MPTAmount>)
|
||||
{
|
||||
return MPTAmount{*out};
|
||||
}
|
||||
else
|
||||
{
|
||||
return STAmount{remainingOut.asset(), out->mantissa(), out->exponent()};
|
||||
static constexpr bool kAlwaysFalse = !std::is_same_v<TOutAmt, TOutAmt>;
|
||||
static_assert(kAlwaysFalse, "Unhandled StepAmount type");
|
||||
}
|
||||
}();
|
||||
// A tiny difference could be due to the round off
|
||||
|
||||
@@ -118,6 +118,7 @@ public:
|
||||
Sandbox& view,
|
||||
SLE const& ammSle,
|
||||
AccountID const account,
|
||||
std::optional<AccountID> const& clawbackIssuer,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
STAmount const& amount2Balance,
|
||||
@@ -138,6 +139,11 @@ public:
|
||||
* @param view
|
||||
* @param ammSle AMM ledger entry
|
||||
* @param ammAccount AMM account
|
||||
* @param clawbackIssuer when set (AMMClawback path), the issuer performing
|
||||
* the clawback. A recreated MPToken is only auto-authorized when the
|
||||
* asset's issuer matches this account, so a clawback cannot grant
|
||||
* authorization on behalf of a different (paired-asset) issuer.
|
||||
* @param account LP account
|
||||
* @param amountBalance current LP asset1 balance
|
||||
* @param amountWithdraw asset1 withdraw amount
|
||||
* @param amount2Withdraw asset2 withdraw amount
|
||||
@@ -153,6 +159,7 @@ public:
|
||||
Sandbox& view,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
std::optional<AccountID> const& clawbackIssuer,
|
||||
AccountID const& account,
|
||||
STAmount const& amountBalance,
|
||||
STAmount const& amountWithdraw,
|
||||
|
||||
Reference in New Issue
Block a user