mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Fix offer crossing via single path AMM with transfer fee:
Single path AMM offer has to factor in the transfer in rate when calculating the upper bound quality and the quality function because single path AMM's offer quality is not constant. This fix factors in the transfer fee in BookStep::adjustQualityWithFees().
This commit is contained in:
@@ -275,6 +275,7 @@ public:
|
||||
|
||||
using BookStep<TIn, TOut, BookPaymentStep<TIn, TOut>>::BookStep;
|
||||
using BookStep<TIn, TOut, BookPaymentStep<TIn, TOut>>::qualityUpperBound;
|
||||
using typename BookStep<TIn, TOut, BookPaymentStep<TIn, TOut>>::OfferType;
|
||||
|
||||
// Never limit self cross quality on a payment.
|
||||
template <template <typename, typename> typename Offer>
|
||||
@@ -328,7 +329,9 @@ public:
|
||||
ReadView const& v,
|
||||
Quality const& ofrQ,
|
||||
DebtDirection prevStepDir,
|
||||
WaiveTransferFee waiveFee) const
|
||||
WaiveTransferFee waiveFee,
|
||||
OfferType,
|
||||
Rules const&) const
|
||||
{
|
||||
// Charge the offer owner, not the sender
|
||||
// Charge a fee even if the owner is the same as the issuer
|
||||
@@ -368,6 +371,8 @@ class BookOfferCrossingStep
|
||||
{
|
||||
using BookStep<TIn, TOut, BookOfferCrossingStep<TIn, TOut>>::
|
||||
qualityUpperBound;
|
||||
using typename BookStep<TIn, TOut, BookOfferCrossingStep<TIn, TOut>>::
|
||||
OfferType;
|
||||
|
||||
private:
|
||||
// Helper function that throws if the optional passed to the constructor
|
||||
@@ -513,7 +518,9 @@ public:
|
||||
ReadView const& v,
|
||||
Quality const& ofrQ,
|
||||
DebtDirection prevStepDir,
|
||||
WaiveTransferFee waiveFee) const
|
||||
WaiveTransferFee waiveFee,
|
||||
OfferType offerType,
|
||||
Rules const& rules) const
|
||||
{
|
||||
// Offer x-ing does not charge a transfer fee when the offer's owner
|
||||
// is the same as the strand dst. It is important that
|
||||
@@ -521,7 +528,30 @@ public:
|
||||
// ignore strands whose quality cannot meet a minimum threshold). When
|
||||
// calculating quality assume no fee is charged, or the estimate will no
|
||||
// longer be an upper bound.
|
||||
return ofrQ;
|
||||
|
||||
// Single path AMM offer has to factor in the transfer in rate
|
||||
// when calculating the upper bound quality and the quality function
|
||||
// because single path AMM's offer quality is not constant.
|
||||
if (!rules.enabled(fixAMMRounding))
|
||||
return ofrQ;
|
||||
else if (
|
||||
offerType == OfferType::CLOB ||
|
||||
(this->ammLiquidity_ && this->ammLiquidity_->multiPath()))
|
||||
return ofrQ;
|
||||
|
||||
auto rate = [&](AccountID const& id) {
|
||||
if (isXRP(id) || id == this->strandDst_)
|
||||
return parityRate;
|
||||
return transferRate(v, id);
|
||||
};
|
||||
|
||||
auto const trIn =
|
||||
redeems(prevStepDir) ? rate(this->book_.in.account) : parityRate;
|
||||
// AMM doesn't pay the transfer fee on the out amount
|
||||
auto const trOut = parityRate;
|
||||
|
||||
Quality const q1{getRate(STAmount(trOut.value), STAmount(trIn.value))};
|
||||
return composed_quality(q1, ofrQ);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -563,7 +593,12 @@ BookStep<TIn, TOut, TDerived>::qualityUpperBound(
|
||||
: WaiveTransferFee::No;
|
||||
|
||||
Quality const q = static_cast<TDerived const*>(this)->adjustQualityWithFees(
|
||||
v, std::get<Quality>(*res), prevStepDir, waiveFee);
|
||||
v,
|
||||
std::get<Quality>(*res),
|
||||
prevStepDir,
|
||||
waiveFee,
|
||||
std::get<OfferType>(*res),
|
||||
v.rules());
|
||||
return {q, dir};
|
||||
}
|
||||
|
||||
@@ -585,7 +620,12 @@ BookStep<TIn, TOut, TDerived>::getQualityFunc(
|
||||
auto static const qOne = Quality{STAmount::uRateOne};
|
||||
auto const q =
|
||||
static_cast<TDerived const*>(this)->adjustQualityWithFees(
|
||||
v, qOne, prevStepDir, WaiveTransferFee::Yes);
|
||||
v,
|
||||
qOne,
|
||||
prevStepDir,
|
||||
WaiveTransferFee::Yes,
|
||||
OfferType::AMM,
|
||||
v.rules());
|
||||
if (q == qOne)
|
||||
return {res, dir};
|
||||
QualityFunction qf{q, QualityFunction::CLOBLikeTag{}};
|
||||
@@ -595,7 +635,12 @@ BookStep<TIn, TOut, TDerived>::getQualityFunc(
|
||||
|
||||
// CLOB
|
||||
Quality const q = static_cast<TDerived const*>(this)->adjustQualityWithFees(
|
||||
v, *(res->quality()), prevStepDir, WaiveTransferFee::No);
|
||||
v,
|
||||
*(res->quality()),
|
||||
prevStepDir,
|
||||
WaiveTransferFee::No,
|
||||
OfferType::CLOB,
|
||||
v.rules());
|
||||
return {QualityFunction{q, QualityFunction::CLOBLikeTag{}}, dir};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user