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