xrpld
Loading...
Searching...
No Matches
Freeze_test.cpp
1#include <test/jtx/AMM.h>
2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/balance.h>
7#include <test/jtx/check.h>
8#include <test/jtx/flags.h>
9#include <test/jtx/offer.h>
10#include <test/jtx/owners.h>
11#include <test/jtx/paths.h>
12#include <test/jtx/pay.h>
13#include <test/jtx/sendmax.h>
14#include <test/jtx/ter.h>
15#include <test/jtx/token.h>
16#include <test/jtx/trust.h>
17#include <test/jtx/txflags.h>
18
19#include <xrpl/basics/base_uint.h>
20#include <xrpl/beast/unit_test/suite.h>
21#include <xrpl/protocol/AccountID.h>
22#include <xrpl/protocol/Feature.h>
23#include <xrpl/protocol/Indexes.h>
24#include <xrpl/protocol/LedgerFormats.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/SeqProxy.h>
27#include <xrpl/protocol/TER.h>
28#include <xrpl/protocol/TxFlags.h>
29#include <xrpl/protocol/UintTypes.h>
30#include <xrpl/protocol/jss.h>
31
32#include <cstddef>
33#include <cstdint>
34#include <iterator>
35#include <set>
36
37namespace xrpl {
38
40{
41 void
43 {
44 testcase("RippleState Freeze");
45
46 using namespace test::jtx;
47 Env env(*this, features);
48
49 Account const g1{"G1"};
50 Account const alice{"alice"};
51 Account const bob{"bob"};
52
53 env.fund(XRP(1000), g1, alice, bob);
54 env.close();
55
56 env.trust(g1["USD"](100), bob);
57 env.trust(g1["USD"](100), alice);
58 env.close();
59
60 env(pay(g1, bob, g1["USD"](10)));
61 env(pay(g1, alice, g1["USD"](100)));
62 env.close();
63
64 env(offer(alice, XRP(500), g1["USD"](100)));
65 env.close();
66
67 {
68 auto lines = getAccountLines(env, bob);
69 if (!BEAST_EXPECT(checkArraySize(lines[jss::lines], 1u)))
70 return;
71 BEAST_EXPECT(lines[jss::lines][0u][jss::account] == g1.human());
72 BEAST_EXPECT(lines[jss::lines][0u][jss::limit] == "100");
73 BEAST_EXPECT(lines[jss::lines][0u][jss::balance] == "10");
74 }
75
76 {
77 auto lines = getAccountLines(env, alice);
78 if (!BEAST_EXPECT(checkArraySize(lines[jss::lines], 1u)))
79 return;
80 BEAST_EXPECT(lines[jss::lines][0u][jss::account] == g1.human());
81 BEAST_EXPECT(lines[jss::lines][0u][jss::limit] == "100");
82 BEAST_EXPECT(lines[jss::lines][0u][jss::balance] == "100");
83 }
84
85 {
86 // Account with line unfrozen (proving operations normally work)
87 // test: can make Payment on that line
88 env(pay(alice, bob, g1["USD"](1)));
89
90 // test: can receive Payment on that line
91 env(pay(bob, alice, g1["USD"](1)));
92 env.close();
93 }
94
95 {
96 // Is created via a TrustSet with SetFreeze flag
97 // test: sets LowFreeze | HighFreeze flags
98 env(trust(g1, bob["USD"](0), tfSetFreeze));
99 auto affected =
100 env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
101 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
102 return;
103 auto ff = affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
104 BEAST_EXPECT(
105 ff[sfLowLimit.fieldName] ==
106 g1["USD"](0).value().getJson(JsonOptions::Values::None));
107 BEAST_EXPECT(ff[jss::Flags].asUInt() & lsfLowFreeze);
108 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfHighFreeze));
109 env.close();
110 }
111
112 {
113 // Account with line frozen by issuer
114 // test: can buy more assets on that line
115 env(offer(bob, g1["USD"](5), XRP(25)));
116 auto affected =
117 env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
118 if (!BEAST_EXPECT(checkArraySize(affected, 5u)))
119 return;
120 auto ff = affected[3u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
121 BEAST_EXPECT(
122 ff[sfHighLimit.fieldName] ==
123 bob["USD"](100).value().getJson(JsonOptions::Values::None));
124 auto amt = STAmount{Issue{toCurrency("USD"), noAccount()}, -15}.value().getJson(
126 BEAST_EXPECT(ff[sfBalance.fieldName] == amt);
127 env.close();
128 }
129
130 {
131 // test: can not sell assets from that line
132 env(offer(bob, XRP(1), g1["USD"](5)), Ter(tecUNFUNDED_OFFER));
133
134 // test: can receive Payment on that line
135 env(pay(alice, bob, g1["USD"](1)));
136
137 // test: can not make Payment from that line
138 env(pay(bob, alice, g1["USD"](1)), Ter(tecPATH_DRY));
139 }
140
141 {
142 // check G1 account lines
143 // test: shows freeze
144 auto lines = getAccountLines(env, g1);
145 json::Value bobLine;
146 for (auto const& it : lines[jss::lines])
147 {
148 if (it[jss::account] == bob.human())
149 {
150 bobLine = it;
151 break;
152 }
153 }
154 if (!BEAST_EXPECT(bobLine))
155 return;
156 BEAST_EXPECT(bobLine[jss::freeze] == true);
157 BEAST_EXPECT(bobLine[jss::balance] == "-16");
158 }
159
160 {
161 // test: shows freeze peer
162 auto lines = getAccountLines(env, bob);
163 json::Value g1Line;
164 for (auto const& it : lines[jss::lines])
165 {
166 if (it[jss::account] == g1.human())
167 {
168 g1Line = it;
169 break;
170 }
171 }
172 if (!BEAST_EXPECT(g1Line))
173 return;
174 BEAST_EXPECT(g1Line[jss::freeze_peer] == true);
175 BEAST_EXPECT(g1Line[jss::balance] == "16");
176 }
177
178 {
179 // Is cleared via a TrustSet with ClearFreeze flag
180 // test: sets LowFreeze | HighFreeze flags
181 env(trust(g1, bob["USD"](0), tfClearFreeze));
182 auto affected =
183 env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
184 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
185 return;
186 auto ff = affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
187 BEAST_EXPECT(
188 ff[sfLowLimit.fieldName] ==
189 g1["USD"](0).value().getJson(JsonOptions::Values::None));
190 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfLowFreeze));
191 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfHighFreeze));
192 env.close();
193 }
194 }
195
196 void
198 {
199 testcase("Deep Freeze");
200
201 using namespace test::jtx;
202 Env env(*this, features);
203
204 Account const g1{"G1"};
205 Account const a1{"A1"};
206
207 env.fund(XRP(10000), g1, a1);
208 env.close();
209
210 env.trust(g1["USD"](1000), a1);
211 env.close();
212
213 if (features[featureDeepFreeze])
214 {
215 // test: Issuer deep freezing the trust line in a single
216 // transaction
217 env(trust(g1, a1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
218 {
219 auto const flags = getTrustlineFlags(env, 2u, 1u);
220 BEAST_EXPECT(flags & lsfLowFreeze);
221 BEAST_EXPECT(flags & lsfLowDeepFreeze);
222 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
223 env.close();
224 }
225
226 // test: Issuer clearing deep freeze and normal freeze in a single
227 // transaction
228 env(trust(g1, a1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
229 {
230 auto const flags = getTrustlineFlags(env, 2u, 1u);
231 BEAST_EXPECT(!(flags & (lsfLowFreeze | lsfLowDeepFreeze)));
232 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
233 env.close();
234 }
235
236 // test: Issuer deep freezing not already frozen line must fail
237 env(trust(g1, a1["USD"](0), tfSetDeepFreeze), Ter(tecNO_PERMISSION));
238
239 env(trust(g1, a1["USD"](0), tfSetFreeze));
240 env.close();
241
242 // test: Issuer deep freezing already frozen trust line
243 env(trust(g1, a1["USD"](0), tfSetDeepFreeze));
244 {
245 auto const flags = getTrustlineFlags(env, 2u, 1u);
246 BEAST_EXPECT(flags & lsfLowFreeze);
247 BEAST_EXPECT(flags & lsfLowDeepFreeze);
248 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
249 env.close();
250 }
251
252 // test: Holder clearing freeze flags has no effect. Each sides'
253 // flags are independent
254 env(trust(a1, g1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
255 {
256 auto const flags = getTrustlineFlags(env, 2u, 1u);
257 BEAST_EXPECT(flags & lsfLowFreeze);
258 BEAST_EXPECT(flags & lsfLowDeepFreeze);
259 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
260 env.close();
261 }
262
263 // test: Issuer can't clear normal freeze when line is deep frozen
264 env(trust(g1, a1["USD"](0), tfClearFreeze), Ter(tecNO_PERMISSION));
265
266 // test: Issuer clearing deep freeze but normal freeze is still in
267 // effect
268 env(trust(g1, a1["USD"](0), tfClearDeepFreeze));
269 {
270 auto const flags = getTrustlineFlags(env, 2u, 1u);
271 BEAST_EXPECT(flags & lsfLowFreeze);
272 BEAST_EXPECT(!(flags & lsfLowDeepFreeze));
273 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
274 env.close();
275 }
276 }
277 else
278 {
279 // test: applying deep freeze before amendment fails
280 env(trust(g1, a1["USD"](0), tfSetDeepFreeze), Ter(temINVALID_FLAG));
281
282 // test: clearing deep freeze before amendment fails
283 env(trust(g1, a1["USD"](0), tfClearDeepFreeze), Ter(temINVALID_FLAG));
284 }
285 }
286
287 void
289 {
290 testcase("Create Frozen Trustline");
291
292 using namespace test::jtx;
293 Env env(*this, features);
294
295 Account const g1{"G1"};
296 Account const a1{"A1"};
297
298 env.fund(XRP(10000), g1, a1);
299 env.close();
300
301 // test: can create frozen trustline
302 {
303 env(trust(g1, a1["USD"](1000), tfSetFreeze));
304 auto const flags = getTrustlineFlags(env, 5u, 3u, false);
305 BEAST_EXPECT(flags & lsfLowFreeze);
306 env.close();
307 env.require(lines(a1, 1));
308 }
309
310 // Cleanup
311 env(trust(g1, a1["USD"](0), tfClearFreeze));
312 env.close();
313 env.require(lines(g1, 0));
314 env.require(lines(a1, 0));
315
316 // test: cannot create deep frozen trustline without normal freeze
317 if (features[featureDeepFreeze])
318 {
319 env(trust(g1, a1["USD"](1000), tfSetDeepFreeze), Ter(tecNO_PERMISSION));
320 env.close();
321 env.require(lines(a1, 0));
322 }
323
324 // test: can create deep frozen trustline together with normal freeze
325 if (features[featureDeepFreeze])
326 {
327 env(trust(g1, a1["USD"](1000), tfSetFreeze | tfSetDeepFreeze));
328 auto const flags = getTrustlineFlags(env, 5u, 3u, false);
329 BEAST_EXPECT(flags & lsfLowFreeze);
330 BEAST_EXPECT(flags & lsfLowDeepFreeze);
331 env.close();
332 env.require(lines(a1, 1));
333 }
334 }
335
336 void
338 {
339 testcase("Freeze Set and Clear");
340
341 using namespace test::jtx;
342 Env env(*this, features);
343
344 Account const g1{"G1"};
345 Account const a1{"A1"};
346
347 env.fund(XRP(10000), g1, a1);
348 env.close();
349
350 env.trust(g1["USD"](1000), a1);
351 env.close();
352
353 if (features[featureDeepFreeze])
354 {
355 // test: can't have both set and clear flag families in the same
356 // transaction
357 env(trust(g1, a1["USD"](0), tfSetFreeze | tfClearFreeze), Ter(tecNO_PERMISSION));
358 env(trust(g1, a1["USD"](0), tfSetFreeze | tfClearDeepFreeze), Ter(tecNO_PERMISSION));
359 env(trust(g1, a1["USD"](0), tfSetDeepFreeze | tfClearFreeze), Ter(tecNO_PERMISSION));
360 env(trust(g1, a1["USD"](0), tfSetDeepFreeze | tfClearDeepFreeze),
361 Ter(tecNO_PERMISSION));
362 }
363 else
364 {
365 // test: old behavior, transaction succeed with no effect on a
366 // trust line
367 env(trust(g1, a1["USD"](0), tfSetFreeze | tfClearFreeze));
368 {
369 auto affected =
370 env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
371 BEAST_EXPECT(checkArraySize(affected, 1u)); // means no trustline changes
372 }
373 }
374 }
375
376 void
378 {
379 testcase("Global Freeze");
380
381 using namespace test::jtx;
382 Env env(*this, features);
383
384 Account const g1{"G1"};
385 Account const a1{"A1"};
386 Account const a2{"A2"};
387 Account const a3{"A3"};
388 Account const a4{"A4"};
389
390 env.fund(XRP(12000), g1);
391 env.fund(XRP(1000), a1);
392 env.fund(XRP(20000), a2, a3, a4);
393 env.close();
394
395 env.trust(g1["USD"](1200), a1);
396 env.trust(g1["USD"](200), a2);
397 env.trust(g1["BTC"](100), a3);
398 env.trust(g1["BTC"](100), a4);
399 env.close();
400
401 env(pay(g1, a1, g1["USD"](1000)));
402 env(pay(g1, a2, g1["USD"](100)));
403 env(pay(g1, a3, g1["BTC"](100)));
404 env(pay(g1, a4, g1["BTC"](100)));
405 env.close();
406
407 env(offer(g1, XRP(10000), g1["USD"](100)), Txflags(tfPassive));
408 env(offer(g1, g1["USD"](100), XRP(10000)), Txflags(tfPassive));
409 env(offer(a1, XRP(10000), g1["USD"](100)), Txflags(tfPassive));
410 env(offer(a2, g1["USD"](100), XRP(10000)), Txflags(tfPassive));
411 env.close();
412
413 {
414 // Is toggled via AccountSet using SetFlag and ClearFlag
415 // test: SetFlag GlobalFreeze
416 env.require(Nflags(g1, asfGlobalFreeze));
417 env(fset(g1, asfGlobalFreeze));
418 env.require(Flags(g1, asfGlobalFreeze));
419 env.require(Nflags(g1, asfNoFreeze));
420
421 // test: ClearFlag GlobalFreeze
422 env(fclear(g1, asfGlobalFreeze));
423 env.require(Nflags(g1, asfGlobalFreeze));
424 env.require(Nflags(g1, asfNoFreeze));
425 }
426
427 {
428 // Account without GlobalFreeze (proving operations normally work)
429 // test: visible offers where taker_pays is unfrozen issuer
430 auto offers = env.rpc(
431 "book_offers", std::string("USD/") + g1.human(), "XRP")[jss::result][jss::offers];
432 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
433 return;
434 std::set<std::string> accounts;
435 for (auto const& offer : offers)
436 {
437 accounts.insert(offer[jss::Account].asString());
438 }
439 BEAST_EXPECT(accounts.find(a2.human()) != std::end(accounts));
440 BEAST_EXPECT(accounts.find(g1.human()) != std::end(accounts));
441
442 // test: visible offers where taker_gets is unfrozen issuer
443 offers = env.rpc(
444 "book_offers", "XRP", std::string("USD/") + g1.human())[jss::result][jss::offers];
445 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
446 return;
447 accounts.clear();
448 for (auto const& offer : offers)
449 {
450 accounts.insert(offer[jss::Account].asString());
451 }
452 BEAST_EXPECT(accounts.find(a1.human()) != std::end(accounts));
453 BEAST_EXPECT(accounts.find(g1.human()) != std::end(accounts));
454 }
455
456 {
457 // Offers/Payments
458 // test: assets can be bought on the market
459 env(offer(a3, g1["BTC"](1), XRP(1)));
460
461 // test: assets can be sold on the market
462 env(offer(a4, XRP(1), g1["BTC"](1)));
463
464 // test: direct issues can be sent
465 env(pay(g1, a2, g1["USD"](1)));
466
467 // test: direct redemptions can be sent
468 env(pay(a2, g1, g1["USD"](1)));
469
470 // test: via rippling can be sent
471 env(pay(a2, a1, g1["USD"](1)));
472
473 // test: via rippling can be sent back
474 env(pay(a1, a2, g1["USD"](1)));
475 }
476
477 {
478 // Account with GlobalFreeze
479 // set GlobalFreeze first
480 // test: SetFlag GlobalFreeze will toggle back to freeze
481 env.require(Nflags(g1, asfGlobalFreeze));
482 env(fset(g1, asfGlobalFreeze));
483 env.require(Flags(g1, asfGlobalFreeze));
484 env.require(Nflags(g1, asfNoFreeze));
485
486 // test: assets can't be bought on the market
487 env(offer(a3, g1["BTC"](1), XRP(1)), Ter(tecFROZEN));
488
489 // test: assets can't be sold on the market
490 env(offer(a4, XRP(1), g1["BTC"](1)), Ter(tecFROZEN));
491 }
492
493 {
494 // offers are filtered (seems to be broken?)
495 // test: account_offers always shows own offers
496 auto offers = getAccountOffers(env, g1)[jss::offers];
497 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
498 return;
499
500 // test: book_offers shows offers
501 // (should these actually be filtered?)
502 offers = env.rpc(
503 "book_offers", "XRP", std::string("USD/") + g1.human())[jss::result][jss::offers];
504 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
505 return;
506
507 offers = env.rpc(
508 "book_offers", std::string("USD/") + g1.human(), "XRP")[jss::result][jss::offers];
509 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
510 return;
511 }
512
513 {
514 // Payments
515 // test: direct issues can be sent
516 env(pay(g1, a2, g1["USD"](1)));
517
518 // test: direct redemptions can be sent
519 env(pay(a2, g1, g1["USD"](1)));
520
521 // test: via rippling cant be sent
522 env(pay(a2, a1, g1["USD"](1)), Ter(tecPATH_DRY));
523 }
524 }
525
526 void
528 {
529 testcase("No Freeze");
530
531 using namespace test::jtx;
532 Env env(*this, features);
533
534 Account const g1{"G1"};
535 Account const a1{"A1"};
536 Account const frozenAcc{"A2"};
537 Account const deepFrozenAcc{"A3"};
538
539 env.fund(XRP(12000), g1);
540 env.fund(XRP(1000), a1);
541 env.fund(XRP(1000), frozenAcc);
542 env.fund(XRP(1000), deepFrozenAcc);
543 env.close();
544
545 env.trust(g1["USD"](1000), a1);
546 env.trust(g1["USD"](1000), frozenAcc);
547 env.trust(g1["USD"](1000), deepFrozenAcc);
548 env.close();
549
550 env(pay(g1, a1, g1["USD"](1000)));
551 env(pay(g1, frozenAcc, g1["USD"](1000)));
552 env(pay(g1, deepFrozenAcc, g1["USD"](1000)));
553
554 // Freezing and deep freezing some of the trust lines to check deep
555 // freeze and clearing of freeze separately
556 env(trust(g1, frozenAcc["USD"](0), tfSetFreeze));
557 {
558 auto const flags = getTrustlineFlags(env, 2u, 1u);
559 BEAST_EXPECT(flags & lsfLowFreeze);
560 BEAST_EXPECT(!(flags & lsfHighFreeze));
561 }
562 if (features[featureDeepFreeze])
563 {
564 env(trust(g1, deepFrozenAcc["USD"](0), tfSetFreeze | tfSetDeepFreeze));
565 {
566 auto const flags = getTrustlineFlags(env, 2u, 1u);
567 BEAST_EXPECT(!(flags & (lsfLowFreeze | lsfLowDeepFreeze)));
568 BEAST_EXPECT(flags & lsfHighFreeze);
569 BEAST_EXPECT(flags & lsfHighDeepFreeze);
570 }
571 }
572 env.close();
573
574 // TrustSet NoFreeze
575 // test: should set NoFreeze in Flags
576 env.require(Nflags(g1, asfNoFreeze));
577 env(fset(g1, asfNoFreeze));
578 env.require(Flags(g1, asfNoFreeze));
579 env.require(Nflags(g1, asfGlobalFreeze));
580
581 // test: cannot be cleared
582 env(fclear(g1, asfNoFreeze));
583 env.require(Flags(g1, asfNoFreeze));
584 env.require(Nflags(g1, asfGlobalFreeze));
585
586 // test: can set GlobalFreeze
587 env(fset(g1, asfGlobalFreeze));
588 env.require(Flags(g1, asfNoFreeze));
589 env.require(Flags(g1, asfGlobalFreeze));
590
591 // test: cannot unset GlobalFreeze
592 env(fclear(g1, asfGlobalFreeze));
593 env.require(Flags(g1, asfNoFreeze));
594 env.require(Flags(g1, asfGlobalFreeze));
595
596 // test: trustlines can't be frozen when no freeze enacted
597 if (features[featureDeepFreeze])
598 {
599 env(trust(g1, a1["USD"](0), tfSetFreeze), Ter(tecNO_PERMISSION));
600
601 // test: cannot deep freeze already frozen line when no freeze
602 // enacted
603 env(trust(g1, frozenAcc["USD"](0), tfSetDeepFreeze), Ter(tecNO_PERMISSION));
604 }
605 else
606 {
607 // test: previous functionality, checking there's no changes to a
608 // trust line
609 env(trust(g1, a1["USD"](0), tfSetFreeze));
610 auto affected =
611 env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
612 if (!BEAST_EXPECT(checkArraySize(affected, 1u)))
613 return;
614
615 auto let = affected[0u][sfModifiedNode.fieldName][sfLedgerEntryType.fieldName];
616 BEAST_EXPECT(let == jss::AccountRoot);
617 }
618
619 // test: can clear freeze on account
620 env(trust(g1, frozenAcc["USD"](0), tfClearFreeze));
621 {
622 auto const flags = getTrustlineFlags(env, 2u, 1u);
623 BEAST_EXPECT(!(flags & lsfLowFreeze));
624 }
625
626 if (features[featureDeepFreeze])
627 {
628 // test: can clear deep freeze on account
629 env(trust(g1, deepFrozenAcc["USD"](0), tfClearDeepFreeze));
630 {
631 auto const flags = getTrustlineFlags(env, 2u, 1u);
632 BEAST_EXPECT(flags & lsfHighFreeze);
633 BEAST_EXPECT(!(flags & lsfHighDeepFreeze));
634 }
635 }
636 }
637
638 void
640 {
641 testcase("Offers for Frozen Trust Lines");
642
643 using namespace test::jtx;
644 Env env(*this, features);
645
646 Account const g1{"G1"};
647 Account const a2{"A2"};
648 Account const a3{"A3"};
649 Account const a4{"A4"};
650
651 env.fund(XRP(1000), g1, a3, a4);
652 env.fund(XRP(2000), a2);
653 env.close();
654
655 env.trust(g1["USD"](1000), a2);
656 env.trust(g1["USD"](2000), a3);
657 env.trust(g1["USD"](2000), a4);
658 env.close();
659
660 env(pay(g1, a3, g1["USD"](2000)));
661 env(pay(g1, a4, g1["USD"](2000)));
662 env.close();
663
664 env(offer(a3, XRP(1000), g1["USD"](1000)), Txflags(tfPassive));
665 env.close();
666
667 // removal after successful payment
668 // test: make a payment with partially consuming offer
669 env(pay(a2, g1, g1["USD"](1)), Paths(g1["USD"]), Sendmax(XRP(1)));
670 env.close();
671
672 // test: offer was only partially consumed
673 auto offers = getAccountOffers(env, a3)[jss::offers];
674 if (!BEAST_EXPECT(checkArraySize(offers, 1u)))
675 return;
676 BEAST_EXPECT(
677 offers[0u][jss::taker_gets] ==
678 g1["USD"](999).value().getJson(JsonOptions::Values::None));
679
680 // test: someone else creates an offer providing liquidity
681 env(offer(a4, XRP(999), g1["USD"](999)));
682 env.close();
683
684 // test: owner of partially consumed offers line is frozen
685 env(trust(g1, a3["USD"](0), tfSetFreeze));
686 auto affected = env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
687 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
688 return;
689 auto ff = affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
690 BEAST_EXPECT(
691 ff[sfHighLimit.fieldName] == g1["USD"](0).value().getJson(JsonOptions::Values::None));
692 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfLowFreeze));
693 BEAST_EXPECT(ff[jss::Flags].asUInt() & lsfHighFreeze);
694 env.close();
695
696 // verify offer on the books
697 offers = getAccountOffers(env, a3)[jss::offers];
698 if (!BEAST_EXPECT(checkArraySize(offers, 1u)))
699 return;
700
701 // test: Can make a payment via the new offer
702 env(pay(a2, g1, g1["USD"](1)), Paths(g1["USD"]), Sendmax(XRP(1)));
703 env.close();
704
705 // test: Partially consumed offer was removed by tes* payment
706 offers = getAccountOffers(env, a3)[jss::offers];
707 if (!BEAST_EXPECT(checkArraySize(offers, 0u)))
708 return;
709
710 // removal buy successful OfferCreate
711 // test: freeze the new offer
712 env(trust(g1, a4["USD"](0), tfSetFreeze));
713 affected = env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
714 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
715 return;
716 ff = affected[0u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
717 BEAST_EXPECT(
718 ff[sfLowLimit.fieldName] == g1["USD"](0).value().getJson(JsonOptions::Values::None));
719 BEAST_EXPECT(ff[jss::Flags].asUInt() & lsfLowFreeze);
720 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfHighFreeze));
721 env.close();
722
723 // test: can no longer create a crossing offer
724 env(offer(a2, g1["USD"](999), XRP(999)));
725 affected = env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
726 if (!BEAST_EXPECT(checkArraySize(affected, 8u)))
727 return;
728 auto created = affected[0u][sfCreatedNode.fieldName];
729 BEAST_EXPECT(created[sfNewFields.fieldName][jss::Account] == a2.human());
730 env.close();
731
732 // test: offer was removed by offer_create
733 offers = getAccountOffers(env, a4)[jss::offers];
734 if (!BEAST_EXPECT(checkArraySize(offers, 0u)))
735 return;
736 }
737
738 void
740 {
741 testcase("Offers on frozen trust lines");
742
743 using namespace test::jtx;
744 Env env(*this, features);
745
746 Account const g1{"G1"};
747 Account const a1{"A1"};
748 Account const a2{"A2"};
749 Account const a3{"A3"};
750 auto const usd{g1["USD"]};
751
752 env.fund(XRP(10000), g1, a1, a2, a3);
753 env.close();
754
755 auto const limit = usd(10000);
756 env.trust(limit, a1, a2, a3);
757 env.close();
758
759 env(pay(g1, a1, usd(1000)));
760 env(pay(g1, a2, usd(1000)));
761 env.close();
762
763 // Making large passive sell offer
764 // Wants to sell 50 USD for 100 XRP
765 env(offer(a2, XRP(100), usd(50)), Txflags(tfPassive));
766 env.close();
767 // Making large passive buy offer
768 // Wants to buy 100 USD for 100 XRP
769 env(offer(a3, usd(100), XRP(100)), Txflags(tfPassive));
770 env.close();
771 env.require(offers(a2, 1), offers(a3, 1));
772
773 // Checking A1 can buy from A2 by crossing it's offer
774 env(offer(a1, usd(1), XRP(2)), Txflags(tfFillOrKill));
775 env.close();
776 env.require(Balance(a1, usd(1001)), Balance(a2, usd(999)));
777
778 // Checking A1 can sell to A3 by crossing it's offer
779 env(offer(a1, XRP(1), usd(1)), Txflags(tfFillOrKill));
780 env.close();
781 env.require(Balance(a1, usd(1000)), Balance(a3, usd(1)));
782
783 // Testing aggressive and passive offer placing, trustline frozen by
784 // the issuer
785 {
786 env(trust(g1, a1["USD"](0), tfSetFreeze));
787 env.close();
788
789 // test: can still make passive buy offer
790 env(offer(a1, usd(1), XRP(0.5)), Txflags(tfPassive));
791 env.close();
792 env.require(Balance(a1, usd(1000)), offers(a1, 1));
793 // Cleanup
794 env(offerCancel(a1, env.seq(a1) - 1));
795 env.require(offers(a1, 0));
796 env.close();
797
798 // test: can still buy from A2
799 env(offer(a1, usd(1), XRP(2)), Txflags(tfFillOrKill));
800 env.close();
801 env.require(Balance(a1, usd(1001)), Balance(a2, usd(998)), offers(a1, 0));
802
803 // test: cannot create passive sell offer
804 env(offer(a1, XRP(2), usd(1)), Txflags(tfPassive), Ter(tecUNFUNDED_OFFER));
805 env.close();
806 env.require(Balance(a1, usd(1001)), offers(a1, 0));
807
808 // test: cannot sell to A3
809 env(offer(a1, XRP(1), usd(1)), Txflags(tfFillOrKill), Ter(tecUNFUNDED_OFFER));
810 env.close();
811 env.require(Balance(a1, usd(1001)), offers(a1, 0));
812
813 env(trust(g1, a1["USD"](0), tfClearFreeze));
814 env.close();
815 }
816
817 // Testing aggressive and passive offer placing, trustline deep frozen
818 // by the issuer
819 if (features[featureDeepFreeze])
820 {
821 env(trust(g1, a1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
822 env.close();
823
824 // test: cannot create passive buy offer
825 env(offer(a1, usd(1), XRP(0.5)), Txflags(tfPassive), Ter(tecFROZEN));
826 env.close();
827
828 // test: cannot buy from A2
829 env(offer(a1, usd(1), XRP(2)), Txflags(tfFillOrKill), Ter(tecFROZEN));
830 env.close();
831
832 // test: cannot create passive sell offer
833 env(offer(a1, XRP(2), usd(1)), Txflags(tfPassive), Ter(tecUNFUNDED_OFFER));
834 env.close();
835
836 // test: cannot sell to A3
837 env(offer(a1, XRP(1), usd(1)), Txflags(tfFillOrKill), Ter(tecUNFUNDED_OFFER));
838 env.close();
839
840 env(trust(g1, a1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
841 env.close();
842 env.require(Balance(a1, usd(1001)), offers(a1, 0));
843 }
844
845 // Testing already existing offers behavior after trustline is frozen by
846 // the issuer
847 {
848 env.require(Balance(a1, usd(1001)));
849 env(offer(a1, XRP(1.9), usd(1)));
850 env(offer(a1, usd(1), XRP(1.1)));
851 env.close();
852 env.require(Balance(a1, usd(1001)), offers(a1, 2));
853
854 env(trust(g1, a1["USD"](0), tfSetFreeze));
855 env.close();
856
857 // test: A2 wants to sell to A1, must succeed
858 env.require(Balance(a1, usd(1001)), Balance(a2, usd(998)));
859 env(offer(a2, XRP(1.1), usd(1)), Txflags(tfFillOrKill));
860 env.close();
861 env.require(Balance(a1, usd(1002)), Balance(a2, usd(997)), offers(a1, 1));
862
863 // test: A3 wants to buy from A1, must fail
864 env.require(Balance(a1, usd(1002)), Balance(a3, usd(1)), offers(a1, 1));
865 env(offer(a3, usd(1), XRP(1.9)), Txflags(tfFillOrKill), Ter(tecKILLED));
866 env.close();
867 env.require(Balance(a1, usd(1002)), Balance(a3, usd(1)), offers(a1, 0));
868
869 env(trust(g1, a1["USD"](0), tfClearFreeze));
870 env.close();
871 }
872
873 // Testing existing offers behavior after trustline is deep frozen by
874 // the issuer
875 if (features[featureDeepFreeze])
876 {
877 env.require(Balance(a1, usd(1002)));
878 env(offer(a1, XRP(1.9), usd(1)));
879 env(offer(a1, usd(1), XRP(1.1)));
880 env.close();
881 env.require(Balance(a1, usd(1002)), offers(a1, 2));
882
883 env(trust(g1, a1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
884 env.close();
885
886 // test: A2 wants to sell to A1, must fail
887 env.require(Balance(a1, usd(1002)), Balance(a2, usd(997)));
888 env(offer(a2, XRP(1.1), usd(1)), Txflags(tfFillOrKill), Ter(tecKILLED));
889 env.close();
890 env.require(Balance(a1, usd(1002)), Balance(a2, usd(997)), offers(a1, 1));
891
892 // test: A3 wants to buy from A1, must fail
893 env.require(Balance(a1, usd(1002)), Balance(a3, usd(1)), offers(a1, 1));
894 env(offer(a3, usd(1), XRP(1.9)), Txflags(tfFillOrKill), Ter(tecKILLED));
895 env.close();
896 env.require(Balance(a1, usd(1002)), Balance(a3, usd(1)), offers(a1, 0));
897
898 env(trust(g1, a1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
899 env.close();
900 }
901
902 // Testing aggressive and passive offer placing, trustline frozen by
903 // the holder
904 {
905 env(trust(a1, limit, tfSetFreeze));
906 env.close();
907
908 // test: A1 can make passive buy offer
909 env(offer(a1, usd(1), XRP(0.5)), Txflags(tfPassive));
910 env.close();
911 env.require(Balance(a1, usd(1002)), offers(a1, 1));
912 // Cleanup
913 env(offerCancel(a1, env.seq(a1) - 1));
914 env.require(offers(a1, 0));
915 env.close();
916
917 // test: A1 wants to buy, must fail
918 env(offer(a1, usd(1), XRP(2)), Txflags(tfFillOrKill), Ter(tecKILLED));
919 env.close();
920 env.require(Balance(a1, usd(1002)), Balance(a2, usd(997)), offers(a1, 0));
921
922 // test: A1 can create passive sell offer
923 env(offer(a1, XRP(2), usd(1)), Txflags(tfPassive));
924 env.close();
925 env.require(Balance(a1, usd(1002)), offers(a1, 1));
926 // Cleanup
927 env(offerCancel(a1, env.seq(a1) - 1));
928 env.require(offers(a1, 0));
929 env.close();
930
931 // test: A1 can sell to A3
932 env(offer(a1, XRP(1), usd(1)), Txflags(tfFillOrKill));
933 env.close();
934 env.require(Balance(a1, usd(1001)), offers(a1, 0));
935
936 env(trust(a1, limit, tfClearFreeze));
937 env.close();
938 }
939
940 // Testing aggressive and passive offer placing, trustline deep frozen
941 // by the holder
942 if (features[featureDeepFreeze])
943 {
944 env(trust(a1, limit, tfSetFreeze | tfSetDeepFreeze));
945 env.close();
946
947 // test: A1 cannot create passive buy offer
948 env(offer(a1, usd(1), XRP(0.5)), Txflags(tfPassive), Ter(tecFROZEN));
949 env.close();
950
951 // test: A1 cannot buy, must fail
952 env(offer(a1, usd(1), XRP(2)), Txflags(tfFillOrKill), Ter(tecFROZEN));
953 env.close();
954
955 // test: A1 cannot create passive sell offer
956 env(offer(a1, XRP(2), usd(1)), Txflags(tfPassive), Ter(tecUNFUNDED_OFFER));
957 env.close();
958
959 // test: A1 cannot sell to A3
960 env(offer(a1, XRP(1), usd(1)), Txflags(tfFillOrKill), Ter(tecUNFUNDED_OFFER));
961 env.close();
962
963 env(trust(a1, limit, tfClearFreeze | tfClearDeepFreeze));
964 env.close();
965 }
966 }
967
968 void
970 {
971 testcase("Longer paths payment on frozen trust lines");
972 using namespace test::jtx;
973
974 Env env(*this, features);
975 Account const g1{"G1"};
976 Account const a1{"A1"};
977 Account const a2{"A2"};
978 auto const usd{g1["USD"]};
979
980 env.fund(XRP(10000), g1, a1, a2);
981 env.close();
982
983 auto const limit = usd(10000);
984 env.trust(limit, a1, a2);
985 env.close();
986
987 env(pay(g1, a1, usd(1000)));
988 env(pay(g1, a2, usd(1000)));
989 env.close();
990
991 env(offer(a2, XRP(100), usd(100)), Txflags(tfPassive));
992 env.close();
993
994 // Testing payments A1 <-> G1 using offer from A2 frozen by issuer.
995 {
996 env(trust(g1, a2["USD"](0), tfSetFreeze));
997 env.close();
998
999 // test: A1 cannot send USD using XRP through A2 offer
1000 env(pay(a1, g1, usd(10)),
1001 Path(~usd),
1002 Sendmax(XRP(11)),
1003 Txflags(tfNoRippleDirect),
1004 Ter(tecPATH_PARTIAL));
1005 env.close();
1006
1007 // test: G1 cannot send USD using XRP through A2 offer
1008 env(pay(g1, a1, usd(10)),
1009 Path(~usd),
1010 Sendmax(XRP(11)),
1011 Txflags(tfNoRippleDirect),
1012 Ter(tecPATH_PARTIAL));
1013 env.close();
1014
1015 env(trust(g1, a2["USD"](0), tfClearFreeze));
1016 env.close();
1017 }
1018
1019 // Testing payments A1 <-> G1 using offer from A2 deep frozen by issuer.
1020 if (features[featureDeepFreeze])
1021 {
1022 env(trust(g1, a2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1023 env.close();
1024
1025 // test: A1 cannot send USD using XRP through A2 offer
1026 env(pay(a1, g1, usd(10)),
1027 Path(~usd),
1028 Sendmax(XRP(11)),
1029 Txflags(tfNoRippleDirect),
1030 Ter(tecPATH_PARTIAL));
1031 env.close();
1032
1033 // test: G1 cannot send USD using XRP through A2 offer
1034 env(pay(g1, a1, usd(10)),
1035 Path(~usd),
1036 Sendmax(XRP(11)),
1037 Txflags(tfNoRippleDirect),
1038 Ter(tecPATH_PARTIAL));
1039 env.close();
1040
1041 env(trust(g1, a2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1042 env.close();
1043 }
1044
1045 // Testing payments A1 <-> G1 using offer from A2 frozen by currency
1046 // holder.
1047 {
1048 env(trust(a2, limit, tfSetFreeze));
1049 env.close();
1050
1051 // test: A1 can send USD using XRP through A2 offer
1052 env(pay(a1, g1, usd(10)), Path(~usd), Sendmax(XRP(11)), Txflags(tfNoRippleDirect));
1053 env.close();
1054
1055 // test: G1 can send USD using XRP through A2 offer
1056 env(pay(g1, a1, usd(10)), Path(~usd), Sendmax(XRP(11)), Txflags(tfNoRippleDirect));
1057 env.close();
1058
1059 env(trust(a2, limit, tfClearFreeze));
1060 env.close();
1061 }
1062
1063 // Testing payments A1 <-> G1 using offer from A2 deep frozen by
1064 // currency holder.
1065 if (features[featureDeepFreeze])
1066 {
1067 env(trust(a2, limit, tfSetFreeze | tfSetDeepFreeze));
1068 env.close();
1069
1070 // test: A1 cannot send USD using XRP through A2 offer
1071 env(pay(a1, g1, usd(10)),
1072 Path(~usd),
1073 Sendmax(XRP(11)),
1074 Txflags(tfNoRippleDirect),
1075 Ter(tecPATH_PARTIAL));
1076 env.close();
1077
1078 // test: G1 cannot send USD using XRP through A2 offer
1079 env(pay(g1, a1, usd(10)),
1080 Path(~usd),
1081 Sendmax(XRP(11)),
1082 Txflags(tfNoRippleDirect),
1083 Ter(tecPATH_PARTIAL));
1084 env.close();
1085
1086 env(trust(a2, limit, tfClearFreeze | tfClearDeepFreeze));
1087 env.close();
1088 }
1089
1090 // Cleanup
1091 env(offerCancel(a1, env.seq(a1) - 1));
1092 env.require(offers(a1, 0));
1093 env.close();
1094
1095 env(offer(a2, usd(100), XRP(100)), Txflags(tfPassive));
1096 env.close();
1097
1098 // Testing payments A1 <-> G1 using offer from A2 frozen by issuer.
1099 {
1100 env(trust(g1, a2["USD"](0), tfSetFreeze));
1101 env.close();
1102
1103 // test: A1 can send XRP using USD through A2 offer
1104 env(pay(a1, g1, XRP(10)), Path(~XRP), Sendmax(usd(11)), Txflags(tfNoRippleDirect));
1105 env.close();
1106
1107 // test: G1 can send XRP using USD through A2 offer
1108 env(pay(g1, a1, XRP(10)), Path(~XRP), Sendmax(usd(11)), Txflags(tfNoRippleDirect));
1109 env.close();
1110
1111 env(trust(g1, a2["USD"](0), tfClearFreeze));
1112 env.close();
1113 }
1114
1115 // Testing payments A1 <-> G1 using offer from A2 deep frozen by
1116 // issuer.
1117 if (features[featureDeepFreeze])
1118 {
1119 env(trust(g1, a2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1120 env.close();
1121
1122 // test: A1 cannot send XRP using USD through A2 offer
1123 env(pay(a1, g1, XRP(10)),
1124 Path(~XRP),
1125 Sendmax(usd(11)),
1126 Txflags(tfNoRippleDirect),
1127 Ter(tecPATH_PARTIAL));
1128 env.close();
1129
1130 // test: G1 cannot send XRP using USD through A2 offer
1131 env(pay(g1, a1, XRP(10)),
1132 Path(~XRP),
1133 Sendmax(usd(11)),
1134 Txflags(tfNoRippleDirect),
1135 Ter(tecPATH_PARTIAL));
1136 env.close();
1137
1138 env(trust(g1, a2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1139 env.close();
1140 }
1141
1142 // Testing payments A1 <-> G1 using offer from A2 frozen by currency
1143 // holder.
1144 {
1145 env(trust(a2, limit, tfSetFreeze));
1146 env.close();
1147
1148 // test: A1 can send XRP using USD through A2 offer
1149 env(pay(a1, g1, XRP(10)), Path(~XRP), Sendmax(usd(11)), Txflags(tfNoRippleDirect));
1150 env.close();
1151
1152 // test: G1 can send XRP using USD through A2 offer
1153 env(pay(g1, a1, XRP(10)), Path(~XRP), Sendmax(usd(11)), Txflags(tfNoRippleDirect));
1154 env.close();
1155
1156 env(trust(a2, limit, tfClearFreeze));
1157 env.close();
1158 }
1159
1160 // Testing payments A1 <-> G1 using offer from A2 deep frozen by
1161 // currency holder.
1162 if (features[featureDeepFreeze])
1163 {
1164 env(trust(a2, limit, tfSetFreeze | tfSetDeepFreeze));
1165 env.close();
1166
1167 // test: A1 cannot send XRP using USD through A2 offer
1168 env(pay(a1, g1, XRP(10)),
1169 Path(~XRP),
1170 Sendmax(usd(11)),
1171 Txflags(tfNoRippleDirect),
1172 Ter(tecPATH_PARTIAL));
1173 env.close();
1174
1175 // test: G1 cannot send XRP using USD through A2 offer
1176 env(pay(g1, a1, XRP(10)),
1177 Path(~XRP),
1178 Sendmax(usd(11)),
1179 Txflags(tfNoRippleDirect),
1180 Ter(tecPATH_PARTIAL));
1181 env.close();
1182
1183 env(trust(a2, limit, tfClearFreeze | tfClearDeepFreeze));
1184 env.close();
1185 }
1186
1187 // Cleanup
1188 env(offerCancel(a1, env.seq(a1) - 1));
1189 env.require(offers(a1, 0));
1190 env.close();
1191 }
1192
1193 void
1195 {
1196 testcase("Direct payments on frozen trust lines");
1197
1198 using namespace test::jtx;
1199 Env env(*this, features);
1200
1201 Account const g1{"G1"};
1202 Account const a1{"A1"};
1203 Account const a2{"A2"};
1204 auto const usd{g1["USD"]};
1205
1206 env.fund(XRP(10000), g1, a1, a2);
1207 env.close();
1208
1209 auto const limit = usd(10000);
1210 env.trust(limit, a1, a2);
1211 env.close();
1212
1213 env(pay(g1, a1, usd(1000)));
1214 env(pay(g1, a2, usd(1000)));
1215 env.close();
1216
1217 // Checking payments before freeze
1218 // To issuer:
1219 env(pay(a1, g1, usd(1)));
1220 env(pay(a2, g1, usd(1)));
1221 env.close();
1222
1223 // To each other:
1224 env(pay(a1, a2, usd(1)));
1225 env(pay(a2, a1, usd(1)));
1226 env.close();
1227
1228 // Freeze A1
1229 env(trust(g1, a1["USD"](0), tfSetFreeze));
1230 env.close();
1231
1232 // Issuer and A1 can send payments to each other
1233 env(pay(a1, g1, usd(1)));
1234 env(pay(g1, a1, usd(1)));
1235 env.close();
1236
1237 // A1 cannot send tokens to A2
1238 env(pay(a1, a2, usd(1)), Ter(tecPATH_DRY));
1239
1240 // A2 can still send to A1
1241 env(pay(a2, a1, usd(1)));
1242 env.close();
1243
1244 if (features[featureDeepFreeze])
1245 {
1246 // Deep freeze A1
1247 env(trust(g1, a1["USD"](0), tfSetDeepFreeze));
1248 env.close();
1249
1250 // Issuer and A1 can send payments to each other
1251 env(pay(a1, g1, usd(1)));
1252 env(pay(g1, a1, usd(1)));
1253 env.close();
1254
1255 // A1 cannot send tokens to A2
1256 env(pay(a1, a2, usd(1)), Ter(tecPATH_DRY));
1257
1258 // A2 cannot send tokens to A1
1259 env(pay(a2, a1, usd(1)), Ter(tecPATH_DRY));
1260
1261 // Clear deep freeze on A1
1262 env(trust(g1, a1["USD"](0), tfClearDeepFreeze));
1263 env.close();
1264 }
1265
1266 // Clear freeze on A1
1267 env(trust(g1, a1["USD"](0), tfClearFreeze));
1268 env.close();
1269
1270 // A1 freezes trust line
1271 env(trust(a1, limit, tfSetFreeze));
1272 env.close();
1273
1274 // Issuer and A2 must not be affected
1275 env(pay(a2, g1, usd(1)));
1276 env(pay(g1, a2, usd(1)));
1277 env.close();
1278
1279 // A1 can send tokens to the issuer
1280 env(pay(a1, g1, usd(1)));
1281 env.close();
1282 // A1 can send tokens to A2
1283 env(pay(a1, a2, usd(1)));
1284 env.close();
1285
1286 // Issuer can sent tokens to A1
1287 env(pay(g1, a1, usd(1)));
1288 // A2 cannot send tokens to A1
1289 env(pay(a2, a1, usd(1)), Ter(tecPATH_DRY));
1290
1291 if (features[featureDeepFreeze])
1292 {
1293 // A1 deep freezes trust line
1294 env(trust(a1, limit, tfSetDeepFreeze));
1295 env.close();
1296
1297 // Issuer and A2 must not be affected
1298 env(pay(a2, g1, usd(1)));
1299 env(pay(g1, a2, usd(1)));
1300 env.close();
1301
1302 // A1 can still send token to issuer
1303 env(pay(a1, g1, usd(1)));
1304 env.close();
1305
1306 // Issuer can send tokens to A1
1307 env(pay(g1, a1, usd(1)));
1308 // A2 cannot send tokens to A1
1309 env(pay(a2, a1, usd(1)), Ter(tecPATH_DRY));
1310 // A1 cannot send tokens to A2
1311 env(pay(a1, a2, usd(1)), Ter(tecPATH_DRY));
1312 }
1313 }
1314
1315 void
1317 {
1318 testcase("Checks on frozen trust lines");
1319
1320 using namespace test::jtx;
1321 Env env(*this, features);
1322
1323 Account const g1{"G1"};
1324 Account const a1{"A1"};
1325 Account const a2{"A2"};
1326 auto const usd{g1["USD"]};
1327
1328 env.fund(XRP(10000), g1, a1, a2);
1329 env.close();
1330
1331 auto const limit = usd(10000);
1332 env.trust(limit, a1, a2);
1333 env.close();
1334
1335 env(pay(g1, a1, usd(1000)));
1336 env(pay(g1, a2, usd(1000)));
1337 env.close();
1338
1339 // Confirming we can write and cash checks
1340 {
1341 uint256 const checkId{getCheckIndex(g1, env.seq(g1))};
1342 env(check::create(g1, a1, usd(10)));
1343 env.close();
1344 env(check::cash(a1, checkId, usd(10)));
1345 env.close();
1346 }
1347
1348 {
1349 uint256 const checkId{getCheckIndex(g1, env.seq(g1))};
1350 env(check::create(g1, a2, usd(10)));
1351 env.close();
1352 env(check::cash(a2, checkId, usd(10)));
1353 env.close();
1354 }
1355
1356 {
1357 uint256 const checkId{getCheckIndex(a1, env.seq(a1))};
1358 env(check::create(a1, g1, usd(10)));
1359 env.close();
1360 env(check::cash(g1, checkId, usd(10)));
1361 env.close();
1362 }
1363
1364 {
1365 uint256 const checkId{getCheckIndex(a1, env.seq(a1))};
1366 env(check::create(a1, a2, usd(10)));
1367 env.close();
1368 env(check::cash(a2, checkId, usd(10)));
1369 env.close();
1370 }
1371
1372 {
1373 uint256 const checkId{getCheckIndex(a2, env.seq(a2))};
1374 env(check::create(a2, g1, usd(10)));
1375 env.close();
1376 env(check::cash(g1, checkId, usd(10)));
1377 env.close();
1378 }
1379
1380 {
1381 uint256 const checkId{getCheckIndex(a2, env.seq(a2))};
1382 env(check::create(a2, a1, usd(10)));
1383 env.close();
1384 env(check::cash(a1, checkId, usd(10)));
1385 env.close();
1386 }
1387
1388 // Testing creation and cashing of checks on a trustline frozen by
1389 // issuer
1390 {
1391 env(trust(g1, a1["USD"](0), tfSetFreeze));
1392 env.close();
1393
1394 // test: issuer writes check to A1.
1395 {
1396 uint256 const checkId{getCheckIndex(g1, env.seq(g1))};
1397 env(check::create(g1, a1, usd(10)));
1398 env.close();
1399 env(check::cash(a1, checkId, usd(10)), Ter(tecFROZEN));
1400 env.close();
1401 }
1402
1403 // test: A2 writes check to A1.
1404 {
1405 uint256 const checkId{getCheckIndex(a2, env.seq(a2))};
1406 env(check::create(a2, a1, usd(10)));
1407 env.close();
1408 // Same as previous test
1409 env(check::cash(a1, checkId, usd(10)), Ter(tecFROZEN));
1410 env.close();
1411 }
1412
1413 // test: A1 writes check to issuer
1414 {
1415 env(check::create(a1, g1, usd(10)), Ter(tecFROZEN));
1416 env.close();
1417 }
1418
1419 // test: A1 writes check to A2
1420 {
1421 // Same as previous test
1422 env(check::create(a1, a2, usd(10)), Ter(tecFROZEN));
1423 env.close();
1424 }
1425
1426 // Unfreeze the trustline to create a couple of checks so that we
1427 // could try to cash them later when the trustline is frozen again.
1428 env(trust(g1, a1["USD"](0), tfClearFreeze));
1429 env.close();
1430
1431 uint256 const checkId1{getCheckIndex(a1, env.seq(a1))};
1432 env(check::create(a1, g1, usd(10)));
1433 env.close();
1434 uint256 const checkId2{getCheckIndex(a1, env.seq(a1))};
1435 env(check::create(a1, a2, usd(10)));
1436 env.close();
1437
1438 env(trust(g1, a1["USD"](0), tfSetFreeze));
1439 env.close();
1440
1441 // test: issuer tries to cash the check from A1
1442 {
1443 env(check::cash(g1, checkId1, usd(10)), Ter(tecPATH_PARTIAL));
1444 env.close();
1445 }
1446
1447 // test: A2 tries to cash the check from A1
1448 {
1449 env(check::cash(a2, checkId2, usd(10)), Ter(tecPATH_PARTIAL));
1450 env.close();
1451 }
1452
1453 env(trust(g1, a1["USD"](0), tfClearFreeze));
1454 env.close();
1455 }
1456
1457 // Testing creation and cashing of checks on a trustline deep frozen by
1458 // issuer
1459 if (features[featureDeepFreeze])
1460 {
1461 env(trust(g1, a1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1462 env.close();
1463
1464 // test: issuer writes check to A1.
1465 {
1466 uint256 const checkId{getCheckIndex(g1, env.seq(g1))};
1467 env(check::create(g1, a1, usd(10)));
1468 env.close();
1469
1470 env(check::cash(a1, checkId, usd(10)), Ter(tecFROZEN));
1471 env.close();
1472 }
1473
1474 // test: A2 writes check to A1.
1475 {
1476 uint256 const checkId{getCheckIndex(a2, env.seq(a2))};
1477 env(check::create(a2, a1, usd(10)));
1478 env.close();
1479 // Same as previous test
1480 env(check::cash(a1, checkId, usd(10)), Ter(tecFROZEN));
1481 env.close();
1482 }
1483
1484 // test: A1 writes check to issuer
1485 {
1486 env(check::create(a1, g1, usd(10)), Ter(tecFROZEN));
1487 env.close();
1488 }
1489
1490 // test: A1 writes check to A2
1491 {
1492 // Same as previous test
1493 env(check::create(a1, a2, usd(10)), Ter(tecFROZEN));
1494 env.close();
1495 }
1496
1497 // Unfreeze the trustline to create a couple of checks so that we
1498 // could try to cash them later when the trustline is frozen again.
1499 env(trust(g1, a1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1500 env.close();
1501
1502 uint256 const checkId1{getCheckIndex(a1, env.seq(a1))};
1503 env(check::create(a1, g1, usd(10)));
1504 env.close();
1505 uint256 const checkId2{getCheckIndex(a1, env.seq(a1))};
1506 env(check::create(a1, a2, usd(10)));
1507 env.close();
1508
1509 env(trust(g1, a1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1510 env.close();
1511
1512 // test: issuer tries to cash the check from A1
1513 {
1514 env(check::cash(g1, checkId1, usd(10)), Ter(tecPATH_PARTIAL));
1515 env.close();
1516 }
1517
1518 // test: A2 tries to cash the check from A1
1519 {
1520 env(check::cash(a2, checkId2, usd(10)), Ter(tecPATH_PARTIAL));
1521 env.close();
1522 }
1523
1524 env(trust(g1, a1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1525 env.close();
1526 }
1527
1528 // Testing creation and cashing of checks on a trustline frozen by
1529 // a currency holder
1530 {
1531 env(trust(a1, limit, tfSetFreeze));
1532 env.close();
1533
1534 // test: issuer writes check to A1.
1535 {
1536 env(check::create(g1, a1, usd(10)), Ter(tecFROZEN));
1537 env.close();
1538 }
1539
1540 // test: A2 writes check to A1.
1541 {
1542 env(check::create(a2, a1, usd(10)), Ter(tecFROZEN));
1543 env.close();
1544 }
1545
1546 // test: A1 writes check to issuer
1547 {
1548 uint256 const checkId{getCheckIndex(a1, env.seq(a1))};
1549 env(check::create(a1, g1, usd(10)));
1550 env.close();
1551 env(check::cash(g1, checkId, usd(10)));
1552 env.close();
1553 }
1554
1555 // test: A1 writes check to A2
1556 {
1557 uint256 const checkId{getCheckIndex(a1, env.seq(a1))};
1558 env(check::create(a1, a2, usd(10)));
1559 env.close();
1560 env(check::cash(a2, checkId, usd(10)));
1561 env.close();
1562 }
1563
1564 env(trust(a1, limit, tfClearFreeze));
1565 env.close();
1566 }
1567
1568 // Testing creation and cashing of checks on a trustline deep frozen by
1569 // a currency holder
1570 if (features[featureDeepFreeze])
1571 {
1572 env(trust(a1, limit, tfSetFreeze | tfSetDeepFreeze));
1573 env.close();
1574
1575 // test: issuer writes check to A1.
1576 {
1577 env(check::create(g1, a1, usd(10)), Ter(tecFROZEN));
1578 env.close();
1579 }
1580
1581 // test: A2 writes check to A1.
1582 {
1583 env(check::create(a2, a1, usd(10)), Ter(tecFROZEN));
1584 env.close();
1585 }
1586
1587 // test: A1 writes check to issuer
1588 {
1589 uint256 const checkId{getCheckIndex(a1, env.seq(a1))};
1590 env(check::create(a1, g1, usd(10)));
1591 env.close();
1592 env(check::cash(g1, checkId, usd(10)), Ter(tecPATH_PARTIAL));
1593 env.close();
1594 }
1595
1596 // test: A1 writes check to A2
1597 {
1598 uint256 const checkId{getCheckIndex(a1, env.seq(a1))};
1599 env(check::create(a1, a2, usd(10)));
1600 env.close();
1601 env(check::cash(a2, checkId, usd(10)), Ter(tecPATH_PARTIAL));
1602 env.close();
1603 }
1604
1605 env(trust(a1, limit, tfClearFreeze | tfClearDeepFreeze));
1606 env.close();
1607 }
1608 }
1609
1610 void
1612 {
1613 testcase("AMM payments on frozen trust lines");
1614 using namespace test::jtx;
1615
1616 Env env(*this, features);
1617 Account const g1{"G1"};
1618 Account const a1{"A1"};
1619 Account const a2{"A2"};
1620 auto const usd{g1["USD"]};
1621
1622 env.fund(XRP(10000), g1, a1, a2);
1623 env.close();
1624
1625 env.trust(g1["USD"](10000), a1, a2);
1626 env.close();
1627
1628 env(pay(g1, a1, usd(1000)));
1629 env(pay(g1, a2, usd(1000)));
1630 env.close();
1631
1632 AMM const ammG1(env, g1, XRP(1'000), usd(1'000));
1633 env.close();
1634
1635 // Testing basic payment using AMM when freezing one of the trust lines.
1636 {
1637 env(trust(g1, a1["USD"](0), tfSetFreeze));
1638 env.close();
1639
1640 // test: can still use XRP to make payment
1641 env(pay(a1, a2, usd(10)), Path(~usd), Sendmax(XRP(11)), Txflags(tfNoRippleDirect));
1642 env.close();
1643
1644 // test: cannot use USD to make payment
1645 env(pay(a1, a2, XRP(10)),
1646 Path(~XRP),
1647 Sendmax(usd(11)),
1648 Txflags(tfNoRippleDirect),
1649 Ter(tecPATH_DRY));
1650 env.close();
1651
1652 // test: can still receive USD payments.
1653 env(pay(a2, a1, usd(10)), Path(~usd), Sendmax(XRP(11)), Txflags(tfNoRippleDirect));
1654 env.close();
1655
1656 // test: can still receive XRP payments.
1657 env(pay(a2, a1, XRP(10)), Path(~XRP), Sendmax(usd(11)), Txflags(tfNoRippleDirect));
1658 env.close();
1659
1660 env(trust(g1, a1["USD"](0), tfClearFreeze));
1661 env.close();
1662 }
1663
1664 // Testing basic payment using AMM when deep freezing one of the trust
1665 // lines.
1666 if (features[featureDeepFreeze])
1667 {
1668 env(trust(g1, a1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1669 env.close();
1670
1671 // test: can still use XRP to make payment
1672 env(pay(a1, a2, usd(10)), Path(~usd), Sendmax(XRP(11)), Txflags(tfNoRippleDirect));
1673 env.close();
1674
1675 // test: cannot use USD to make payment
1676 env(pay(a1, a2, XRP(10)),
1677 Path(~XRP),
1678 Sendmax(usd(11)),
1679 Txflags(tfNoRippleDirect),
1680 Ter(tecPATH_DRY));
1681 env.close();
1682
1683 // test: cannot receive USD payments.
1684 env(pay(a2, a1, usd(10)),
1685 Path(~usd),
1686 Sendmax(XRP(11)),
1687 Txflags(tfNoRippleDirect),
1688 Ter(tecPATH_DRY));
1689 env.close();
1690
1691 // test: can still receive XRP payments.
1692 env(pay(a2, a1, XRP(10)), Path(~XRP), Sendmax(usd(11)), Txflags(tfNoRippleDirect));
1693 env.close();
1694
1695 env(trust(g1, a1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1696 env.close();
1697 }
1698 }
1699
1700 void
1702 {
1703 testcase("NFT offers on frozen trust lines");
1704 using namespace test::jtx;
1705
1706 Env env(*this, features);
1707 Account const g1{"G1"};
1708 Account const a1{"A1"};
1709 Account const a2{"A2"};
1710 auto const usd{g1["USD"]};
1711
1712 env.fund(XRP(10000), g1, a1, a2);
1713 env.close();
1714
1715 auto const limit = usd(10000);
1716 env.trust(limit, a1, a2);
1717 env.close();
1718
1719 env(pay(g1, a1, usd(1000)));
1720 env(pay(g1, a2, usd(1000)));
1721 env.close();
1722
1723 // Testing A2 nft offer sell when A2 frozen by issuer
1724 {
1725 auto const sellOfferIndex = createNFTSellOffer(env, a2, usd(10));
1726 env(trust(g1, a2["USD"](0), tfSetFreeze));
1727 env.close();
1728
1729 // test: A2 can still receive USD for his NFT
1730 env(token::acceptSellOffer(a1, sellOfferIndex));
1731 env.close();
1732
1733 env(trust(g1, a2["USD"](0), tfClearFreeze));
1734 env.close();
1735 }
1736
1737 // Testing A2 nft offer sell when A2 deep frozen by issuer
1738 if (features[featureDeepFreeze])
1739 {
1740 auto const sellOfferIndex = createNFTSellOffer(env, a2, usd(10));
1741
1742 env(trust(g1, a2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1743 env.close();
1744
1745 // test: A2 cannot receive USD for his NFT
1746 env(token::acceptSellOffer(a1, sellOfferIndex), Ter(tecFROZEN));
1747 env.close();
1748
1749 env(trust(g1, a2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1750 env.close();
1751 }
1752
1753 // Testing A1 nft offer sell when A2 frozen by issuer
1754 {
1755 auto const sellOfferIndex = createNFTSellOffer(env, a1, usd(10));
1756 env(trust(g1, a2["USD"](0), tfSetFreeze));
1757 env.close();
1758
1759 // test: A2 cannot send USD for NFT
1760 env(token::acceptSellOffer(a2, sellOfferIndex), Ter(tecINSUFFICIENT_FUNDS));
1761 env.close();
1762
1763 env(trust(g1, a2["USD"](0), tfClearFreeze));
1764 env.close();
1765 }
1766
1767 // Testing A1 nft offer sell when A2 deep frozen by issuer
1768 if (features[featureDeepFreeze])
1769 {
1770 auto const sellOfferIndex = createNFTSellOffer(env, a1, usd(10));
1771 env(trust(g1, a2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1772 env.close();
1773
1774 // test: A2 cannot send USD for NFT
1775 env(token::acceptSellOffer(a2, sellOfferIndex), Ter(tecINSUFFICIENT_FUNDS));
1776 env.close();
1777
1778 env(trust(g1, a2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1779 env.close();
1780 }
1781
1782 // Testing A1 nft buy offer when A2 deep frozen by issuer
1783 if (features[featureDeepFreeze] && features[fixEnforceNFTokenTrustlineV2])
1784 {
1785 env(trust(g1, a2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1786 env.close();
1787
1788 uint256 const nftID{token::getNextID(env, a2, 0u, tfTransferable)};
1789 env(token::mint(a2, 0), Txflags(tfTransferable));
1790 env.close();
1791
1792 auto const buyIdx = keylet::nftokenOffer(a1, SeqProxy::rawSequence(env.seq(a1))).key;
1793 env(token::createOffer(a1, nftID, usd(10)), token::Owner(a2));
1794 env.close();
1795
1796 env(token::acceptBuyOffer(a2, buyIdx), Ter(tecFROZEN));
1797 env.close();
1798
1799 env(trust(g1, a2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1800 env.close();
1801
1802 env(token::acceptBuyOffer(a2, buyIdx));
1803 env.close();
1804 }
1805
1806 // Testing A2 nft offer sell when A2 frozen by currency holder
1807 {
1808 auto const sellOfferIndex = createNFTSellOffer(env, a2, usd(10));
1809 env(trust(a2, limit, tfSetFreeze));
1810 env.close();
1811
1812 // test: offer can still be accepted.
1813 env(token::acceptSellOffer(a1, sellOfferIndex));
1814 env.close();
1815
1816 env(trust(a2, limit, tfClearFreeze));
1817 env.close();
1818 }
1819
1820 // Testing A2 nft offer sell when A2 deep frozen by currency holder
1821 if (features[featureDeepFreeze])
1822 {
1823 auto const sellOfferIndex = createNFTSellOffer(env, a2, usd(10));
1824
1825 env(trust(a2, limit, tfSetFreeze | tfSetDeepFreeze));
1826 env.close();
1827
1828 // test: A2 cannot receive USD for his NFT
1829 env(token::acceptSellOffer(a1, sellOfferIndex), Ter(tecFROZEN));
1830 env.close();
1831
1832 env(trust(a2, limit, tfClearFreeze | tfClearDeepFreeze));
1833 env.close();
1834 }
1835
1836 // Testing A1 nft offer sell when A2 frozen by currency holder
1837 {
1838 auto const sellOfferIndex = createNFTSellOffer(env, a1, usd(10));
1839 env(trust(a2, limit, tfSetFreeze));
1840 env.close();
1841
1842 // test: A2 cannot send USD for NFT
1843 env(token::acceptSellOffer(a2, sellOfferIndex));
1844 env.close();
1845
1846 env(trust(a2, limit, tfClearFreeze));
1847 env.close();
1848 }
1849
1850 // Testing A1 nft offer sell when A2 deep frozen by currency holder
1851 if (features[featureDeepFreeze])
1852 {
1853 auto const sellOfferIndex = createNFTSellOffer(env, a1, usd(10));
1854 env(trust(a2, limit, tfSetFreeze | tfSetDeepFreeze));
1855 env.close();
1856
1857 // test: A2 cannot send USD for NFT
1858 env(token::acceptSellOffer(a2, sellOfferIndex), Ter(tecINSUFFICIENT_FUNDS));
1859 env.close();
1860
1861 env(trust(a2, limit, tfClearFreeze | tfClearDeepFreeze));
1862 env.close();
1863 }
1864
1865 // Testing brokered offer acceptance
1866 if (features[featureDeepFreeze] && features[fixEnforceNFTokenTrustlineV2])
1867 {
1868 Account const broker{"broker"};
1869 env.fund(XRP(10000), broker);
1870 env.close();
1871 env(trust(g1, broker["USD"](1000), tfSetFreeze | tfSetDeepFreeze));
1872 env.close();
1873
1874 uint256 const nftID{token::getNextID(env, a2, 0u, tfTransferable)};
1875 env(token::mint(a2, 0), Txflags(tfTransferable));
1876 env.close();
1877
1878 uint256 const sellIdx =
1880 env(token::createOffer(a2, nftID, usd(10)), Txflags(tfSellNFToken));
1881 env.close();
1882 auto const buyIdx = keylet::nftokenOffer(a1, SeqProxy::rawSequence(env.seq(a1))).key;
1883 env(token::createOffer(a1, nftID, usd(11)), token::Owner(a2));
1884 env.close();
1885
1886 env(token::brokerOffers(broker, buyIdx, sellIdx),
1887 token::BrokerFee(usd(1)),
1888 Ter(tecFROZEN));
1889 env.close();
1890 }
1891
1892 // Testing transfer fee
1893 if (features[featureDeepFreeze] && features[fixEnforceNFTokenTrustlineV2])
1894 {
1895 Account const minter{"minter"};
1896 env.fund(XRP(10000), minter);
1897 env.close();
1898 env(trust(g1, minter["USD"](1000)));
1899 env.close();
1900
1901 uint256 const nftID{token::getNextID(env, minter, 0u, tfTransferable, 1u)};
1902 env(token::mint(minter, 0), token::XferFee(1u), Txflags(tfTransferable));
1903 env.close();
1904
1905 uint256 const minterSellIdx =
1906 keylet::nftokenOffer(minter, SeqProxy::rawSequence(env.seq(minter))).key;
1907 env(token::createOffer(minter, nftID, drops(1)), Txflags(tfSellNFToken));
1908 env.close();
1909 env(token::acceptSellOffer(a2, minterSellIdx));
1910 env.close();
1911
1912 uint256 const sellIdx =
1914 env(token::createOffer(a2, nftID, usd(100)), Txflags(tfSellNFToken));
1915 env.close();
1916 env(trust(g1, minter["USD"](1000), tfSetFreeze | tfSetDeepFreeze));
1917 env.close();
1918 env(token::acceptSellOffer(a1, sellIdx), Ter(tecFROZEN));
1919 env.close();
1920 }
1921 }
1922
1923 // Helper function to extract trustline flags from open ledger
1924 uint32_t
1926 test::jtx::Env& env,
1927 size_t expectedArraySize,
1928 size_t expectedArrayIndex,
1929 bool modified = true)
1930 {
1931 using namespace test::jtx;
1932 auto const affected =
1933 env.meta()->getJson(JsonOptions::Values::None)[sfAffectedNodes.fieldName];
1934 if (!BEAST_EXPECT(checkArraySize(affected, expectedArraySize)))
1935 return 0;
1936
1937 if (modified)
1938 {
1939 return affected[expectedArrayIndex][sfModifiedNode.fieldName][sfFinalFields.fieldName]
1940 [jss::Flags]
1941 .asUInt();
1942 }
1943
1944 return affected[expectedArrayIndex][sfCreatedNode.fieldName][sfNewFields.fieldName]
1945 [jss::Flags]
1946 .asUInt();
1947 }
1948
1949 // Helper function that returns the index of the next check on account
1950 static uint256
1951 getCheckIndex(AccountID const& account, std::uint32_t uSequence)
1952 {
1953 return keylet::check(account, SeqProxy::rawSequence(uSequence)).key;
1954 }
1955
1956 static uint256
1958 test::jtx::Env& env,
1959 test::jtx::Account const& account,
1960 test::jtx::PrettyAmount const& currency)
1961 {
1962 using namespace test::jtx;
1963 uint256 const nftID{token::getNextID(env, account, 0u, tfTransferable)};
1964 env(token::mint(account, 0), Txflags(tfTransferable));
1965 env.close();
1966
1967 uint256 const sellOfferIndex =
1968 keylet::nftokenOffer(account, SeqProxy::rawSequence(env.seq(account))).key;
1969 env(token::createOffer(account, nftID, currency), Txflags(tfSellNFToken));
1970 env.close();
1971
1972 return sellOfferIndex;
1973 }
1974
1975public:
1976 void
1977 run() override
1978 {
1979 auto testAll = [this](FeatureBitset features) {
1980 testRippleState(features);
1981 testDeepFreeze(features);
1982 testCreateFrozenTrustline(features);
1983 testSetAndClear(features);
1984 testGlobalFreeze(features);
1985 testNoFreeze(features);
1986 testOffersWhenFrozen(features);
1987 testOffersWhenDeepFrozen(features);
1989 testChecksWhenFrozen(features);
1990 testAMMWhenFreeze(features);
1991 testPathsWhenFrozen(features);
1992 testNFTOffersWhenFreeze(features);
1993 };
1994 using namespace test::jtx;
1995 auto const sa = testableAmendments();
1996 testAll(sa - featureDeepFreeze - featurePermissionedDEX - fixEnforceNFTokenTrustlineV2);
1997 testAll(sa - featurePermissionedDEX - fixEnforceNFTokenTrustlineV2);
1998 testAll(sa - featureDeepFreeze - featurePermissionedDEX);
1999 testAll(sa - featurePermissionedDEX);
2000 testAll(sa - fixEnforceNFTokenTrustlineV2);
2001 testAll(sa - featureDeepFreeze);
2002 testAll(sa);
2003 }
2004};
2005
2007} // namespace xrpl
A testsuite class.
Definition suite.h:52
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:155
Represents a JSON value.
Definition json_value.h:117
void testOffersWhenDeepFrozen(FeatureBitset features)
void testSetAndClear(FeatureBitset features)
void testChecksWhenFrozen(FeatureBitset features)
void testPathsWhenFrozen(FeatureBitset features)
uint32_t getTrustlineFlags(test::jtx::Env &env, size_t expectedArraySize, size_t expectedArrayIndex, bool modified=true)
static uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
void testOffersWhenFrozen(FeatureBitset features)
void run() override
Runs the suite.
void testNoFreeze(FeatureBitset features)
void testAMMWhenFreeze(FeatureBitset features)
void testNFTOffersWhenFreeze(FeatureBitset features)
void testGlobalFreeze(FeatureBitset features)
static uint256 createNFTSellOffer(test::jtx::Env &env, test::jtx::Account const &account, test::jtx::PrettyAmount const &currency)
void testRippleState(FeatureBitset features)
void testCreateFrozenTrustline(FeatureBitset features)
void testPaymentsWhenDeepFrozen(FeatureBitset features)
void testDeepFreeze(FeatureBitset features)
A currency issued by an account.
Definition Issue.h:18
json::Value getJson(JsonOptions=JsonOptions::Values::None) const override
Definition STAmount.cpp:734
STAmount const & value() const noexcept
Definition STAmount.h:610
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
Definition SeqProxy.h:62
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
A transaction testing environment.
Definition Env.h:161
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:133
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:302
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition Env.cpp:538
T clear(T... args)
T end(T... args)
T find(T... args)
T insert(T... args)
Keylet nftokenOffer(AccountID const &owner, SeqProxy const &seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:423
Keylet check(AccountID const &id, SeqProxy const &seq) noexcept
A Check.
Definition Indexes.cpp:338
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool toCurrency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Definition UintTypes.cpp:65
json::Value getJson(LedgerFill const &fill)
Return a new json::Value representing the ledger with given options.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
AccountID const & noAccount()
A placeholder for empty accounts.
@ temINVALID_FLAG
Definition TER.h:99
@ tecPATH_PARTIAL
Definition TER.h:285
@ tecPATH_DRY
Definition TER.h:297
@ tecFROZEN
Definition TER.h:306
@ tecINSUFFICIENT_FUNDS
Definition TER.h:328
@ tecUNFUNDED_OFFER
Definition TER.h:287
@ tecKILLED
Definition TER.h:319
@ tecNO_PERMISSION
Definition TER.h:308
BaseUInt< 256 > uint256
Definition base_uint.h:580
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl)
uint256 key
Definition Keylet.h:21
Represents an XRP, IOU, or MPT quantity This customizes the string conversion and supports XRP conver...