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,
140 {
141  Json::Value jv;
142  if (account)
143  jv[jss::account] = to_string(*account);
144  if (ledgerIndex)
145  jv[jss::ledger_index] = *ledgerIndex;
146  if (tokens)
147  {
148  jv[jss::asset] =
150  jv[jss::asset2] =
152  }
153  else
154  {
155  jv[jss::asset] =
157  jv[jss::asset2] =
159  }
160  auto jr = env_.rpc("json", "amm_info", to_string(jv));
161  if (jr.isObject() && jr.isMember(jss::result) &&
162  jr[jss::result].isMember(jss::status))
163  return jr[jss::result];
164  return Json::nullValue;
165 }
166 
169  Issue const& issue1,
170  Issue const& issue2,
171  std::optional<AccountID> const& account) const
172 {
173  if (auto const amm =
175  {
176  auto const ammAccountID = amm->getAccountID(sfAccount);
177  auto const [asset1Balance, asset2Balance] = ammPoolHolds(
178  *env_.current(),
179  ammAccountID,
180  issue1,
181  issue2,
182  FreezeHandling::fhIGNORE_FREEZE,
183  env_.journal);
184  auto const lptAMMBalance = account
185  ? ammLPHolds(*env_.current(), *amm, *account, env_.journal)
186  : amm->getFieldAmount(sfLPTokenBalance);
187  return {asset1Balance, asset2Balance, lptAMMBalance};
188  }
189  return {STAmount{}, STAmount{}, STAmount{}};
190 }
191 
192 bool
194  STAmount const& asset1,
195  STAmount const& asset2,
196  IOUAmount const& lpt,
197  std::optional<AccountID> const& account) const
198 {
199  auto const [asset1Balance, asset2Balance, lptAMMBalance] =
200  balances(asset1.issue(), asset2.issue(), account);
201  return asset1 == asset1Balance && asset2 == asset2Balance &&
202  lptAMMBalance == STAmount{lpt, lptIssue_};
203  return false;
204 }
205 
206 IOUAmount
208 {
209  if (account)
210  return accountHolds(
211  *env_.current(),
212  *account,
213  lptIssue_,
214  FreezeHandling::fhZERO_IF_FROZEN,
215  env_.journal)
216  .iou();
217  if (auto const amm =
219  return amm->getFieldAmount(sfLPTokenBalance).iou();
220  return IOUAmount{0};
221 }
222 
223 bool
224 AMM::expectLPTokens(AccountID const& account, IOUAmount const& expTokens) const
225 {
226  if (auto const amm =
228  {
229  auto const lptAMMBalance =
230  ammLPHolds(*env_.current(), *amm, account, env_.journal);
231  return lptAMMBalance == STAmount{expTokens, lptIssue_};
232  }
233  return false;
234 }
235 
236 bool
240  IOUAmount expectedPrice) const
241 {
242  return expectAuctionSlot([&](std::uint32_t slotFee,
243  std::optional<std::uint8_t> slotInterval,
244  IOUAmount const& slotPrice,
245  auto const&) {
246  return slotFee == fee &&
247  // Auction slot might be expired, in which case slotInterval is
248  // 0
249  ((!timeSlot && slotInterval == 0) || slotInterval == timeSlot) &&
250  slotPrice == expectedPrice;
251  });
252 }
253 
254 bool
256 {
257  return expectAuctionSlot([&](std::uint32_t,
259  IOUAmount const&,
260  STArray const& accounts) {
261  for (auto const& account : accounts)
262  {
263  if (std::find(
264  authAccounts.cbegin(),
265  authAccounts.cend(),
266  account.getAccountID(sfAccount)) == authAccounts.end())
267  return false;
268  }
269  return true;
270  });
271 }
272 
273 bool
275 {
276  auto const amm =
278  return amm && (*amm)[sfTradingFee] == fee;
279 }
280 
281 bool
283 {
284  return env_.current()->read(keylet::account(ammAccount_)) != nullptr &&
285  env_.current()->read(keylet::amm(asset1_.issue(), asset2_.issue())) !=
286  nullptr;
287 }
288 
289 bool
291  STAmount const& asset1,
292  STAmount const& asset2,
293  IOUAmount const& balance,
294  std::optional<AccountID> const& account,
295  std::optional<std::string> const& ledger_index) const
296 {
297  auto const jv = ammRpcInfo(account, ledger_index);
298  return expectAmmInfo(asset1, asset2, balance, jv);
299 }
300 
301 bool
303  STAmount const& asset1,
304  STAmount const& asset2,
305  IOUAmount const& balance,
306  Json::Value const& jvres) const
307 {
308  if (!jvres.isMember(jss::amm))
309  return false;
310  auto const& jv = jvres[jss::amm];
311  if (!jv.isMember(jss::amount) || !jv.isMember(jss::amount2) ||
312  !jv.isMember(jss::lp_token))
313  return false;
314  STAmount asset1Info;
315  if (!amountFromJsonNoThrow(asset1Info, jv[jss::amount]))
316  return false;
317  STAmount asset2Info;
318  if (!amountFromJsonNoThrow(asset2Info, jv[jss::amount2]))
319  return false;
320  STAmount lptBalance;
321  if (!amountFromJsonNoThrow(lptBalance, jv[jss::lp_token]))
322  return false;
323  // ammRpcInfo returns unordered assets
324  if (asset1Info.issue() != asset1.issue())
325  std::swap(asset1Info, asset2Info);
326  return asset1 == asset1Info && asset2 == asset2Info &&
327  lptBalance == STAmount{balance, lptIssue_};
328 }
329 
330 void
332  Json::Value& jv,
333  std::optional<std::pair<Issue, Issue>> const& assets)
334 {
335  if (assets)
336  {
337  jv[jss::Asset] =
338  STIssue(sfAsset, assets->first).getJson(JsonOptions::none);
339  jv[jss::Asset2] =
340  STIssue(sfAsset, assets->second).getJson(JsonOptions::none);
341  }
342  else
343  {
344  jv[jss::Asset] =
346  jv[jss::Asset2] =
348  }
349 }
350 
351 IOUAmount
353  std::optional<Account> const& account,
354  Json::Value& jv,
355  std::optional<std::pair<Issue, Issue>> const& assets,
357  std::optional<ter> const& ter)
358 {
359  auto const& acct = account ? *account : creatorAccount_;
360  auto const lpTokens = getLPTokensBalance(acct);
361  jv[jss::Account] = acct.human();
362  setTokens(jv, assets);
363  jv[jss::TransactionType] = jss::AMMDeposit;
364  if (fee_ != 0)
365  jv[jss::Fee] = std::to_string(fee_);
366  submit(jv, seq, ter);
367  return getLPTokensBalance(acct) - lpTokens;
368 }
369 
370 IOUAmount
372  std::optional<Account> const& account,
373  LPToken tokens,
374  std::optional<STAmount> const& asset1In,
376  std::optional<ter> const& ter)
377 {
378  return deposit(
379  account,
380  tokens,
381  asset1In,
382  std::nullopt,
383  std::nullopt,
384  flags,
385  std::nullopt,
386  std::nullopt,
387  std::nullopt,
388  ter);
389 }
390 
391 IOUAmount
393  std::optional<Account> const& account,
394  STAmount const& asset1In,
395  std::optional<STAmount> const& asset2In,
396  std::optional<STAmount> const& maxEP,
398  std::optional<ter> const& ter)
399 {
400  assert(!(asset2In && maxEP));
401  return deposit(
402  account,
403  std::nullopt,
404  asset1In,
405  asset2In,
406  maxEP,
407  flags,
408  std::nullopt,
409  std::nullopt,
410  std::nullopt,
411  ter);
412 }
413 
414 IOUAmount
416  std::optional<Account> const& account,
417  std::optional<LPToken> tokens,
418  std::optional<STAmount> const& asset1In,
419  std::optional<STAmount> const& asset2In,
420  std::optional<STAmount> const& maxEP,
422  std::optional<std::pair<Issue, Issue>> const& assets,
424  std::optional<std::uint16_t> const& tfee,
425  std::optional<ter> const& ter)
426 {
427  Json::Value jv;
428  if (tokens)
429  tokens->tokens(lptIssue_).setJson(jv[jss::LPTokenOut]);
430  if (asset1In)
431  asset1In->setJson(jv[jss::Amount]);
432  if (asset2In)
433  asset2In->setJson(jv[jss::Amount2]);
434  if (maxEP)
435  maxEP->setJson(jv[jss::EPrice]);
436  if (tfee)
437  jv[jss::TradingFee] = *tfee;
438  std::uint32_t jvflags = 0;
439  if (flags)
440  jvflags = *flags;
441  // If including asset1In and asset2In or tokens as
442  // deposit min amounts then must set the flags
443  // explicitly instead of relying on this logic.
444  if (!(jvflags & tfDepositSubTx))
445  {
446  if (tokens && !asset1In)
447  jvflags |= tfLPToken;
448  else if (tokens && asset1In)
449  jvflags |= tfOneAssetLPToken;
450  else if (asset1In && asset2In)
451  jvflags |= tfTwoAsset;
452  else if (maxEP && asset1In)
453  jvflags |= tfLimitLPToken;
454  else if (asset1In)
455  jvflags |= tfSingleAsset;
456  }
457  jv[jss::Flags] = jvflags;
458  return deposit(account, jv, assets, seq, ter);
459 }
460 
461 IOUAmount
463  std::optional<Account> const& account,
464  Json::Value& jv,
466  std::optional<std::pair<Issue, Issue>> const& assets,
467  std::optional<ter> const& ter)
468 {
469  auto const& acct = account ? *account : creatorAccount_;
470  auto const lpTokens = getLPTokensBalance(acct);
471  jv[jss::Account] = acct.human();
472  setTokens(jv, assets);
473  jv[jss::TransactionType] = jss::AMMWithdraw;
474  if (fee_ != 0)
475  jv[jss::Fee] = std::to_string(fee_);
476  submit(jv, seq, ter);
477  return lpTokens - getLPTokensBalance(acct);
478 }
479 
480 IOUAmount
482  std::optional<Account> const& account,
483  std::optional<LPToken> const& tokens,
484  std::optional<STAmount> const& asset1Out,
486  std::optional<ter> const& ter)
487 {
488  return withdraw(
489  account,
490  tokens,
491  asset1Out,
492  std::nullopt,
493  std::nullopt,
494  flags,
495  std::nullopt,
496  std::nullopt,
497  ter);
498 }
499 
500 IOUAmount
502  std::optional<Account> const& account,
503  STAmount const& asset1Out,
504  std::optional<STAmount> const& asset2Out,
505  std::optional<IOUAmount> const& maxEP,
506  std::optional<ter> const& ter)
507 {
508  assert(!(asset2Out && maxEP));
509  return withdraw(
510  account,
511  std::nullopt,
512  asset1Out,
513  asset2Out,
514  maxEP,
515  std::nullopt,
516  std::nullopt,
517  std::nullopt,
518  ter);
519 }
520 
521 IOUAmount
523  std::optional<Account> const& account,
524  std::optional<LPToken> const& tokens,
525  std::optional<STAmount> const& asset1Out,
526  std::optional<STAmount> const& asset2Out,
527  std::optional<IOUAmount> const& maxEP,
529  std::optional<std::pair<Issue, Issue>> const& assets,
531  std::optional<ter> const& ter)
532 {
533  Json::Value jv;
534  if (tokens)
535  tokens->tokens(lptIssue_).setJson(jv[jss::LPTokenIn]);
536  if (asset1Out)
537  asset1Out->setJson(jv[jss::Amount]);
538  if (asset2Out)
539  asset2Out->setJson(jv[jss::Amount2]);
540  if (maxEP)
541  {
542  STAmount const saMaxEP{*maxEP, lptIssue_};
543  saMaxEP.setJson(jv[jss::EPrice]);
544  }
545  std::uint32_t jvflags = 0;
546  if (flags)
547  jvflags = *flags;
548  if (!(jvflags & tfWithdrawSubTx))
549  {
550  if (tokens && !asset1Out)
551  jvflags |= tfLPToken;
552  else if (asset1Out && asset2Out)
553  jvflags |= tfTwoAsset;
554  else if (tokens && asset1Out)
555  jvflags |= tfOneAssetLPToken;
556  else if (asset1Out && maxEP)
557  jvflags |= tfLimitLPToken;
558  else if (asset1Out)
559  jvflags |= tfSingleAsset;
560  }
561  jv[jss::Flags] = jvflags;
562  return withdraw(account, jv, seq, assets, ter);
563 }
564 
565 void
567  std::optional<Account> const& account,
568  std::uint32_t feeVal,
571  std::optional<std::pair<Issue, Issue>> const& assets,
572  std::optional<ter> const& ter)
573 {
574  Json::Value jv;
575  jv[jss::Account] = account ? account->human() : creatorAccount_.human();
576  setTokens(jv, assets);
577  jv[jss::TradingFee] = feeVal;
578  jv[jss::TransactionType] = jss::AMMVote;
579  if (flags)
580  jv[jss::Flags] = *flags;
581  if (fee_ != 0)
582  jv[jss::Fee] = std::to_string(fee_);
583  submit(jv, seq, ter);
584 }
585 
586 void
588  std::optional<Account> const& account,
591  std::vector<Account> const& authAccounts,
594  std::optional<std::pair<Issue, Issue>> const& assets,
595  std::optional<ter> const& ter)
596 {
597  if (auto const amm =
599  {
600  if (amm->isFieldPresent(sfAuctionSlot))
601  {
602  auto const& auctionSlot =
603  static_cast<STObject const&>(amm->peekAtField(sfAuctionSlot));
604  lastPurchasePrice_ = auctionSlot[sfPrice].iou();
605  }
606  }
607  bidMin_ = std::nullopt;
608  bidMax_ = std::nullopt;
609 
610  Json::Value jv;
611  jv[jss::Account] = account ? account->human() : creatorAccount_.human();
612  setTokens(jv, assets);
613  auto getBid = [&](auto const& bid) {
614  if (std::holds_alternative<int>(bid))
615  return STAmount{lptIssue_, std::get<int>(bid)};
616  else if (std::holds_alternative<IOUAmount>(bid))
617  return toSTAmount(std::get<IOUAmount>(bid), lptIssue_);
618  else
619  return std::get<STAmount>(bid);
620  };
621  if (bidMin)
622  {
623  STAmount saTokens = getBid(*bidMin);
624  saTokens.setJson(jv[jss::BidMin]);
625  bidMin_ = saTokens.iou();
626  }
627  if (bidMax)
628  {
629  STAmount saTokens = getBid(*bidMax);
630  saTokens.setJson(jv[jss::BidMax]);
631  bidMax_ = saTokens.iou();
632  }
633  if (authAccounts.size() > 0)
634  {
635  Json::Value accounts(Json::arrayValue);
636  for (auto const& account : authAccounts)
637  {
638  Json::Value acct;
639  Json::Value authAcct;
640  acct[jss::Account] = account.human();
641  authAcct[jss::AuthAccount] = acct;
642  accounts.append(authAcct);
643  }
644  jv[jss::AuthAccounts] = accounts;
645  }
646  if (flags)
647  jv[jss::Flags] = *flags;
648  jv[jss::TransactionType] = jss::AMMBid;
649  if (fee_ != 0)
650  jv[jss::Fee] = std::to_string(fee_);
651  submit(jv, seq, ter);
652 }
653 
654 void
656  Json::Value const& jv,
658  std::optional<ter> const& ter)
659 {
660  if (log_)
661  std::cout << jv.toStyledString();
662  if (msig_)
663  {
664  if (seq && ter)
665  env_(jv, *msig_, *seq, *ter);
666  else if (seq)
667  env_(jv, *msig_, *seq);
668  else if (ter)
669  env_(jv, *msig_, *ter);
670  else
671  env_(jv, *msig_);
672  }
673  else if (seq && ter)
674  env_(jv, *seq, *ter);
675  else if (seq)
676  env_(jv, *seq);
677  else if (ter)
678  env_(jv, *ter);
679  else
680  env_(jv);
681  if (doClose_)
682  env_.close();
683 }
684 
685 bool
686 AMM::expectAuctionSlot(auto&& cb) const
687 {
688  if (auto const amm =
690  amm && amm->isFieldPresent(sfAuctionSlot))
691  {
692  auto const& auctionSlot =
693  static_cast<STObject const&>(amm->peekAtField(sfAuctionSlot));
694  if (auctionSlot.isFieldPresent(sfAccount))
695  {
696  auto const slotFee = auctionSlot[sfDiscountedFee];
697  auto const slotInterval = ammAuctionTimeSlot(
698  env_.app().timeKeeper().now().time_since_epoch().count(),
699  auctionSlot);
700  auto const slotPrice = auctionSlot[sfPrice].iou();
701  auto const authAccounts = auctionSlot.getFieldArray(sfAuthAccounts);
702  return cb(slotFee, slotInterval, slotPrice, authAccounts);
703  }
704  }
705  return false;
706 }
707 
708 void
710 {
711  Json::Value jv;
712  jv[jss::Account] = to_string(deleter);
713  setTokens(jv);
714  jv[jss::TransactionType] = jss::AMMDelete;
715  if (fee_ != 0)
716  jv[jss::Fee] = std::to_string(fee_);
717  submit(jv, std::nullopt, ter);
718 }
719 
720 namespace amm {
722 trust(AccountID const& account, STAmount const& amount, std::uint32_t flags)
723 {
724  if (isXRP(amount))
725  Throw<std::runtime_error>("trust() requires IOU");
726  Json::Value jv;
727  jv[jss::Account] = to_string(account);
728  jv[jss::LimitAmount] = amount.getJson(JsonOptions::none);
729  jv[jss::TransactionType] = jss::TrustSet;
730  jv[jss::Flags] = flags;
731  return jv;
732 }
734 pay(Account const& account, AccountID const& to, STAmount const& amount)
735 {
736  Json::Value jv;
737  jv[jss::Account] = account.human();
738  jv[jss::Amount] = amount.getJson(JsonOptions::none);
739  jv[jss::Destination] = to_string(to);
740  jv[jss::TransactionType] = jss::Payment;
741  jv[jss::Flags] = tfUniversal;
742  return jv;
743 }
744 } // namespace amm
745 } // namespace jtx
746 } // namespace test
747 } // namespace ripple
ripple::amountFromJsonNoThrow
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:1021
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:709
ripple::test::jtx::AMM::msig_
const std::optional< msig > msig_
Definition: AMM.h:77
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:347
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::AMM::ammRpcInfo
Json::Value ammRpcInfo(std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledgerIndex=std::nullopt, std::optional< std::pair< Issue, Issue >> tokens=std::nullopt) const
Send amm_info RPC command.
Definition: AMM.cpp:136
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:375
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:642
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:566
ripple::test::jtx::amm::pay
Json::Value pay(Account const &account, AccountID const &to, STAmount const &amount)
Definition: AMM.cpp:734
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:371
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:587
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:302
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:349
ripple::test::jtx::Env::ter
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:526
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:334
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:193
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
std::cout
ripple::STIssue::getJson
Json::Value getJson(JsonOptions) const override
Definition: STIssue.cpp:63
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:82
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:517
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:224
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
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) const
Definition: AMM.cpp:290
ripple::test::jtx::AMM::lastPurchasePrice_
IOUAmount lastPurchasePrice_
Definition: AMM.h:73
ripple::JsonOptions::none
@ none
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:45
ripple::test::jtx::amm::trust
Json::Value trust(AccountID const &account, STAmount const &amount, std::uint32_t flags=0)
Definition: AMM.cpp:722
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:89
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::STIssue
Definition: STIssue.h:31
ripple::test::jtx::AMM::expectTradingFee
bool expectTradingFee(std::uint16_t fee) const
Definition: AMM.cpp:274
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:481
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:282
ripple::STObject
Definition: STObject.h:52
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:331
ripple::tfLPToken
constexpr std::uint32_t tfLPToken
Definition: TxFlags.h:167
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:263
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::TimeKeeper::now
virtual time_point now() const override=0
Returns the estimate of wall time, in network time.
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:237
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:655
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:226
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:301
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::test::jtx::Env::rpc
Json::Value rpc(std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:700
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:168
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:207