rippled
Loading...
Searching...
No Matches
AMM.cpp
1#include <test/jtx/AMM.h>
2#include <test/jtx/Env.h>
3
4#include <xrpld/app/misc/AMMHelpers.h>
5#include <xrpld/app/misc/AMMUtils.h>
6
7#include <xrpl/protocol/AMMCore.h>
8#include <xrpl/protocol/AmountConversions.h>
9#include <xrpl/protocol/ApiVersion.h>
10#include <xrpl/protocol/jss.h>
11
12namespace ripple {
13namespace test {
14namespace jtx {
15
16static Number
18{
19 if (isXRP(a))
20 return a.xrp();
21 return a;
22}
23
26{
27 if (!env_.enabled(fixAMMv1_3))
28 {
29 auto const product = number(asset1_) * number(asset2_);
30 return (IOUAmount)(product.mantissa() >= 0 ? root2(product)
31 : root2(-product));
32 }
33 return getLPTokensBalance();
34}
35
37 Env& env,
38 Account const& account,
39 STAmount const& asset1,
40 STAmount const& asset2,
41 bool log,
42 std::uint16_t tfee,
48 bool close)
49 : env_(env)
50 , creatorAccount_(account)
51 , asset1_(asset1)
52 , asset2_(asset2)
53 , ammID_(keylet::amm(asset1_.issue(), asset2_.issue()).key)
54 , log_(log)
55 , doClose_(close)
56 , lastPurchasePrice_(0)
57 , bidMin_()
58 , bidMax_()
59 , msig_(ms)
60 , fee_(fee)
61 , ammAccount_(create(tfee, flags, seq, ter))
62 , lptIssue_(ripple::ammLPTIssue(
63 asset1_.issue().currency,
64 asset2_.issue().currency,
65 ammAccount_))
66 , initialLPTokens_(initialTokens())
67{
68}
69
71 Env& env,
72 Account const& account,
73 STAmount const& asset1,
74 STAmount const& asset2,
75 ter const& ter,
76 bool log,
77 bool close)
78 : AMM(env,
79 account,
80 asset1,
81 asset2,
82 log,
83 0,
84 0,
85 std::nullopt,
86 std::nullopt,
87 std::nullopt,
88 ter,
89 close)
90{
91}
92
94 Env& env,
95 Account const& account,
96 STAmount const& asset1,
97 STAmount const& asset2,
98 CreateArg const& arg)
99 : AMM(env,
100 account,
101 asset1,
102 asset2,
103 arg.log,
104 arg.tfee,
105 arg.fee,
106 arg.flags,
107 arg.seq,
108 arg.ms,
109 arg.err,
110 arg.close)
111{
112}
113
114[[nodiscard]] AccountID
116 std::uint32_t tfee,
119 std::optional<ter> const& ter)
120{
121 Json::Value jv;
122 jv[jss::Account] = creatorAccount_.human();
123 jv[jss::Amount] = asset1_.getJson(JsonOptions::none);
124 jv[jss::Amount2] = asset2_.getJson(JsonOptions::none);
125 jv[jss::TradingFee] = tfee;
126 jv[jss::TransactionType] = jss::AMMCreate;
127 if (flags)
128 jv[jss::Flags] = *flags;
129 if (fee_ != 0)
130 jv[sfFee] = std::to_string(fee_);
131 else
132 jv[jss::Fee] = std::to_string(env_.current()->fees().increment.drops());
133 submit(jv, seq, ter);
134
135 if (!ter || env_.ter() == tesSUCCESS)
136 {
137 if (auto const amm = env_.current()->read(
139 {
140 return amm->getAccountID(sfAccount);
141 }
142 }
143 return {};
144}
145
148 std::optional<AccountID> const& account,
149 std::optional<std::string> const& ledgerIndex,
152 std::optional<AccountID> const& ammAccount,
153 bool ignoreParams,
154 unsigned apiVersion) const
155{
156 Json::Value jv;
157 if (account)
158 jv[jss::account] = to_string(*account);
159 if (ledgerIndex)
160 jv[jss::ledger_index] = *ledgerIndex;
161 if (!ignoreParams)
162 {
163 if (issue1 || issue2)
164 {
165 if (issue1)
166 jv[jss::asset] =
167 STIssue(sfAsset, *issue1).getJson(JsonOptions::none);
168 if (issue2)
169 jv[jss::asset2] =
170 STIssue(sfAsset2, *issue2).getJson(JsonOptions::none);
171 }
172 else if (!ammAccount)
173 {
174 jv[jss::asset] =
176 jv[jss::asset2] =
178 }
179 if (ammAccount)
180 jv[jss::amm_account] = to_string(*ammAccount);
181 }
182 auto jr =
183 (apiVersion == RPC::apiInvalidVersion
184 ? env_.rpc("json", "amm_info", to_string(jv))
185 : env_.rpc(apiVersion, "json", "amm_info", to_string(jv)));
186 if (jr.isObject() && jr.isMember(jss::result) &&
187 jr[jss::result].isMember(jss::status))
188 return jr[jss::result];
189 return Json::nullValue;
190}
191
194 Issue const& issue1,
195 Issue const& issue2,
196 std::optional<AccountID> const& account) const
197{
198 if (auto const amm =
200 {
201 auto const ammAccountID = amm->getAccountID(sfAccount);
202 auto const [asset1Balance, asset2Balance] = ammPoolHolds(
203 *env_.current(),
204 ammAccountID,
205 issue1,
206 issue2,
208 env_.journal);
209 auto const lptAMMBalance = account
210 ? ammLPHolds(*env_.current(), *amm, *account, env_.journal)
211 : amm->getFieldAmount(sfLPTokenBalance);
212 return {asset1Balance, asset2Balance, lptAMMBalance};
213 }
214 return {STAmount{}, STAmount{}, STAmount{}};
215}
216
217bool
219 STAmount const& asset1,
220 STAmount const& asset2,
221 IOUAmount const& lpt,
222 std::optional<AccountID> const& account) const
223{
224 auto const [asset1Balance, asset2Balance, lptAMMBalance] =
225 balances(asset1.issue(), asset2.issue(), account);
226 return asset1 == asset1Balance && asset2 == asset2Balance &&
227 lptAMMBalance == STAmount{lpt, lptIssue_};
228}
229
232{
233 if (account)
234 return accountHolds(
235 *env_.current(),
236 *account,
237 lptIssue_,
240 .iou();
241 if (auto const amm =
243 return amm->getFieldAmount(sfLPTokenBalance).iou();
244 return IOUAmount{0};
245}
246
247bool
248AMM::expectLPTokens(AccountID const& account, IOUAmount const& expTokens) const
249{
250 if (auto const amm =
252 {
253 auto const lptAMMBalance =
254 ammLPHolds(*env_.current(), *amm, account, env_.journal);
255 return lptAMMBalance == STAmount{expTokens, lptIssue_};
256 }
257 return false;
258}
259
260bool
264 IOUAmount expectedPrice) const
265{
266 return expectAuctionSlot([&](std::uint32_t slotFee,
267 std::optional<std::uint8_t> slotInterval,
268 IOUAmount const& slotPrice,
269 auto const&) {
270 return slotFee == fee &&
271 // Auction slot might be expired, in which case slotInterval is
272 // 0
273 ((!timeSlot && slotInterval == 0) || slotInterval == timeSlot) &&
274 slotPrice == expectedPrice;
275 });
276}
277
278bool
280{
283 IOUAmount const&,
284 STArray const& accounts) {
285 for (auto const& account : accounts)
286 {
287 if (std::find(
288 authAccounts.cbegin(),
289 authAccounts.cend(),
290 account.getAccountID(sfAccount)) == authAccounts.end())
291 return false;
292 }
293 return true;
294 });
295}
296
297bool
299{
300 auto const amm =
302 return amm && (*amm)[sfTradingFee] == fee;
303}
304
305bool
307{
308 return env_.current()->read(keylet::account(ammAccount_)) != nullptr &&
310 nullptr;
311}
312
313bool
315 STAmount const& asset1,
316 STAmount const& asset2,
317 IOUAmount const& balance,
318 std::optional<AccountID> const& account,
319 std::optional<std::string> const& ledger_index,
320 std::optional<AccountID> const& ammAccount) const
321{
322 auto const jv = ammRpcInfo(
323 account, ledger_index, std::nullopt, std::nullopt, ammAccount);
324 return expectAmmInfo(asset1, asset2, balance, jv);
325}
326
327bool
329 STAmount const& asset1,
330 STAmount const& asset2,
331 IOUAmount const& balance,
332 Json::Value const& jvres) const
333{
334 if (!jvres.isMember(jss::amm))
335 return false;
336 auto const& jv = jvres[jss::amm];
337 if (!jv.isMember(jss::amount) || !jv.isMember(jss::amount2) ||
338 !jv.isMember(jss::lp_token))
339 return false;
340 STAmount asset1Info;
341 if (!amountFromJsonNoThrow(asset1Info, jv[jss::amount]))
342 return false;
343 STAmount asset2Info;
344 if (!amountFromJsonNoThrow(asset2Info, jv[jss::amount2]))
345 return false;
346 STAmount lptBalance;
347 if (!amountFromJsonNoThrow(lptBalance, jv[jss::lp_token]))
348 return false;
349 // ammRpcInfo returns unordered assets
350 if (asset1Info.issue() != asset1.issue())
351 std::swap(asset1Info, asset2Info);
352 return asset1 == asset1Info && asset2 == asset2Info &&
353 lptBalance == STAmount{balance, lptIssue_};
354}
355
356void
358 Json::Value& jv,
360{
361 if (assets)
362 {
363 jv[jss::Asset] =
364 STIssue(sfAsset, assets->first).getJson(JsonOptions::none);
365 jv[jss::Asset2] =
366 STIssue(sfAsset, assets->second).getJson(JsonOptions::none);
367 }
368 else
369 {
370 jv[jss::Asset] =
372 jv[jss::Asset2] =
374 }
375}
376
379 std::optional<Account> const& account,
380 Json::Value& jv,
383 std::optional<ter> const& ter)
384{
385 auto const& acct = account ? *account : creatorAccount_;
386 auto const lpTokens = getLPTokensBalance(acct);
387 jv[jss::Account] = acct.human();
388 setTokens(jv, assets);
389 jv[jss::TransactionType] = jss::AMMDeposit;
390 if (fee_ != 0)
391 jv[jss::Fee] = std::to_string(fee_);
392 submit(jv, seq, ter);
393 return getLPTokensBalance(acct) - lpTokens;
394}
395
398 std::optional<Account> const& account,
399 LPToken tokens,
400 std::optional<STAmount> const& asset1In,
402 std::optional<ter> const& ter)
403{
404 return deposit(
405 account,
406 tokens,
407 asset1In,
410 flags,
414 ter);
415}
416
419 std::optional<Account> const& account,
420 STAmount const& asset1In,
421 std::optional<STAmount> const& asset2In,
422 std::optional<STAmount> const& maxEP,
424 std::optional<ter> const& ter)
425{
426 assert(!(asset2In && maxEP));
427 return deposit(
428 account,
430 asset1In,
431 asset2In,
432 maxEP,
433 flags,
437 ter);
438}
439
442 std::optional<Account> const& account,
444 std::optional<STAmount> const& asset1In,
445 std::optional<STAmount> const& asset2In,
446 std::optional<STAmount> const& maxEP,
451 std::optional<ter> const& ter)
452{
453 Json::Value jv;
454 if (tokens)
455 tokens->tokens(lptIssue_).setJson(jv[jss::LPTokenOut]);
456 if (asset1In)
457 asset1In->setJson(jv[jss::Amount]);
458 if (asset2In)
459 asset2In->setJson(jv[jss::Amount2]);
460 if (maxEP)
461 maxEP->setJson(jv[jss::EPrice]);
462 if (tfee)
463 jv[jss::TradingFee] = *tfee;
464 std::uint32_t jvflags = 0;
465 if (flags)
466 jvflags = *flags;
467 // If including asset1In and asset2In or tokens as
468 // deposit min amounts then must set the flags
469 // explicitly instead of relying on this logic.
470 if (!(jvflags & tfDepositSubTx))
471 {
472 if (tokens && !asset1In)
473 jvflags |= tfLPToken;
474 else if (tokens && asset1In)
475 jvflags |= tfOneAssetLPToken;
476 else if (asset1In && asset2In)
477 jvflags |= tfTwoAsset;
478 else if (maxEP && asset1In)
479 jvflags |= tfLimitLPToken;
480 else if (asset1In)
481 jvflags |= tfSingleAsset;
482 }
483 jv[jss::Flags] = jvflags;
484 return deposit(account, jv, assets, seq, ter);
485}
486
489{
490 return deposit(
491 arg.account,
492 arg.tokens,
493 arg.asset1In,
494 arg.asset2In,
495 arg.maxEP,
496 arg.flags,
497 arg.assets,
498 arg.seq,
499 arg.tfee,
500 arg.err);
501}
502
505 std::optional<Account> const& account,
506 Json::Value& jv,
509 std::optional<ter> const& ter)
510{
511 auto const& acct = account ? *account : creatorAccount_;
512 auto const lpTokens = getLPTokensBalance(acct);
513 jv[jss::Account] = acct.human();
514 setTokens(jv, assets);
515 jv[jss::TransactionType] = jss::AMMWithdraw;
516 if (fee_ != 0)
517 jv[jss::Fee] = std::to_string(fee_);
518 submit(jv, seq, ter);
519 return lpTokens - getLPTokensBalance(acct);
520}
521
524 std::optional<Account> const& account,
525 std::optional<LPToken> const& tokens,
526 std::optional<STAmount> const& asset1Out,
528 std::optional<ter> const& ter)
529{
530 return withdraw(
531 account,
532 tokens,
533 asset1Out,
536 flags,
539 ter);
540}
541
544 std::optional<Account> const& account,
545 STAmount const& asset1Out,
546 std::optional<STAmount> const& asset2Out,
547 std::optional<IOUAmount> const& maxEP,
548 std::optional<ter> const& ter)
549{
550 assert(!(asset2Out && maxEP));
551 return withdraw(
552 account,
554 asset1Out,
555 asset2Out,
556 maxEP,
560 ter);
561}
562
565 std::optional<Account> const& account,
566 std::optional<LPToken> const& tokens,
567 std::optional<STAmount> const& asset1Out,
568 std::optional<STAmount> const& asset2Out,
569 std::optional<IOUAmount> const& maxEP,
573 std::optional<ter> const& ter)
574{
575 Json::Value jv;
576 if (tokens)
577 tokens->tokens(lptIssue_).setJson(jv[jss::LPTokenIn]);
578 if (asset1Out)
579 asset1Out->setJson(jv[jss::Amount]);
580 if (asset2Out)
581 asset2Out->setJson(jv[jss::Amount2]);
582 if (maxEP)
583 {
584 STAmount const saMaxEP{*maxEP, lptIssue_};
585 saMaxEP.setJson(jv[jss::EPrice]);
586 }
587 std::uint32_t jvflags = 0;
588 if (flags)
589 jvflags = *flags;
590 if (!(jvflags & tfWithdrawSubTx))
591 {
592 if (tokens && !asset1Out)
593 jvflags |= tfLPToken;
594 else if (asset1Out && asset2Out)
595 jvflags |= tfTwoAsset;
596 else if (tokens && asset1Out)
597 jvflags |= tfOneAssetLPToken;
598 else if (asset1Out && maxEP)
599 jvflags |= tfLimitLPToken;
600 else if (asset1Out)
601 jvflags |= tfSingleAsset;
602 }
603 jv[jss::Flags] = jvflags;
604 return withdraw(account, jv, seq, assets, ter);
605}
606
609{
610 return withdraw(
611 arg.account,
612 arg.tokens,
613 arg.asset1Out,
614 arg.asset2Out,
615 arg.maxEP,
616 arg.flags,
617 arg.assets,
618 arg.seq,
619 arg.err);
620}
621
622void
624 std::optional<Account> const& account,
625 std::uint32_t feeVal,
629 std::optional<ter> const& ter)
630{
631 Json::Value jv;
632 jv[jss::Account] = account ? account->human() : creatorAccount_.human();
633 setTokens(jv, assets);
634 jv[jss::TradingFee] = feeVal;
635 jv[jss::TransactionType] = jss::AMMVote;
636 if (flags)
637 jv[jss::Flags] = *flags;
638 if (fee_ != 0)
639 jv[jss::Fee] = std::to_string(fee_);
640 submit(jv, seq, ter);
641}
642
643void
645{
646 return vote(arg.account, arg.tfee, arg.flags, arg.seq, arg.assets, arg.err);
647}
648
650AMM::bid(BidArg const& arg)
651{
652 if (auto const amm =
654 {
655 assert(
656 !env_.current()->rules().enabled(fixInnerObjTemplate) ||
657 amm->isFieldPresent(sfAuctionSlot));
658 if (amm->isFieldPresent(sfAuctionSlot))
659 {
660 auto const& auctionSlot =
661 static_cast<STObject const&>(amm->peekAtField(sfAuctionSlot));
662 lastPurchasePrice_ = auctionSlot[sfPrice].iou();
663 }
664 }
667
668 Json::Value jv;
669 jv[jss::Account] =
670 arg.account ? arg.account->human() : creatorAccount_.human();
671 setTokens(jv, arg.assets);
672 auto getBid = [&](auto const& bid) {
676 return toSTAmount(std::get<IOUAmount>(bid), lptIssue_);
677 else
678 return std::get<STAmount>(bid);
679 };
680 if (arg.bidMin)
681 {
682 STAmount saTokens = getBid(*arg.bidMin);
683 saTokens.setJson(jv[jss::BidMin]);
684 bidMin_ = saTokens.iou();
685 }
686 if (arg.bidMax)
687 {
688 STAmount saTokens = getBid(*arg.bidMax);
689 saTokens.setJson(jv[jss::BidMax]);
690 bidMax_ = saTokens.iou();
691 }
692 if (arg.authAccounts.size() > 0)
693 {
695 for (auto const& account : arg.authAccounts)
696 {
697 Json::Value acct;
698 Json::Value authAcct;
699 acct[jss::Account] = account.human();
700 authAcct[jss::AuthAccount] = acct;
701 accounts.append(authAcct);
702 }
703 jv[jss::AuthAccounts] = accounts;
704 }
705 if (arg.flags)
706 jv[jss::Flags] = *arg.flags;
707 jv[jss::TransactionType] = jss::AMMBid;
708 if (fee_ != 0)
709 jv[jss::Fee] = std::to_string(fee_);
710 return jv;
711}
712
713void
715 Json::Value const& jv,
717 std::optional<ter> const& ter)
718{
719 if (log_)
721 if (msig_)
722 {
723 if (seq && ter)
724 env_(jv, *msig_, *seq, *ter);
725 else if (seq)
726 env_(jv, *msig_, *seq);
727 else if (ter)
728 env_(jv, *msig_, *ter);
729 else
730 env_(jv, *msig_);
731 }
732 else if (seq && ter)
733 env_(jv, *seq, *ter);
734 else if (seq)
735 env_(jv, *seq);
736 else if (ter)
737 env_(jv, *ter);
738 else
739 env_(jv);
740 if (doClose_)
741 env_.close();
742}
743
744bool
746{
747 if (auto const amm =
749 {
750 assert(
751 !env_.current()->rules().enabled(fixInnerObjTemplate) ||
752 amm->isFieldPresent(sfAuctionSlot));
753 if (amm->isFieldPresent(sfAuctionSlot))
754 {
755 auto const& auctionSlot =
756 static_cast<STObject const&>(amm->peekAtField(sfAuctionSlot));
757 if (auctionSlot.isFieldPresent(sfAccount))
758 {
759 // This could fail in pre-fixInnerObjTemplate tests
760 // if the submitted transactions recreate one of
761 // the failure scenarios. Access as optional
762 // to avoid the failure.
763 auto const slotFee = auctionSlot[~sfDiscountedFee].value_or(0);
764 auto const slotInterval = ammAuctionTimeSlot(
765 env_.app().timeKeeper().now().time_since_epoch().count(),
766 auctionSlot);
767 auto const slotPrice = auctionSlot[sfPrice].iou();
768 auto const authAccounts =
769 auctionSlot.getFieldArray(sfAuthAccounts);
770 return cb(slotFee, slotInterval, slotPrice, authAccounts);
771 }
772 }
773 }
774 return false;
775}
776
777void
779{
780 Json::Value jv;
781 jv[jss::Account] = to_string(deleter);
782 setTokens(jv);
783 jv[jss::TransactionType] = jss::AMMDelete;
784 if (fee_ != 0)
785 jv[jss::Fee] = std::to_string(fee_);
786 submit(jv, std::nullopt, ter);
787}
788
789namespace amm {
791trust(AccountID const& account, STAmount const& amount, std::uint32_t flags)
792{
793 if (isXRP(amount))
794 Throw<std::runtime_error>("trust() requires IOU");
795 Json::Value jv;
796 jv[jss::Account] = to_string(account);
797 jv[jss::LimitAmount] = amount.getJson(JsonOptions::none);
798 jv[jss::TransactionType] = jss::TrustSet;
799 jv[jss::Flags] = flags;
800 return jv;
801}
803pay(Account const& account, AccountID const& to, STAmount const& amount)
804{
805 Json::Value jv;
806 jv[jss::Account] = account.human();
807 jv[jss::Amount] = amount.getJson(JsonOptions::none);
808 jv[jss::Destination] = to_string(to);
809 jv[jss::TransactionType] = jss::Payment;
810 return jv;
811}
812
815 Account const& issuer,
816 Account const& holder,
817 Issue const& asset,
818 Issue const& asset2,
819 std::optional<STAmount> const& amount)
820{
821 Json::Value jv;
822 jv[jss::TransactionType] = jss::AMMClawback;
823 jv[jss::Account] = issuer.human();
824 jv[jss::Holder] = holder.human();
825 jv[jss::Asset] = to_json(asset);
826 jv[jss::Asset2] = to_json(asset2);
827 if (amount)
828 jv[jss::Amount] = amount->getJson(JsonOptions::none);
829
830 return jv;
831}
832} // namespace amm
833} // namespace jtx
834} // namespace test
835} // namespace ripple
T cbegin(T... args)
Represents a JSON value.
Definition json_value.h:130
Value & append(Value const &value)
Append value to array at the end.
std::string toStyledString() const
bool isMember(char const *key) const
Return true if the object has a member named key.
virtual TimeKeeper & timeKeeper()=0
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:27
A currency issued by an account.
Definition Issue.h:14
void setJson(Json::Value &jv) const
Definition Issue.cpp:39
IOUAmount iou() const
Definition STAmount.cpp:280
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:753
XRPAmount xrp() const
Definition STAmount.cpp:264
void setJson(Json::Value &) const
Definition STAmount.cpp:624
Issue const & issue() const
Definition STAmount.h:477
Json::Value getJson(JsonOptions) const override
Definition STIssue.cpp:83
time_point now() const override
Returns the current time, using the server's clock.
Definition TimeKeeper.h:45
Convenience class to test AMM functionality.
Definition AMM.h:105
std::optional< IOUAmount > bidMin_
Definition AMM.h:115
Issue const lptIssue_
Definition AMM.h:122
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, unsigned apiVersion=RPC::apiInvalidVersion) const
Send amm_info RPC command.
Definition AMM.cpp:147
void submit(Json::Value const &jv, std::optional< jtx::seq > const &seq, std::optional< ter > const &ter)
Definition AMM.cpp:714
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:623
std::uint32_t const fee_
Definition AMM.h:120
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:115
bool expectAuctionSlot(std::uint32_t fee, std::optional< std::uint8_t > timeSlot, IOUAmount expectedPrice) const
Definition AMM.cpp:261
STAmount const asset2_
Definition AMM.h:109
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:193
STAmount const asset1_
Definition AMM.h:108
void ammDelete(AccountID const &deleter, std::optional< ter > const &ter=std::nullopt)
Definition AMM.cpp:778
IOUAmount tokens() const
Definition AMM.h:324
bool expectAmmInfo(STAmount const &asset1, STAmount const &asset2, IOUAmount const &balance, Json::Value const &jv) const
Definition AMM.cpp:328
IOUAmount lastPurchasePrice_
Definition AMM.h:114
AccountID const & ammAccount() const
Definition AMM.h:312
IOUAmount initialTokens()
Definition AMM.cpp:25
AccountID const ammAccount_
Definition AMM.h:121
bool expectTradingFee(std::uint16_t fee) const
Definition AMM.cpp:298
std::optional< msig > const msig_
Definition AMM.h:118
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:523
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:218
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:397
Account const creatorAccount_
Definition AMM.h:107
std::optional< IOUAmount > bidMax_
Definition AMM.h:116
IOUAmount getLPTokensBalance(std::optional< AccountID > const &account=std::nullopt) const
Definition AMM.cpp:231
Json::Value bid(BidArg const &arg)
Definition AMM.cpp:650
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:314
void setTokens(Json::Value &jv, std::optional< std::pair< Issue, Issue > > const &assets=std::nullopt)
Definition AMM.cpp:357
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, bool close=true)
Definition AMM.cpp:36
bool ammExists() const
Definition AMM.cpp:306
bool expectLPTokens(AccountID const &account, IOUAmount const &tokens) const
Definition AMM.cpp:248
Immutable cryptographic account descriptor.
Definition Account.h:20
std::string const & human() const
Returns the human readable public key.
Definition Account.h:99
A transaction testing environment.
Definition Env.h:102
TER ter() const
Return the TER for the last JTx.
Definition Env.h:579
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:312
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:103
bool enabled(uint256 feature) const
Definition Env.h:619
Application & app()
Definition Env.h:242
beast::Journal const journal
Definition Env.h:143
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:772
A balance matches.
Definition balance.h:20
Set the fee on a JTx.
Definition fee.h:18
Match set account flags.
Definition flags.h:109
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition ter.h:16
T cend(T... args)
T find(T... args)
T is_same_v
@ nullValue
'null' value
Definition json_value.h:19
@ arrayValue
array value (ordered list)
Definition json_value.h:25
static constexpr auto apiInvalidVersion
Definition ApiVersion.h:41
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
Definition Indexes.cpp:427
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Json::Value trust(AccountID const &account, STAmount const &amount, std::uint32_t flags=0)
Definition AMM.cpp:791
Json::Value ammClawback(Account const &issuer, Account const &holder, Issue const &asset, Issue const &asset2, std::optional< STAmount > const &amount)
Definition AMM.cpp:814
Json::Value pay(Account const &account, AccountID const &to, STAmount const &amount)
Definition AMM.cpp:803
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)
static Number number(STAmount const &a)
Definition AMM.cpp:17
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
constexpr std::uint32_t tfSingleAsset
Definition TxFlags.h:228
@ fhZERO_IF_FROZEN
Definition View.h:58
@ fhIGNORE_FREEZE
Definition View.h:58
bool isXRP(AccountID const &c)
Definition AccountID.h:71
std::optional< std::uint8_t > ammAuctionTimeSlot(std::uint64_t current, STObject const &auctionSlot)
Get time slot of the auction slot.
Definition AMMCore.cpp:89
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
constexpr std::uint32_t tfLimitLPToken
Definition TxFlags.h:231
Issue ammLPTIssue(Currency const &cur1, Currency const &cur2, AccountID const &ammAccountID)
Calculate LPT Issue from AMM asset pair.
Definition AMMCore.cpp:38
constexpr std::uint32_t tfOneAssetLPToken
Definition TxFlags.h:230
constexpr std::uint32_t tfTwoAsset
Definition TxFlags.h:229
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:94
Json::Value to_json(Asset const &asset)
Definition Asset.h:104
constexpr std::uint32_t tfDepositSubTx
Definition TxFlags.h:236
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:12
constexpr std::uint32_t tfLPToken
Definition TxFlags.h:225
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
@ tesSUCCESS
Definition TER.h:226
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition View.cpp:368
constexpr std::uint32_t tfWithdrawSubTx
Definition TxFlags.h:233
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
Number root2(Number f)
Definition Number.cpp:682
STL namespace.
std::vector< Account > authAccounts
Definition AMM.h:97
std::optional< std::variant< int, IOUAmount, STAmount > > bidMin
Definition AMM.h:95
std::optional< std::uint32_t > flags
Definition AMM.h:98
std::optional< std::variant< int, IOUAmount, STAmount > > bidMax
Definition AMM.h:96
std::optional< Account > account
Definition AMM.h:94
std::optional< std::pair< Issue, Issue > > assets
Definition AMM.h:99
std::optional< std::uint32_t > flags
Definition AMM.h:62
std::optional< jtx::seq > seq
Definition AMM.h:64
std::optional< Account > account
Definition AMM.h:57
std::optional< STAmount > asset1In
Definition AMM.h:59
std::optional< std::pair< Issue, Issue > > assets
Definition AMM.h:63
std::optional< ter > err
Definition AMM.h:66
std::optional< STAmount > maxEP
Definition AMM.h:61
std::optional< STAmount > asset2In
Definition AMM.h:60
std::optional< std::uint16_t > tfee
Definition AMM.h:65
std::optional< LPToken > tokens
Definition AMM.h:58
std::optional< ter > err
Definition AMM.h:89
std::optional< Account > account
Definition AMM.h:84
std::uint32_t tfee
Definition AMM.h:85
std::optional< jtx::seq > seq
Definition AMM.h:87
std::optional< std::uint32_t > flags
Definition AMM.h:86
std::optional< std::pair< Issue, Issue > > assets
Definition AMM.h:88
std::optional< STAmount > asset2Out
Definition AMM.h:74
std::optional< IOUAmount > maxEP
Definition AMM.h:75
std::optional< Account > account
Definition AMM.h:71
std::optional< std::uint32_t > flags
Definition AMM.h:76
std::optional< STAmount > asset1Out
Definition AMM.h:73
std::optional< std::pair< Issue, Issue > > assets
Definition AMM.h:77
std::optional< LPToken > tokens
Definition AMM.h:72
std::optional< ter > err
Definition AMM.h:79
std::optional< jtx::seq > seq
Definition AMM.h:78
Set the sequence number on a JTx.
Definition seq.h:15
T swap(T... args)
T to_string(T... args)