xrpld
Loading...
Searching...
No Matches
src/test/jtx/AMM.h
1#pragma once
2
3#include <test/jtx/Account.h>
4#include <test/jtx/Env.h>
5#include <test/jtx/multisign.h>
6#include <test/jtx/seq.h>
7#include <test/jtx/ter.h>
8
9#include <xrpld/rpc/GRPCHandlers.h>
10
11#include <xrpl/json/json_value.h>
12#include <xrpl/protocol/STAmount.h>
13#include <xrpl/protocol/TxFlags.h>
14
15#include <nudb/detail/stream.hpp>
16
17namespace xrpl::test::jtx {
18
20{
23
24public:
34 [[nodiscard]] STAmount
35 tokens() const
36 {
37 return STAmount{asset_, tokens_};
38 }
39 [[nodiscard]] STAmount
40 tokens(Issue const& ammIssue) const
41 {
42 return STAmount{ammIssue, tokens_};
43 }
44};
45
47{
48 bool log = false;
54 std::optional<Ter> err = std::nullopt;
55 bool close = true;
56};
57
71
84
94
104
114
117class AMM
118{
124 bool log_;
126 // Predict next purchase price
130 // Multi-signature
132 // Transaction fee
137
138public:
139 AMM(Env& env,
140 Account account,
141 STAmount asset1,
142 STAmount asset2,
143 bool log = false,
144 std::uint16_t tfee = 0,
145 std::uint32_t fee = 0,
146 std::optional<std::uint32_t> flags = std::nullopt,
147 std::optional<jtx::Seq> seq = std::nullopt,
148 std::optional<jtx::Msig> ms = std::nullopt,
149 std::optional<Ter> const& ter = std::nullopt,
150 bool close = true);
151 AMM(Env& env,
152 Account const& account,
153 STAmount const& asset1,
154 STAmount const& asset2,
155 Ter const& ter,
156 bool log = false,
157 bool close = true);
158 AMM(Env& env,
159 Account const& account,
160 STAmount const& asset1,
161 STAmount const& asset2,
162 CreateArg const& arg);
163
164 static json::Value
165 createJv(
166 AccountID const& account,
167 STAmount const& asset1,
168 STAmount const& asset2,
169 std::uint16_t const& tfee);
170
173 [[nodiscard]] json::Value
175 std::optional<AccountID> const& account = std::nullopt,
176 std::optional<std::string> const& ledgerIndex = std::nullopt,
177 std::optional<Asset> const& asset1 = std::nullopt,
178 std::optional<Asset> const& asset2 = std::nullopt,
179 std::optional<AccountID> const& ammAccount = std::nullopt,
180 bool ignoreParams = false,
181 unsigned apiVersion = RPC::kApiInvalidVersion) const;
182
183 [[nodiscard]] json::Value
185 std::optional<json::Value> const& account,
186 std::optional<std::string> const& ledgerIndex,
187 std::optional<Asset> const& asset1,
188 std::optional<Asset> const& asset2,
190 bool ignoreParams,
191 unsigned apiVersion) const;
192
195 [[nodiscard]] bool
197 STAmount const& asset1,
198 STAmount const& asset2,
199 IOUAmount const& lpt,
200 std::optional<AccountID> const& account = std::nullopt) const;
201
205 balances(
206 Asset const& asset1,
207 Asset const& asset2,
208 std::optional<AccountID> const& account = std::nullopt) const;
209
211 balances(std::optional<AccountID> const& account = std::nullopt) const
212 {
213 return balances(asset1_.asset(), asset2_.asset(), account);
214 }
215
216 [[nodiscard]] bool
217 expectLPTokens(AccountID const& account, IOUAmount const& tokens) const;
218
224 [[nodiscard]] bool
226 std::uint32_t fee,
228 IOUAmount expectedPrice) const;
229
230 [[nodiscard]] bool
231 expectAuctionSlot(std::vector<AccountID> const& authAccount) const;
232
233 [[nodiscard]] bool
235
236 [[nodiscard]] bool
238 STAmount const& asset1,
239 STAmount const& asset2,
240 IOUAmount const& balance,
241 std::optional<AccountID> const& account = std::nullopt,
242 std::optional<std::string> const& ledgerIndex = std::nullopt,
243 std::optional<AccountID> const& ammAccount = std::nullopt) const;
244
245 [[nodiscard]] bool
246 ammExists() const;
247
248 static json::Value
249 depositJv(DepositArg const& arg);
250
252 deposit(
253 std::optional<Account> const& account,
255 std::optional<STAmount> const& asset1InDetails = std::nullopt,
256 std::optional<std::uint32_t> const& flags = std::nullopt,
257 std::optional<Ter> const& ter = std::nullopt);
258
260 deposit(
261 std::optional<Account> const& account,
262 STAmount const& asset1InDetails,
263 std::optional<STAmount> const& asset2InAmount = std::nullopt,
264 std::optional<STAmount> const& maxEP = std::nullopt,
265 std::optional<std::uint32_t> const& flags = std::nullopt,
266 std::optional<Ter> const& ter = std::nullopt);
267
269 deposit(
270 std::optional<Account> const& account,
272 std::optional<STAmount> const& asset1In,
273 std::optional<STAmount> const& asset2In,
274 std::optional<STAmount> const& maxEP,
275 std::optional<std::uint32_t> const& flags,
277 std::optional<jtx::Seq> const& seq,
278 std::optional<std::uint16_t> const& tfee = std::nullopt,
279 std::optional<Ter> const& ter = std::nullopt);
280
282 deposit(DepositArg const& arg);
283
284 static json::Value
285 withdrawJv(WithdrawArg const& arg);
286
288 withdraw(
289 std::optional<Account> const& account,
291 std::optional<STAmount> const& asset1OutDetails = std::nullopt,
292 std::optional<std::uint32_t> const& flags = std::nullopt,
293 std::optional<Ter> const& ter = std::nullopt);
294
297 std::optional<Account> const& account,
298 std::optional<STAmount> const& asset1OutDetails = std::nullopt,
299 std::optional<Ter> const& ter = std::nullopt)
300 {
301 return withdraw(
302 account,
303 std::nullopt,
304 asset1OutDetails,
305 asset1OutDetails ? tfOneAssetWithdrawAll : tfWithdrawAll,
306 ter);
307 }
308
310 withdraw(
311 std::optional<Account> const& account,
312 STAmount const& asset1Out,
313 std::optional<STAmount> const& asset2Out = std::nullopt,
314 std::optional<LPToken> const& maxEP = std::nullopt,
315 std::optional<Ter> const& ter = std::nullopt);
316
318 withdraw(
319 std::optional<Account> const& account,
321 std::optional<STAmount> const& asset1Out,
322 std::optional<STAmount> const& asset2Out,
323 std::optional<LPToken> const& maxEP,
324 std::optional<std::uint32_t> const& flags,
326 std::optional<jtx::Seq> const& seq,
327 std::optional<Ter> const& ter = std::nullopt);
328
330 withdraw(WithdrawArg const& arg);
331
332 static json::Value
333 voteJv(VoteArg const& arg);
334
335 void
336 vote(
337 std::optional<Account> const& account,
338 std::uint32_t feeVal,
339 std::optional<std::uint32_t> const& flags = std::nullopt,
340 std::optional<jtx::Seq> const& seq = std::nullopt,
341 std::optional<std::pair<Asset, Asset>> const& assets = std::nullopt,
342 std::optional<Ter> const& ter = std::nullopt);
343
344 void
345 vote(VoteArg const& arg);
346
348 bid(BidArg const& arg);
349
350 void
351 clawback(ClawbackArg const& arg);
352
353 [[nodiscard]] AccountID const&
355 {
356 return ammAccount_;
357 }
358
359 [[nodiscard]] Issue
360 lptIssue() const
361 {
362 return lptIssue_;
363 }
364
365 [[nodiscard]] IOUAmount
366 tokens() const
367 {
368 return initialLPTokens_;
369 }
370
371 [[nodiscard]] IOUAmount
372 getLPTokensBalance(std::optional<AccountID> const& account = std::nullopt) const;
373
375 operator<<(std::ostream& s, AMM const& amm)
376 {
377 if (auto const res = amm.ammRpcInfo())
378 s << res.toStyledString();
379 return s;
380 }
381
383 operator[](AccountID const& lp) const
384 {
385 return ammRpcInfo(lp).toStyledString();
386 }
387
389 operator()(AccountID const& lp) const
390 {
391 return ammRpcInfo(lp);
392 }
393
394 static json::Value
395 deleteJv(AccountID const& account, Asset const& asset1, Asset const& assets);
396
397 void
398 ammDelete(AccountID const& account, std::optional<Ter> const& ter = std::nullopt);
399
400 void
401 setClose(bool close)
402 {
403 doClose_ = close;
404 }
405
406 [[nodiscard]] uint256
407 ammID() const
408 {
409 return ammID_;
410 }
411
412 void
413 setTokens(json::Value& jv, std::optional<std::pair<Asset, Asset>> const& assets = std::nullopt);
414
415 Asset const&
417 {
418 if (i > 1)
419 Throw<std::runtime_error>("AMM: operator[], invalid index");
420 return i == 0 ? asset1_.asset() : asset2_.asset();
421 }
422
423 struct Pool
424 {
425 AMM const& amm;
427 Pool(AMM const& a, std::vector<json::StaticString> const& n = {}) : amm(a), names(n)
428 {
429 }
431 operator<<(std::ostream& s, Pool const& p)
432 {
433 auto const& jr = p.amm.ammRpcInfo();
434 auto out = [&](json::Value const& jv) {
435 if (jv.isMember(jss::value))
436 {
437 std::cout << jv[jss::value].asString();
438 }
439 else
440 {
441 std::cout << jv.asString();
442 }
443 std::cout << " ";
444 };
445 if (p.names.empty())
446 {
447 out(jr[jss::amm][jss::amount]);
448 out(jr[jss::amm][jss::amount2]);
449 out(jr[jss::amm][jss::lp_token]);
450 }
451 else
452 {
453 for (auto const& n : p.names)
454 out(jr[jss::amm][n]);
455 }
457 return s;
458 }
459 };
460 struct Offers
461 {
463 Offers(json::Value const& j) : jv(j)
464 {
465 }
468 {
469 auto out = [&](json::Value const& jv) {
470 if (jv.isMember(jss::value))
471 {
472 s << jv[jss::value].asString();
473 }
474 else
475 {
476 s << jv;
477 }
478 };
479 for (auto const& o : offers.jv[jss::offers])
480 {
481 s << "taker_pays: ";
482 out(o[jss::taker_pays]);
483 s << " taker_gets: ";
484 out(o[jss::taker_gets]);
485 s << std::endl;
486 }
487 return s;
488 }
489 };
490
491private:
493 create(
494 std::uint32_t tfee = 0,
495 std::optional<std::uint32_t> const& flags = std::nullopt,
496 std::optional<jtx::Seq> const& seq = std::nullopt,
497 std::optional<Ter> const& ter = std::nullopt);
498
499 void
500 log(bool log)
501 {
502 log_ = log;
503 }
504
505 [[nodiscard]] bool
507 STAmount const& asset1,
508 STAmount const& asset2,
509 IOUAmount const& balance,
510 json::Value const& jv) const;
511
512 void
513 submit(
514 json::Value const& jv,
515 std::optional<jtx::Seq> const& seq,
516 std::optional<Ter> const& ter);
517
518 [[nodiscard]] bool
519 expectAuctionSlot(auto&& cb) const;
520
523};
524
525namespace amm {
526
529 Account const& issuer,
530 Account const& holder,
531 Asset const& asset,
532 Asset const& asset2,
533 std::optional<STAmount> const& amount);
534} // namespace amm
535
536} // namespace xrpl::test::jtx
Represents a JSON value.
Definition json_value.h:130
std::string toStyledString() const
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:24
A currency issued by an account.
Definition Issue.h:13
Number is a floating point type that can represent a wide range of values.
Definition Number.h:306
bool expectTradingFee(std::uint16_t fee) const
Definition AMM.cpp:340
bool expectAmmRpcInfo(STAmount const &asset1, STAmount const &asset2, IOUAmount const &balance, std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledgerIndex=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt) const
Definition AMM.cpp:354
json::Value bid(BidArg const &arg)
Definition AMM.cpp:737
IOUAmount getLPTokensBalance(std::optional< AccountID > const &account=std::nullopt) const
Definition AMM.cpp:282
std::optional< IOUAmount > bidMax_
static json::Value withdrawJv(WithdrawArg const &arg)
Definition AMM.cpp:557
AccountID create(std::uint32_t tfee=0, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< jtx::Seq > const &seq=std::nullopt, std::optional< Ter > const &ter=std::nullopt)
Definition AMM.cpp:153
AccountID const ammAccount_
bool ammExists() const
Definition AMM.cpp:347
IOUAmount withdrawAll(std::optional< Account > const &account, std::optional< STAmount > const &asset1OutDetails=std::nullopt, std::optional< Ter > const &ter=std::nullopt)
friend std::ostream & operator<<(std::ostream &s, AMM const &amm)
json::Value operator()(AccountID const &lp) const
static json::Value deleteJv(AccountID const &account, Asset const &asset1, Asset const &assets)
Definition AMM.cpp:896
bool expectAuctionSlot(std::uint32_t fee, std::optional< std::uint8_t > timeSlot, IOUAmount expectedPrice) const
Definition AMM.cpp:307
Asset const & operator[](std::uint8_t i)
IOUAmount tokens() const
IOUAmount withdraw(std::optional< Account > const &account, std::optional< LPToken > const &tokens, std::optional< STAmount > const &asset1OutDetails=std::nullopt, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< Ter > const &ter=std::nullopt)
Definition AMM.cpp:607
Account const creatorAccount_
std::uint32_t const fee_
void submit(json::Value const &jv, std::optional< jtx::Seq > const &seq, std::optional< Ter > const &ter)
Definition AMM.cpp:819
void ammDelete(AccountID const &account, std::optional< Ter > const &ter=std::nullopt)
Definition AMM.cpp:909
AccountID const & ammAccount() const
std::optional< Msig > const msig_
static json::Value createJv(AccountID const &account, STAmount const &asset1, STAmount const &asset2, std::uint16_t const &tfee)
Definition AMM.cpp:136
void setTokens(json::Value &jv, std::optional< std::pair< Asset, Asset > > const &assets=std::nullopt)
Definition AMM.cpp:395
void vote(std::optional< Account > const &account, std::uint32_t feeVal, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< jtx::Seq > const &seq=std::nullopt, std::optional< std::pair< Asset, Asset > > const &assets=std::nullopt, std::optional< Ter > const &ter=std::nullopt)
Definition AMM.cpp:711
std::tuple< STAmount, STAmount, STAmount > balances(std::optional< AccountID > const &account=std::nullopt) const
static json::Value voteJv(VoteArg const &arg)
Definition AMM.cpp:693
void setClose(bool close)
std::optional< IOUAmount > bidMin_
bool expectLPTokens(AccountID const &account, IOUAmount const &tokens) const
Definition AMM.cpp:296
bool expectAmmInfo(STAmount const &asset1, STAmount const &asset2, IOUAmount const &balance, json::Value const &jv) const
Definition AMM.cpp:367
IOUAmount initialTokens()
Definition AMM.cpp:52
AMM(Env &env, Account account, STAmount asset1, STAmount asset2, bool log=false, std::uint16_t tfee=0, std::uint32_t fee=0, std::optional< std::uint32_t > flags=std::nullopt, std::optional< jtx::Seq > seq=std::nullopt, std::optional< jtx::Msig > ms=std::nullopt, std::optional< Ter > const &ter=std::nullopt, bool close=true)
Definition AMM.cpp:62
void clawback(ClawbackArg const &arg)
Definition AMM.cpp:803
json::Value ammRpcInfo(std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledgerIndex=std::nullopt, std::optional< Asset > const &asset1=std::nullopt, std::optional< Asset > const &asset2=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt, bool ignoreParams=false, unsigned apiVersion=RPC::kApiInvalidVersion) const
Send amm_info RPC command.
Definition AMM.cpp:183
std::tuple< STAmount, STAmount, STAmount > balances(Asset const &asset1, Asset const &asset2, std::optional< AccountID > const &account=std::nullopt) const
Get AMM balances for the token pair.
Definition AMM.cpp:246
std::string operator[](AccountID const &lp) const
static json::Value depositJv(DepositArg const &arg)
Definition AMM.cpp:410
bool expectBalances(STAmount const &asset1, STAmount const &asset2, IOUAmount const &lpt, std::optional< AccountID > const &account=std::nullopt) const
Verify the AMM balances.
Definition AMM.cpp:269
IOUAmount const initialLPTokens_
Immutable cryptographic account descriptor.
Definition jtx/Account.h:17
A transaction testing environment.
Definition Env.h:143
STAmount tokens(Issue const &ammIssue) const
LPToken(std::uint64_t tokens)
LPToken(IOUAmount tokens)
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition ter.h:13
T empty(T... args)
T endl(T... args)
static constexpr auto kApiInvalidVersion
Definition ApiVersion.h:40
json::Value ammClawback(Account const &issuer, Account const &holder, Asset const &asset, Asset const &asset2, std::optional< STAmount > const &amount)
Definition AMM.cpp:920
Deposit preauthorize operations.
Definition deposit.h:7
OwnerCount< ltOFFER > offers
Match the number of offers in the account's owner directory.
Definition owners.h:70
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:97
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
BaseUInt< 256 > uint256
Definition base_uint.h:562
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:49
friend std::ostream & operator<<(std::ostream &s, Offers const &offers)
Offers(json::Value const &j)
std::vector< json::StaticString > names
friend std::ostream & operator<<(std::ostream &s, Pool const &p)
Pool(AMM const &a, std::vector< json::StaticString > const &n={})
std::optional< Account > account
std::optional< std::variant< int, IOUAmount, STAmount > > bidMin
std::vector< Account > authAccounts
std::optional< std::variant< int, IOUAmount, STAmount > > bidMax
std::optional< std::uint32_t > flags
std::optional< std::pair< Asset, Asset > > assets
std::optional< STAmount > amount
std::optional< std::uint32_t > flags
std::optional< std::pair< Asset, Asset > > assets
std::optional< Ter > err
std::optional< jtx::Msig > ms
std::optional< jtx::Seq > seq
std::optional< std::uint32_t > flags
std::optional< std::uint32_t > flags
std::optional< std::uint16_t > tfee
std::optional< LPToken > tokens
std::optional< STAmount > maxEP
std::optional< std::pair< Asset, Asset > > assets
std::optional< jtx::Seq > seq
std::optional< Account > account
std::optional< STAmount > asset2In
std::optional< STAmount > asset1In
std::optional< std::pair< Asset, Asset > > assets
std::optional< Ter > err
std::optional< jtx::Seq > seq
std::optional< Account > account
std::optional< std::uint32_t > flags
std::optional< STAmount > asset2Out
std::optional< jtx::Seq > seq
std::optional< std::pair< Asset, Asset > > assets
std::optional< LPToken > maxEP
std::optional< STAmount > asset1Out
std::optional< std::uint32_t > flags
std::optional< Account > account
std::optional< LPToken > tokens