rippled
Loading...
Searching...
No Matches
AMMOffer.cpp
1#include <xrpld/app/paths/AMMLiquidity.h>
2#include <xrpld/app/paths/AMMOffer.h>
3
4#include <xrpl/protocol/QualityFunction.h>
5
6namespace ripple {
7
8template <typename TIn, typename TOut>
10 AMMLiquidity<TIn, TOut> const& ammLiquidity,
11 TAmounts<TIn, TOut> const& amounts,
12 TAmounts<TIn, TOut> const& balances,
13 Quality const& quality)
14 : ammLiquidity_(ammLiquidity)
15 , amounts_(amounts)
16 , balances_(balances)
17 , quality_(quality)
18 , consumed_(false)
19{
20}
21
22template <typename TIn, typename TOut>
23Issue const&
25{
26 return ammLiquidity_.issueIn();
27}
28
29template <typename TIn, typename TOut>
30AccountID const&
32{
33 return ammLiquidity_.ammAccount();
34}
35
36template <typename TIn, typename TOut>
37TAmounts<TIn, TOut> const&
39{
40 return amounts_;
41}
42
43template <typename TIn, typename TOut>
44void
46 ApplyView& view,
47 TAmounts<TIn, TOut> const& consumed)
48{
49 // Consumed offer must be less or equal to the original
50 if (consumed.in > amounts_.in || consumed.out > amounts_.out)
51 Throw<std::logic_error>("Invalid consumed AMM offer.");
52 // AMM pool is updated when the amounts are transferred
53 // in BookStep::consumeOffer().
54
55 consumed_ = true;
56
57 // Let the context know AMM offer is consumed
58 ammLiquidity_.context().setAMMUsed();
59}
60
61template <typename TIn, typename TOut>
62TAmounts<TIn, TOut>
64 TAmounts<TIn, TOut> const& offrAmt,
65 TOut const& limit,
66 bool roundUp) const
67{
68 // Change the offer size proportionally to the original offer quality
69 // to keep the strands quality order unchanged. The taker pays slightly
70 // more for the offer in this case, which results in a slightly higher
71 // pool product than the original pool product. I.e. if the original
72 // pool is poolPays, poolGets and the offer is assetIn, assetOut then
73 // poolPays * poolGets < (poolPays - assetOut) * (poolGets + assetIn)
74 if (ammLiquidity_.multiPath())
75 {
76 // It turns out that the ceil_out implementation has some slop in
77 // it, which ceil_out_strict removes.
78 return quality().ceil_out_strict(offrAmt, limit, roundUp);
79 }
80 // Change the offer size according to the conservation function. The offer
81 // quality is increased in this case, but it doesn't matter since there is
82 // only one path.
83 return {swapAssetOut(balances_, limit, ammLiquidity_.tradingFee()), limit};
84}
85
86template <typename TIn, typename TOut>
87TAmounts<TIn, TOut>
89 TAmounts<TIn, TOut> const& offrAmt,
90 TIn const& limit,
91 bool roundUp) const
92{
93 // See the comments above in limitOut().
94 if (ammLiquidity_.multiPath())
95 {
96 if (auto const& rules = getCurrentTransactionRules();
97 rules && rules->enabled(fixReducedOffersV2))
98 return quality().ceil_in_strict(offrAmt, limit, roundUp);
99
100 return quality().ceil_in(offrAmt, limit);
101 }
102 return {limit, swapAssetIn(balances_, limit, ammLiquidity_.tradingFee())};
103}
104
105template <typename TIn, typename TOut>
108{
109 if (ammLiquidity_.multiPath())
111 return QualityFunction{
112 balances_, ammLiquidity_.tradingFee(), QualityFunction::AMMTag{}};
113}
114
115template <typename TIn, typename TOut>
116bool
118 TAmounts<TIn, TOut> const& consumed,
119 beast::Journal j) const
120{
121 if (consumed.in > amounts_.in || consumed.out > amounts_.out)
122 {
123 JLOG(j.error()) << "AMMOffer::checkInvariant failed: consumed "
124 << to_string(consumed.in) << " "
125 << to_string(consumed.out) << " amounts "
126 << to_string(amounts_.in) << " "
127 << to_string(amounts_.out);
128
129 return false;
130 }
131
132 Number const product = balances_.in * balances_.out;
133 auto const newBalances = TAmounts<TIn, TOut>{
134 balances_.in + consumed.in, balances_.out - consumed.out};
135 Number const newProduct = newBalances.in * newBalances.out;
136
137 if (newProduct >= product ||
138 withinRelativeDistance(product, newProduct, Number{1, -7}))
139 return true;
140
141 JLOG(j.error()) << "AMMOffer::checkInvariant failed: balances "
142 << to_string(balances_.in) << " "
143 << to_string(balances_.out) << " new balances "
144 << to_string(newBalances.in) << " "
145 << to_string(newBalances.out) << " product/newProduct "
146 << product << " " << newProduct << " diff "
147 << (product != Number{0}
148 ? to_string((product - newProduct) / product)
149 : "undefined");
150 return false;
151}
152
153template class AMMOffer<STAmount, STAmount>;
154template class AMMOffer<IOUAmount, IOUAmount>;
155template class AMMOffer<XRPAmount, IOUAmount>;
156template class AMMOffer<IOUAmount, XRPAmount>;
157
158} // namespace ripple
A generic endpoint for log messages.
Definition Journal.h:41
Stream error() const
Definition Journal.h:327
AMMLiquidity class provides AMM offers to BookStep class.
Represents synthetic AMM offer in BookStep.
Definition AMMOffer.h:21
AMMOffer(AMMLiquidity< TIn, TOut > const &ammLiquidity, TAmounts< TIn, TOut > const &amounts, TAmounts< TIn, TOut > const &balances, Quality const &quality)
Definition AMMOffer.cpp:9
AccountID const & owner() const
Definition AMMOffer.cpp:31
TAmounts< TIn, TOut > limitOut(TAmounts< TIn, TOut > const &offrAmt, TOut const &limit, bool roundUp) const
Limit out of the provided offer.
Definition AMMOffer.cpp:63
bool checkInvariant(TAmounts< TIn, TOut > const &consumed, beast::Journal j) const
Check the new pool product is greater or equal to the old pool product or if decreases then within so...
Definition AMMOffer.cpp:117
void consume(ApplyView &view, TAmounts< TIn, TOut > const &consumed)
Definition AMMOffer.cpp:45
TAmounts< TIn, TOut > limitIn(TAmounts< TIn, TOut > const &offrAmt, TIn const &limit, bool roundUp) const
Limit in of the provided offer.
Definition AMMOffer.cpp:88
Issue const & issueIn() const
Definition AMMOffer.cpp:24
TAmounts< TIn, TOut > const & amount() const
Definition AMMOffer.cpp:38
QualityFunction getQualityFunc() const
Definition AMMOffer.cpp:107
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:124
A currency issued by an account.
Definition Issue.h:14
Average quality of a path as a function of out: q(out) = m * out + b, where m = -1 / poolGets,...
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
TOut swapAssetIn(TAmounts< TIn, TOut > const &pool, TIn const &assetIn, std::uint16_t tfee)
AMM pool invariant - the product (A * B) after swap in/out has to remain at least the same: (A + in) ...
Definition AMMHelpers.h:445
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
std::optional< Rules > const & getCurrentTransactionRules()
Definition Rules.cpp:28
bool withinRelativeDistance(Quality const &calcQuality, Quality const &reqQuality, Number const &dist)
Check if the relative distance between the qualities is within the requested distance.
Definition AMMHelpers.h:110
TIn swapAssetOut(TAmounts< TIn, TOut > const &pool, TOut const &assetOut, std::uint16_t tfee)
Swap assetOut out of the pool and swap in a proportional amount of the other asset.
Definition AMMHelpers.h:518