rippled
AMM.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2023 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <test/jtx/AMM.h>
21 
22 #include <ripple/app/misc/AMMUtils.h>
23 #include <ripple/protocol/AMMCore.h>
24 #include <ripple/protocol/AmountConversions.h>
25 #include <ripple/protocol/jss.h>
26 #include <ripple/rpc/impl/RPCHelpers.h>
27 #include <test/jtx/Env.h>
28 
29 namespace ripple {
30 namespace test {
31 namespace jtx {
32 
33 static Number
34 number(STAmount const& a)
35 {
36  if (isXRP(a))
37  return a.xrp();
38  return a;
39 }
40 
41 static IOUAmount
42 initialTokens(STAmount const& asset1, STAmount const& asset2)
43 {
44  auto const product = number(asset1) * number(asset2);
45  return (IOUAmount)(
46  product.mantissa() >= 0 ? root2(product) : root2(-product));
47 }
48 
50  Env& env,
51  Account const& account,
52  STAmount const& asset1,
53  STAmount const& asset2,
54  bool log,
55  std::uint16_t tfee,
60  std::optional<ter> const& ter)
61  : env_(env)
62  , creatorAccount_(account)
63  , asset1_(asset1)
64  , asset2_(asset2)
65  , ammID_(keylet::amm(asset1_.issue(), asset2_.issue()).key)
66  , initialLPTokens_(initialTokens(asset1, asset2))
67  , log_(log)
68  , doClose_(true)
69  , lastPurchasePrice_(0)
70  , bidMin_()
71  , bidMax_()
72  , msig_(ms)
73  , fee_(fee)
74  , ammAccount_(create(tfee, flags, seq, ter))
75  , lptIssue_(ripple::ammLPTIssue(
76  asset1_.issue().currency,
77  asset2_.issue().currency,
78  ammAccount_))
79 {
80 }
81 
83  Env& env,
84  Account const& account,
85  STAmount const& asset1,
86  STAmount const& asset2,
87  ter const& ter,
88  bool log)
89  : AMM(env,
90  account,
91  asset1,
92  asset2,
93  log,
94  0,
95  0,
96  std::nullopt,
97  std::nullopt,
98  std::nullopt,
99  ter)
100 {
101 }
102 
103 [[nodiscard]] AccountID
105  std::uint32_t tfee,
108  std::optional<ter> const& ter)
109 {
110  Json::Value jv;
111  jv[jss::Account] = creatorAccount_.human();
112  jv[jss::Amount] = asset1_.getJson(JsonOptions::none);
113  jv[jss::Amount2] = asset2_.getJson(JsonOptions::none);
114  jv[jss::TradingFee] = tfee;
115  jv[jss::TransactionType] = jss::AMMCreate;
116  if (flags)
117  jv[jss::Flags] = *flags;
118  if (fee_ != 0)
119  jv[jss::Fee] = std::to_string(fee_);
120  else
121  jv[jss::Fee] = std::to_string(env_.current()->fees().increment.drops());
122  submit(jv, seq, ter);
123 
124  if (!ter || env_.ter() == tesSUCCESS)
125  {
126  if (auto const amm = env_.current()->read(
128  {
129  return amm->getAccountID(sfAccount);
130  }
131  }
132  return {};
133 }
134 
137  std::optional<AccountID> const& account,
138  std::optional<std::string> const& ledgerIndex,
139  std::optional<Issue> issue1,
140  std::optional<Issue> issue2,
141  std::optional<AccountID> const& ammAccount,
142  bool ignoreParams) const
143 {
144  Json::Value jv;
145  if (account)
146  jv[jss::account] = to_string(*account);
147  if (ledgerIndex)
148  jv[jss::ledger_index] = *ledgerIndex;
149  if (!ignoreParams)
150  {
151  if (issue1 || issue2)
152  {
153  if (issue1)
154  jv[jss::asset] =
156  if (issue2)
157  jv[jss::asset2] =
159  }
160  else if (!ammAccount)
161  {
162  jv[jss::asset] =
164  jv[jss::asset2] =
166  }
167  if (ammAccount)
168  jv[jss::amm_account] = to_string(*ammAccount);
169  }
170  auto jr = env_.rpc("json", "amm_info", to_string(jv));
171  if (jr.isObject() && jr.isMember(jss::result) &&
172  jr[jss::result].isMember(jss::status))
173  return jr[jss::result];
174  return Json::nullValue;
175 }
176 
179  Issue const& issue1,
180  Issue const& issue2,
181  std::optional<AccountID> const& account) const
182 {
183  if (auto const amm =
185  {
186  auto const ammAccountID = amm->getAccountID(sfAccount);
187  auto const [asset1Balance, asset2Balance] = ammPoolHolds(
188  *env_.current(),
189  ammAccountID,
190  issue1,
191  issue2,
192  FreezeHandling::fhIGNORE_FREEZE,
193  env_.journal);
194  auto const lptAMMBalance = account
195  ? ammLPHolds(*env_.current(), *amm, *account, env_.journal)
196  : amm->getFieldAmount(sfLPTokenBalance);
197  return {asset1Balance, asset2Balance, lptAMMBalance};
198  }
199  return {STAmount{}, STAmount{}, STAmount{}};
200 }
201 
202 bool
204  STAmount const& asset1,
205  STAmount const& asset2,
206  IOUAmount const& lpt,
207  std::optional<AccountID> const& account) const
208 {
209  auto const [asset1Balance, asset2Balance, lptAMMBalance] =
210  balances(asset1.issue(), asset2.issue(), account);
211  return asset1 == asset1Balance && asset2 == asset2Balance &&
212  lptAMMBalance == STAmount{lpt, lptIssue_};
213  return false;
214 }
215 
216 IOUAmount
218 {
219  if (account)
220  return accountHolds(
221  *env_.current(),
222  *account,
223  lptIssue_,
224  FreezeHandling::fhZERO_IF_FROZEN,
225  env_.journal)
226  .iou();
227  if (auto const amm =
229  return amm->getFieldAmount(sfLPTokenBalance).iou();
230  return IOUAmount{0};
231 }
232 
233 bool
234 AMM::expectLPTokens(AccountID const& account, IOUAmount const& expTokens) const
235 {
236  if (auto const amm =
238  {
239  auto const lptAMMBalance =
240  ammLPHolds(*env_.current(), *amm, account, env_.journal);
241  return lptAMMBalance == STAmount{expTokens, lptIssue_};
242  }
243  return false;
244 }
245 
246 bool
250  IOUAmount expectedPrice) const
251 {
252  return expectAuctionSlot([&](std::uint32_t slotFee,
253  std::optional<std::uint8_t> slotInterval,
254  IOUAmount const& slotPrice,
255  auto const&) {
256  return slotFee == fee &&
257  // Auction slot might be expired, in which case slotInterval is
258  // 0
259  ((!timeSlot && slotInterval == 0) || slotInterval == timeSlot) &&
260  slotPrice == expectedPrice;
261  });
262 }
263 
264 bool
266 {
267  return expectAuctionSlot([&](std::uint32_t,
269  IOUAmount const&,
270  STArray const& accounts) {
271  for (auto const& account : accounts)
272  {
273  if (std::find(
274  authAccounts.cbegin(),
275  authAccounts.cend(),
276  account.getAccountID(sfAccount)) == authAccounts.end())
277  return false;
278  }
279  return true;
280  });
281 }
282 
283 bool
285 {
286  auto const amm =
288  return amm && (*amm)[sfTradingFee] == fee;
289 }
290 
291 bool
293 {
294  return env_.current()->read(keylet::account(ammAccount_)) != nullptr &&
295  env_.current()->read(keylet::amm(asset1_.issue(), asset2_.issue())) !=
296  nullptr;
297 }
298 
299 bool
301  STAmount const& asset1,
302  STAmount const& asset2,
303  IOUAmount const& balance,
304  std::optional<AccountID> const& account,
305  std::optional<std::string> const& ledger_index,
306  std::optional<AccountID> const& ammAccount) const
307 {
308  auto const jv = ammRpcInfo(
309  account, ledger_index, std::nullopt, std::nullopt, ammAccount);
310  return expectAmmInfo(asset1, asset2, balance, jv);
311 }
312 
313 bool
315  STAmount const& asset1,
316  STAmount const& asset2,
317  IOUAmount const& balance,
318  Json::Value const& jvres) const
319 {
320  if (!jvres.isMember(jss::amm))
321  return false;
322  auto const& jv = jvres[jss::amm];
323  if (!jv.isMember(jss::amount) || !jv.isMember(jss::amount2) ||
324  !jv.isMember(jss::lp_token))
325  return false;
326  STAmount asset1Info;
327  if (!amountFromJsonNoThrow(asset1Info, jv[jss::amount]))
328  return false;
329  STAmount asset2Info;
330  if (!amountFromJsonNoThrow(asset2Info, jv[jss::amount2]))
331  return false;
332  STAmount lptBalance;
333  if (!amountFromJsonNoThrow(lptBalance, jv[jss::lp_token]))
334  return false;
335  // ammRpcInfo returns unordered assets
336  if (asset1Info.issue() != asset1.issue())
337  std::swap(asset1Info, asset2Info);
338  return asset1 == asset1Info && asset2 == asset2Info &&
339  lptBalance == STAmount{balance, lptIssue_};
340 }
341 
342 void
344  Json::Value& jv,
345  std::optional<std::pair<Issue, Issue>> const& assets)
346 {
347  if (assets)
348  {
349  jv[jss::Asset] =
350  STIssue(sfAsset, assets->first).getJson(JsonOptions::none);
351  jv[jss::Asset2] =
352  STIssue(sfAsset, assets->second).getJson(JsonOptions::none);
353  }
354  else
355  {
356  jv[jss::Asset] =
358  jv[jss::Asset2] =
360  }
361 }
362 
363 IOUAmount
365  std::optional<Account> const& account,
366  Json::Value& jv,
367  std::optional<std::pair<Issue, Issue>> const& assets,
369  std::optional<ter> const& ter)
370 {
371  auto const& acct = account ? *account : creatorAccount_;
372  auto const lpTokens = getLPTokensBalance(acct);
373  jv[jss::Account] = acct.human();
374  setTokens(jv, assets);
375  jv[jss::TransactionType] = jss::AMMDeposit;
376  if (fee_ != 0)
377  jv[jss::Fee] = std::to_string(fee_);
378  submit(jv, seq, ter);
379  return getLPTokensBalance(acct) - lpTokens;
380 }
381 
382 IOUAmount
384  std::optional<Account> const& account,
385  LPToken tokens,
386  std::optional<STAmount> const& asset1In,
388  std::optional<ter> const& ter)
389 {
390  return deposit(
391  account,
392  tokens,
393  asset1In,
394  std::nullopt,
395  std::nullopt,
396  flags,
397  std::nullopt,
398  std::nullopt,
399  std::nullopt,
400  ter);
401 }
402 
403 IOUAmount
405  std::optional<Account> const& account,
406  STAmount const& asset1In,
407  std::optional<STAmount> const& asset2In,
408  std::optional<STAmount> const& maxEP,
410  std::optional<ter> const& ter)
411 {
412  assert(!(asset2In && maxEP));
413  return deposit(
414  account,
415  std::nullopt,
416  asset1In,
417  asset2In,
418  maxEP,
419  flags,
420  std::nullopt,
421  std::nullopt,
422  std::nullopt,
423  ter);
424 }
425 
426 IOUAmount
428  std::optional<Account> const& account,
429  std::optional<LPToken> tokens,
430  std::optional<STAmount> const& asset1In,
431  std::optional<STAmount> const& asset2In,
432  std::optional<STAmount> const& maxEP,
434  std::optional<std::pair<Issue, Issue>> const& assets,
436  std::optional<std::uint16_t> const& tfee,
437  std::optional<ter> const& ter)
438 {
439  Json::Value jv;
440  if (tokens)
441  tokens->tokens(lptIssue_).setJson(jv[jss::LPTokenOut]);
442  if (asset1In)
443  asset1In->setJson(jv[jss::Amount]);
444  if (asset2In)
445  asset2In->setJson(jv[jss::Amount2]);
446  if (maxEP)
447  maxEP->setJson(jv[jss::EPrice]);
448  if (tfee)
449  jv[jss::TradingFee] = *tfee;
450  std::uint32_t jvflags = 0;
451  if (flags)
452  jvflags = *flags;
453  // If including asset1In and asset2In or tokens as
454  // deposit min amounts then must set the flags
455  // explicitly instead of relying on this logic.
456  if (!(jvflags & tfDepositSubTx))
457  {
458  if (tokens && !asset1In)
459  jvflags |= tfLPToken;
460  else if (tokens && asset1In)
461  jvflags |= tfOneAssetLPToken;
462  else if (asset1In && asset2In)
463  jvflags |= tfTwoAsset;
464  else if (maxEP && asset1In)
465  jvflags |= tfLimitLPToken;
466  else if (asset1In)
467  jvflags |= tfSingleAsset;
468  }
469  jv[jss::Flags] = jvflags;
470  return deposit(account, jv, assets, seq, ter);
471 }
472 
473 IOUAmount
475  std::optional<Account> const& account,
476  Json::Value& jv,
478  std::optional<std::pair<Issue, Issue>> const& assets,
479  std::optional<ter> const& ter)
480 {
481  auto const& acct = account ? *account : creatorAccount_;
482  auto const lpTokens = getLPTokensBalance(acct);
483  jv[jss::Account] = acct.human();
484  setTokens(jv, assets);
485  jv[jss::TransactionType] = jss::AMMWithdraw;
486  if (fee_ != 0)
487  jv[jss::Fee] = std::to_string(fee_);
488  submit(jv, seq, ter);
489  return lpTokens - getLPTokensBalance(acct);
490 }
491 
492 IOUAmount
494  std::optional<Account> const& account,
495  std::optional<LPToken> const& tokens,
496  std::optional<STAmount> const& asset1Out,
498  std::optional<ter> const& ter)
499 {
500  return withdraw(
501  account,
502  tokens,
503  asset1Out,
504  std::nullopt,
505  std::nullopt,
506  flags,
507  std::nullopt,
508  std::nullopt,
509  ter);
510 }
511 
512 IOUAmount
514  std::optional<Account> const& account,
515  STAmount const& asset1Out,
516  std::optional<STAmount> const& asset2Out,
517  std::optional<IOUAmount> const& maxEP,
518  std::optional<ter> const& ter)
519 {
520  assert(!(asset2Out && maxEP));
521  return withdraw(
522  account,
523  std::nullopt,
524  asset1Out,
525  asset2Out,
526  maxEP,
527  std::nullopt,
528  std::nullopt,
529  std::nullopt,
530  ter);
531 }
532 
533 IOUAmount
535  std::optional<Account> const& account,
536  std::optional<LPToken> const& tokens,
537  std::optional<STAmount> const& asset1Out,
538  std::optional<STAmount> const& asset2Out,
539  std::optional<IOUAmount> const& maxEP,
541  std::optional<std::pair<Issue, Issue>> const& assets,
543  std::optional<ter> const& ter)
544 {
545  Json::Value jv;
546  if (tokens)
547  tokens->tokens(lptIssue_).setJson(jv[jss::LPTokenIn]);
548  if (asset1Out)
549  asset1Out->setJson(jv[jss::Amount]);
550  if (asset2Out)
551  asset2Out->setJson(jv[jss::Amount2]);
552  if (maxEP)
553  {
554  STAmount const saMaxEP{*maxEP, lptIssue_};
555  saMaxEP.setJson(jv[jss::EPrice]);
556  }
557  std::uint32_t jvflags = 0;
558  if (flags)
559  jvflags = *flags;
560  if (!(jvflags & tfWithdrawSubTx))
561  {
562  if (tokens && !asset1Out)
563  jvflags |= tfLPToken;
564  else if (asset1Out && asset2Out)
565  jvflags |= tfTwoAsset;
566  else if (tokens && asset1Out)
567  jvflags |= tfOneAssetLPToken;
568  else if (asset1Out && maxEP)
569  jvflags |= tfLimitLPToken;
570  else if (asset1Out)
571  jvflags |= tfSingleAsset;
572  }
573  jv[jss::Flags] = jvflags;
574  return withdraw(account, jv, seq, assets, ter);
575 }
576 
577 void
579  std::optional<Account> const& account,
580  std::uint32_t feeVal,
583  std::optional<std::pair<Issue, Issue>> const& assets,
584  std::optional<ter> const& ter)
585 {
586  Json::Value jv;
587  jv[jss::Account] = account ? account->human() : creatorAccount_.human();
588  setTokens(jv, assets);
589  jv[jss::TradingFee] = feeVal;
590  jv[jss::TransactionType] = jss::AMMVote;
591  if (flags)
592  jv[jss::Flags] = *flags;
593  if (fee_ != 0)
594  jv[jss::Fee] = std::to_string(fee_);
595  submit(jv, seq, ter);
596 }
597 
598 void
600  std::optional<Account> const& account,
603  std::vector<Account> const& authAccounts,
606  std::optional<std::pair<Issue, Issue>> const& assets,
607  std::optional<ter> const& ter)
608 {
609  if (auto const amm =
611  {
612  if (amm->isFieldPresent(sfAuctionSlot))
613  {
614  auto const& auctionSlot =
615  static_cast<STObject const&>(amm->peekAtField(sfAuctionSlot));
616  lastPurchasePrice_ = auctionSlot[sfPrice].iou();
617  }
618  }
619  bidMin_ = std::nullopt;
620  bidMax_ = std::nullopt;
621 
622  Json::Value jv;
623  jv[jss::Account] = account ? account->human() : creatorAccount_.human();
624  setTokens(jv, assets);
625  auto getBid = [&](auto const& bid) {
626  if (std::holds_alternative<int>(bid))
627  return STAmount{lptIssue_, std::get<int>(bid)};
628  else if (std::holds_alternative<IOUAmount>(bid))
629  return toSTAmount(std::get<IOUAmount>(bid), lptIssue_);
630  else
631  return std::get<STAmount>(bid);
632  };
633  if (bidMin)
634  {
635  STAmount saTokens = getBid(*bidMin);
636  saTokens.setJson(jv[jss::BidMin]);
637  bidMin_ = saTokens.iou();
638  }
639  if (bidMax)
640  {
641  STAmount saTokens = getBid(*bidMax);
642  saTokens.setJson(jv[jss::BidMax]);
643  bidMax_ = saTokens.iou();
644  }
645  if (authAccounts.size() > 0)
646  {
647  Json::Value accounts(Json::arrayValue);
648  for (auto const& account : authAccounts)
649  {
650  Json::Value acct;
651  Json::Value authAcct;
652  acct[jss::Account] = account.human();
653  authAcct[jss::AuthAccount] = acct;
654  accounts.append(authAcct);
655  }
656  jv[jss::AuthAccounts] = accounts;
657  }
658  if (flags)
659  jv[jss::Flags] = *flags;
660  jv[jss::TransactionType] = jss::AMMBid;
661  if (fee_ != 0)
662  jv[jss::Fee] = std::to_string(fee_);
663  submit(jv, seq, ter);
664 }
665 
666 void
668  Json::Value const& jv,
670  std::optional<ter> const& ter)
671 {
672  if (log_)
673  std::cout << jv.toStyledString();
674  if (msig_)
675  {
676  if (seq && ter)
677  env_(jv, *msig_, *seq, *ter);
678  else if (seq)
679  env_(jv, *msig_, *seq);
680  else if (ter)
681  env_(jv, *msig_, *ter);
682  else
683  env_(jv, *msig_);
684  }
685  else if (seq && ter)
686  env_(jv, *seq, *ter);
687  else if (seq)
688  env_(jv, *seq);
689  else if (ter)
690  env_(jv, *ter);
691  else
692  env_(jv);
693  if (doClose_)
694  env_.close();
695 }
696 
697 bool
698 AMM::expectAuctionSlot(auto&& cb) const
699 {
700  if (auto const amm =
702  amm && amm->isFieldPresent(sfAuctionSlot))
703  {
704  auto const& auctionSlot =
705  static_cast<STObject const&>(amm->peekAtField(sfAuctionSlot));
706  if (auctionSlot.isFieldPresent(sfAccount))
707  {
708  auto const slotFee = auctionSlot[sfDiscountedFee];
709  auto const slotInterval = ammAuctionTimeSlot(
710  env_.app().timeKeeper().now().time_since_epoch().count(),
711  auctionSlot);
712  auto const slotPrice = auctionSlot[sfPrice].iou();
713  auto const authAccounts = auctionSlot.getFieldArray(sfAuthAccounts);
714  return cb(slotFee, slotInterval, slotPrice, authAccounts);
715  }
716  }
717  return false;
718 }
719 
720 void
722 {
723  Json::Value jv;
724  jv[jss::Account] = to_string(deleter);
725  setTokens(jv);
726  jv[jss::TransactionType] = jss::AMMDelete;
727  if (fee_ != 0)
728  jv[jss::Fee] = std::to_string(fee_);
729  submit(jv, std::nullopt, ter);
730 }
731 
732 namespace amm {
734 trust(AccountID const& account, STAmount const& amount, std::uint32_t flags)
735 {
736  if (isXRP(amount))
737  Throw<std::runtime_error>("trust() requires IOU");
738  Json::Value jv;
739  jv[jss::Account] = to_string(account);
740  jv[jss::LimitAmount] = amount.getJson(JsonOptions::none);
741  jv[jss::TransactionType] = jss::TrustSet;
742  jv[jss::Flags] = flags;
743  return jv;
744 }
746 pay(Account const& account, AccountID const& to, STAmount const& amount)
747 {
748  Json::Value jv;
749  jv[jss::Account] = account.human();
750  jv[jss::Amount] = amount.getJson(JsonOptions::none);
751  jv[jss::Destination] = to_string(to);
752  jv[jss::TransactionType] = jss::Payment;
753  jv[jss::Flags] = tfUniversal;
754  return jv;
755 }
756 } // namespace amm
757 } // namespace jtx
758 } // namespace test
759 } // namespace ripple
ripple::amountFromJsonNoThrow
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:1032
ripple::root2
Number root2(Number f)
Definition: Number.cpp:689
ripple::sfDiscountedFee
const SF_UINT16 sfDiscountedFee
ripple::Issue
A currency issued by an account.
Definition: Issue.h:35
ripple::sfAsset
const SF_ISSUE sfAsset
ripple::test::jtx::AMM::ammDelete
void ammDelete(AccountID const &deleter, std::optional< ter > const &ter=std::nullopt)
Definition: AMM.cpp:721
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:712
ripple::test::jtx::AMM::msig_
const std::optional< msig > msig_
Definition: AMM.h:77
ripple::test::jtx::AMM::ammAccount
AccountID const & ammAccount() const
Definition: AMM.h:255
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:350
ripple::test::jtx::ter
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:33
ripple::ammLPTIssue
Issue ammLPTIssue(Currency const &cur1, Currency const &cur2, AccountID const &ammAccountID)
Calculate LPT Issue from AMM asset pair.
Definition: AMMCore.cpp:56
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
std::pair
ripple::test::jtx::balance
A balance matches.
Definition: balance.h:38
ripple::sfLPTokenBalance
const SF_AMOUNT sfLPTokenBalance
std::vector
STL class.
std::find
T find(T... args)
std::vector::size
T size(T... args)
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:226
ripple::keylet::amm
Keylet amm(Issue const &issue1, Issue const &issue2) noexcept
AMM entry.
Definition: Indexes.cpp:383
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:653
ripple::test::jtx::AMM::vote
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< Issue, Issue >> const &assets=std::nullopt, std::optional< ter > const &ter=std::nullopt)
Definition: AMM.cpp:578
ripple::test::jtx::amm::pay
Json::Value pay(Account const &account, AccountID const &to, STAmount const &amount)
Definition: AMM.cpp:746
ripple::test::jtx::Account::human
std::string const & human() const
Returns the human readable public key.
Definition: Account.h:113
ripple::test::jtx::Env::journal
const beast::Journal journal
Definition: Env.h:145
ripple::test::jtx::AMM::deposit
IOUAmount deposit(std::optional< Account > const &account, LPToken tokens, std::optional< STAmount > const &asset1InDetails=std::nullopt, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< ter > const &ter=std::nullopt)
Definition: AMM.cpp:383
std::tuple
ripple::test::jtx::AMM::bid
void bid(std::optional< Account > const &account, std::optional< std::variant< int, IOUAmount, STAmount >> const &bidMin=std::nullopt, std::optional< std::variant< int, IOUAmount, STAmount >> const &bidMax=std::nullopt, std::vector< Account > const &authAccounts={}, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< jtx::seq > const &seq=std::nullopt, std::optional< std::pair< Issue, Issue >> const &assets=std::nullopt, std::optional< ter > const &ter=std::nullopt)
Definition: AMM.cpp:599
ripple::IOUAmount
Floating point representation of amounts with high dynamic range.
Definition: IOUAmount.h:43
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:242
ripple::test::jtx::AMM
Convenience class to test AMM functionality.
Definition: AMM.h:62
Json::Value::toStyledString
std::string toStyledString() const
Definition: json_value.cpp:1039
ripple::Application::timeKeeper
virtual TimeKeeper & timeKeeper()=0
ripple::test::jtx::AMM::expectAmmInfo
bool expectAmmInfo(STAmount const &asset1, STAmount const &asset2, IOUAmount const &balance, Json::Value const &jv) const
Definition: AMM.cpp:314
ripple::test::jtx::AMM::creatorAccount_
const Account creatorAccount_
Definition: AMM.h:65
ripple::sfPrice
const SF_AMOUNT sfPrice
ripple::STAmount::iou
IOUAmount iou() const
Definition: STAmount.cpp:360
ripple::test::jtx::Env::ter
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:537
ripple::ammAccountID
AccountID ammAccountID(std::uint16_t prefix, uint256 const &parentHash, uint256 const &ammID)
Calculate AMM account ID.
Definition: AMMCore.cpp:30
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:345
ripple::sfTradingFee
const SF_UINT16 sfTradingFee
ripple::test::jtx::AMM::expectBalances
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:203
ripple::ammPoolHolds
std::pair< STAmount, STAmount > ammPoolHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue1, Issue const &issue2, FreezeHandling freezeHandling, beast::Journal const j)
Get AMM pool balances.
Definition: AMMUtils.cpp:29
ripple::test::jtx::AMM::ammRpcInfo
Json::Value ammRpcInfo(std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledgerIndex=std::nullopt, std::optional< Issue > issue1=std::nullopt, std::optional< Issue > issue2=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt, bool ignoreParams=false) const
Send amm_info RPC command.
Definition: AMM.cpp:136
std::cout
ripple::STIssue::getJson
Json::Value getJson(JsonOptions) const override
Definition: STIssue.cpp:74
ripple::base_uint< 160, detail::AccountIDTag >
ripple::test::jtx::AMM::expectAmmRpcInfo
bool expectAmmRpcInfo(STAmount const &asset1, STAmount const &asset2, IOUAmount const &balance, std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledger_index=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt) const
Definition: AMM.cpp:300
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::sfAsset2
const SF_ISSUE sfAsset2
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:528
ripple::test::jtx::initialTokens
static IOUAmount initialTokens(STAmount const &asset1, STAmount const &asset2)
Definition: AMM.cpp:42
ripple::test::jtx::AMM::expectLPTokens
bool expectLPTokens(AccountID const &account, IOUAmount const &tokens) const
Definition: AMM.cpp:234
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:142
ripple::test::jtx::AMM::lastPurchasePrice_
IOUAmount lastPurchasePrice_
Definition: AMM.h:73
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:30
ripple::sfAuthAccounts
const SField sfAuthAccounts
ripple::tfWithdrawSubTx
constexpr std::uint32_t tfWithdrawSubTx
Definition: TxFlags.h:175
ripple::test::jtx::AMM::log_
bool log_
Definition: AMM.h:70
ripple::STArray
Definition: STArray.h:28
std::to_string
T to_string(T... args)
ripple::test::jtx::AMM::env_
Env & env_
Definition: AMM.h:64
ripple::test::jtx::AMM::lptIssue_
const Issue lptIssue_
Definition: AMM.h:81
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:121
ripple::test::jtx::AMM::bidMax_
std::optional< IOUAmount > bidMax_
Definition: AMM.h:75
ripple::STAmount
Definition: STAmount.h:46
ripple::test::jtx::amm::trust
Json::Value trust(AccountID const &account, STAmount const &amount, std::uint32_t flags=0)
Definition: AMM.cpp:734
ripple::test::jtx::AMM::AMM
AMM(Env &env, Account const &account, STAmount const &asset1, STAmount const &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)
Definition: AMM.cpp:49
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
std::uint16_t
ripple::tfSingleAsset
constexpr std::uint32_t tfSingleAsset
Definition: TxFlags.h:170
ripple::TimeKeeper::now
time_point now() const override
Returns the current time, using the server's clock.
Definition: TimeKeeper.h:64
ripple::STIssue
Definition: STIssue.h:31
ripple::test::jtx::AMM::expectTradingFee
bool expectTradingFee(std::uint16_t fee) const
Definition: AMM.cpp:284
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:35
std::swap
T swap(T... args)
ripple::test::jtx::AMM::asset1_
const STAmount asset1_
Definition: AMM.h:66
ripple::test::jtx::AMM::withdraw
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:493
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:33
ripple::test::jtx::AMM::ammExists
bool ammExists() const
Definition: AMM.cpp:292
ripple::STObject
Definition: STObject.h:53
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::jtx::AMM::asset2_
const STAmount asset2_
Definition: AMM.h:67
ripple::test::jtx::AMM::setTokens
void setTokens(Json::Value &jv, std::optional< std::pair< Issue, Issue >> const &assets=std::nullopt)
Definition: AMM.cpp:343
ripple::tfLPToken
constexpr std::uint32_t tfLPToken
Definition: TxFlags.h:167
ripple::JsonOptions::none
@ none
Definition: STBase.h:42
ripple::test::jtx::flags
Match set account flags.
Definition: flags.h:111
ripple::test::jtx::AMM::ammAccount_
const AccountID ammAccount_
Definition: AMM.h:80
ripple::tfDepositSubTx
constexpr std::uint32_t tfDepositSubTx
Definition: TxFlags.h:178
ripple::test::jtx::AMM::tokens
IOUAmount tokens() const
Definition: AMM.h:267
std::vector::cbegin
T cbegin(T... args)
std
STL namespace.
ripple::tfTwoAsset
constexpr std::uint32_t tfTwoAsset
Definition: TxFlags.h:171
ripple::test::jtx::number
static Number number(STAmount const &a)
Definition: AMM.cpp:34
Json::nullValue
@ nullValue
'null' value
Definition: json_value.h:36
ripple::ammLPHolds
STAmount ammLPHolds(ReadView const &view, Currency const &cur1, Currency const &cur2, AccountID const &ammAccount, AccountID const &lpAccount, beast::Journal const j)
Get the balance of LP tokens.
Definition: AMMUtils.cpp:104
ripple::test::jtx::AMM::expectAuctionSlot
bool expectAuctionSlot(std::uint32_t fee, std::optional< std::uint8_t > timeSlot, IOUAmount expectedPrice) const
Definition: AMM.cpp:247
ripple::test::jtx::AMM::doClose_
bool doClose_
Definition: AMM.h:71
std::optional< std::uint32_t >
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::test::jtx::AMM::create
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:104
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::test::jtx::AMM::submit
void submit(Json::Value const &jv, std::optional< jtx::seq > const &seq, std::optional< ter > const &ter)
Definition: AMM.cpp:667
std::vector::cend
T cend(T... args)
ripple::test::jtx::LPToken
Definition: AMM.h:37
ripple::test::jtx::AMM::fee_
const std::uint32_t fee_
Definition: AMM.h:79
ripple::tfOneAssetLPToken
constexpr std::uint32_t tfOneAssetLPToken
Definition: TxFlags.h:172
ripple::tfUniversal
constexpr std::uint32_t tfUniversal
Definition: TxFlags.h:59
ripple::sfAuctionSlot
const SField sfAuctionSlot
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:236
ripple::test::jtx::AMM::bidMin_
std::optional< IOUAmount > bidMin_
Definition: AMM.h:74
ripple::test::jtx::Env::current
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:312
ripple::test::jtx::create
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
Definition: TestHelpers.cpp:250
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:117
ripple::ammAuctionTimeSlot
std::optional< std::uint8_t > ammAuctionTimeSlot(std::uint64_t current, STObject const &auctionSlot)
Get time slot of the auction slot.
Definition: AMMCore.cpp:107
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::test::jtx::AMM::balances
std::tuple< STAmount, STAmount, STAmount > balances(Issue const &issue1, Issue const &issue2, std::optional< AccountID > const &account=std::nullopt) const
Get AMM balances for the token pair.
Definition: AMM.cpp:178
std::variant
ripple::tfLimitLPToken
constexpr std::uint32_t tfLimitLPToken
Definition: TxFlags.h:173
ripple::test::jtx::AMM::getLPTokensBalance
IOUAmount getLPTokensBalance(std::optional< AccountID > const &account=std::nullopt) const
Definition: AMM.cpp:217