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