2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/amount.h>
6#include <xrpl/beast/unit_test/suite.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/ledger/helpers/AMMHelpers.h>
9#include <xrpl/protocol/AmountConversions.h>
10#include <xrpl/protocol/IOUAmount.h>
11#include <xrpl/protocol/Quality.h>
12#include <xrpl/protocol/STAmount.h>
13#include <xrpl/protocol/UintTypes.h>
14#include <xrpl/protocol/XRPAmount.h>
16#include <boost/regex/v5/regex.hpp>
17#include <boost/regex/v5/regex_replace.hpp>
18#include <boost/regex/v5/regex_search.hpp>
19#include <boost/regex/v5/regex_token_iterator.hpp>
60 str = boost::regex_replace(str, boost::regex(
"^(A|O)[(]"),
"");
63 boost::regex
const rx(
"^([^(]+)[(]([^)]+)[)]([)])?$");
64 if (boost::regex_search(str, match, rx))
66 if (delimited !=
nullptr)
67 *delimited = (match[3] !=
"");
68 if (match[1] ==
"XRP")
73 if (match[1] ==
"XRPA")
88 str = boost::regex_replace(str, boost::regex(
"^T[(]"),
"");
91 boost::regex
const rx(
"^([^(]+)[(]([^)]+)[)]([)])?$");
92 if (boost::regex_search(str, match, rx))
98 return {{currency,
rate, match[3] !=
""}};
120 bool const amm = s[0] !=
'O';
121 auto const a1 =
getAmt(p++);
122 if (!a1 || p ==
end_)
124 auto const a2 =
getAmt(p++);
127 return {{{*a1, *a2},
amm}};
163 auto isPair = [](
auto const& p) {
165 return s[0] ==
'A' || s[0] ==
'O';
171 if (!res || p ==
end_)
176 auto const swap =
getAmt(p++);
183 auto const fee =
getFee(p);
184 return {{pairs, *swap, *
rate, fee}};
207 auto const vp = std::get<steps>(args);
208 STAmount sout = std::get<STAmount>(args);
209 auto const fee = std::get<std::uint32_t>(args);
210 auto const rates = std::get<transfer_rates>(args);
214 int limitingStep = vp.size();
218 return rates.contains(currency) ? rates.at(currency) : QUALITY_ONE;
222 for (
auto it = vp.rbegin(); it != vp.rend(); ++it)
225 auto const [amts,
amm] = *it;
231 else if (sout <= amts.out)
239 limitingStep = vp.rend() - it - 1;
241 if (it == vp.rbegin())
242 resultOut = amts.out;
248 for (
int i = limitingStep + 1; i < vp.size(); ++i)
250 auto const [amts,
amm] = vp[i];
270 auto const vp = std::get<steps>(args);
271 STAmount sin = std::get<STAmount>(args);
272 auto const fee = std::get<std::uint32_t>(args);
273 auto const rates = std::get<transfer_rates>(args);
277 int limitingStep = 0;
281 return rates.contains(currency) ? rates.at(currency) : QUALITY_ONE;
284 for (
auto it = vp.begin(); it != vp.end(); ++it)
286 auto const [amts,
amm] = *it;
294 else if (sin <= amts.in)
303 limitingStep = it - vp.begin();
311 for (
int i = limitingStep - 1; i >= 0; --i)
314 auto const [amts,
amm] = vp[i];
334 auto const a =
arg();
335 boost::regex
const re(
",");
353 auto const exec = [&]() ->
bool {
368 if (
auto const swap =
getSwap(++p); swap)
383 else if (*p ==
"swapout")
385 if (
auto const swap =
getSwap(++p); swap)
395 else if (*p ==
"lptokens")
400 auto const lpt =
amm[
"LPT"];
415 else if (*p ==
"changespq")
417 Env const env(*
this);
422 auto const fee =
getFee(p);
433 <<
"\nnew pool: " <<
toString(pool->first.in + ammOffer->in)
434 <<
" " <<
toString(pool->first.out - ammOffer->out)
A generic endpoint for log messages.
static Sink & getNullSink()
Returns a Sink which does nothing.
std::string const & arg() const
Return the argument associated with the runner.
A currency issued by an account.
Represents the logical ratio of output currency to input currency.
Amounts ceilOut(Amounts const &amount, STAmount const &limit) const
Returns the scaled amount with out capped.
Amounts ceilIn(Amounts const &amount, STAmount const &limit) const
Returns the scaled amount with in capped.
constexpr TIss const & get() const
std::string getText() const override
bool native() const noexcept
Asset const & asset() const
std::optional< std::tuple< std::string, std::uint32_t, bool > > getRate(token_iter const &p)
static STAmount mulratio(STAmount const &amt, std::uint32_t a, std::uint32_t b, bool round)
std::optional< std::pair< Amounts, bool > > getAmounts(token_iter &p)
static void swapIn(swapargs const &args)
std::tuple< steps, STAmount, transfer_rates, std::uint32_t > swapargs
boost::sregex_token_iterator token_iter
std::map< std::string, std::uint32_t > transfer_rates
static void swapOut(swapargs const &args)
static std::string toString(STAmount const &a)
std::optional< STAmount > getAmt(token_iter const &p, bool *delimited=nullptr)
std::vector< std::pair< Amounts, bool > > steps
void run() override
Runs the suite.
std::optional< swapargs > getSwap(token_iter &p)
std::uint32_t getFee(token_iter const &p)
std::optional< transfer_rates > getTransferRate(token_iter &p)
Immutable cryptographic account descriptor.
A transaction testing environment.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
XrpT const XRP
Converts to XRP Issue or STAmount.
json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
BEAST_DEFINE_TESTSUITE_MANUAL(AMMCalc, app, xrpl)
constexpr XRPAmount
Convert XRP to drops (integral types).
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Asset const &lptIssue)
Calculate LP Tokens given AMM pool reserves.
static void limitStepOut(Offer const &offer, TAmounts< TIn, TOut > &ofrAmt, TAmounts< TIn, TOut > &stpAmt, TOut &ownerGives, std::uint32_t transferRateIn, std::uint32_t transferRateOut, TOut const &limit)
STAmount amountFromString(Asset const &asset, std::string const &amount)
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) ...
static void limitStepIn(Offer const &offer, TAmounts< TIn, TOut > &ofrAmt, TAmounts< TIn, TOut > &stpAmt, TOut &ownerGives, std::uint32_t transferRateIn, std::uint32_t transferRateOut, TIn const &limit)
std::string to_string(BaseUInt< Bits, Tag > const &a)
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
std::optional< TAmounts< TIn, TOut > > changeSpotPriceQuality(TAmounts< TIn, TOut > const &pool, Quality const &quality, std::uint16_t tfee, Rules const &rules, beast::Journal j)
Generate AMM offer so that either updated Spot Price Quality (SPQ) is equal to LOB quality (in this c...
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.
STAmount toSTAmount(IOUAmount const &iou, Asset const &asset)