404 testcase(
"Rm small increased q offers IOU");
412 using namespace std::chrono_literals;
413 auto const alice =
Account{
"alice"};
414 auto const bob =
Account{
"bob"};
415 auto const carol =
Account{
"carol"};
418 auto const USD = gw[
"USD"];
419 auto const EUR = gw[
"EUR"];
430 for (
auto crossBothOffers : {
false,
true})
432 Env env{*
this, features};
434 env.fund(
XRP(10000), alice, bob, carol, gw);
436 env.trust(USD(1000), alice, bob, carol);
437 env.trust(EUR(1000), alice, bob, carol);
439 auto initialCarolUSD = tinyAmount(USD);
440 env(
pay(gw, carol, initialCarolUSD));
441 env(
pay(gw, bob, USD(100)));
442 env(
pay(gw, alice, EUR(100)));
445 env(
offer(carol, EUR(1), USD(10)));
448 env(
offer(bob, EUR(1), USD(5), tfPassive));
455 auto aliceTakerGets = crossBothOffers ? EUR(0.2) : EUR(0.1);
456 env(
offer(alice, USD(1), aliceTakerGets));
476 for (
auto partialPayment : {
false,
true})
478 Env env{*
this, features};
480 env.fund(
XRP(10000), alice, bob, carol, gw);
482 env.trust(USD(1000), alice, bob, carol);
483 env.trust(EUR(1000), alice, bob, carol);
486 auto const initialCarolUSD = tinyAmount(USD);
487 env(
pay(gw, carol, initialCarolUSD));
488 env(
pay(gw, bob, USD(100)));
489 env(
pay(gw, alice, EUR(100)));
492 env(
offer(carol, EUR(1), USD(2)));
494 env(
offer(bob, EUR(2), USD(4), tfPassive));
499 partialPayment ? (tfNoRippleDirect | tfPartialPayment) : tfNoRippleDirect;
503 env(
pay(alice, bob, USD(5)),
512 env.require(
offers(carol, 0));
2171 using namespace jtx;
2173 auto const gw =
Account(
"gateway");
2174 auto const USD = gw[
"USD"];
2176 Env env{*
this, features};
2178 env.fund(
XRP(10000000), gw);
2182 auto const f = env.current()->fees().base;
2185 enum preTrustType { noPreTrust, gwPreTrust, acctPreTrust };
2191 preTrustType preTrust;
2201 TestData
const tests[]{
2203 {
"ann",
reserve(env, 0) + 0 * f, 1, noPreTrust, 1000,
tecUNFUNDED_OFFER, f, USD( 0), 0, 0},
2204 {
"bev",
reserve(env, 0) + 1 * f, 1, noPreTrust, 1000,
tecUNFUNDED_OFFER, f, USD( 0), 0, 0},
2205 {
"cam",
reserve(env, 0) + 2 * f, 0, noPreTrust, 1000,
tecINSUF_RESERVE_OFFER, f, USD( 0), 0, 0},
2206 {
"deb",
drops(10) +
reserve(env, 0) + 1 * f, 1, noPreTrust, 1000,
tesSUCCESS,
drops(10) + f, USD(0.00001), 0, 1},
2207 {
"eve",
reserve(env, 1) + 0 * f, 0, noPreTrust, 1000,
tesSUCCESS, f, USD( 0), 1, 1},
2208 {
"flo",
reserve(env, 1) + 0 * f, 1, noPreTrust, 1000,
tesSUCCESS,
XRP( 1) + f, USD( 1), 0, 1},
2209 {
"gay",
reserve(env, 1) + 1 * f, 1000, noPreTrust, 1000,
tesSUCCESS,
XRP( 50) + f, USD( 50), 0, 1},
2210 {
"hye",
XRP(1000) + 1 * f, 1000, noPreTrust, 1000,
tesSUCCESS,
XRP( 800) + f, USD( 800), 0, 1},
2211 {
"ivy",
XRP( 1) +
reserve(env, 1) + 1 * f, 1, noPreTrust, 1000,
tesSUCCESS,
XRP( 1) + f, USD( 1), 0, 1},
2212 {
"joy",
XRP( 1) +
reserve(env, 2) + 1 * f, 1, noPreTrust, 1000,
tesSUCCESS,
XRP( 1) + f, USD( 1), 1, 2},
2213 {
"kim",
XRP( 900) +
reserve(env, 2) + 1 * f, 999, noPreTrust, 1000,
tesSUCCESS,
XRP( 999) + f, USD( 999), 0, 1},
2214 {
"liz",
XRP( 998) +
reserve(env, 0) + 1 * f, 999, noPreTrust, 1000,
tesSUCCESS,
XRP( 998) + f, USD( 998), 0, 1},
2215 {
"meg",
XRP( 998) +
reserve(env, 1) + 1 * f, 999, noPreTrust, 1000,
tesSUCCESS,
XRP( 999) + f, USD( 999), 0, 1},
2216 {
"nia",
XRP( 998) +
reserve(env, 2) + 1 * f, 999, noPreTrust, 1000,
tesSUCCESS,
XRP( 999) + f, USD( 999), 1, 2},
2217 {
"ova",
XRP( 999) +
reserve(env, 0) + 1 * f, 1000, noPreTrust, 1000,
tesSUCCESS,
XRP( 999) + f, USD( 999), 0, 1},
2218 {
"pam",
XRP( 999) +
reserve(env, 1) + 1 * f, 1000, noPreTrust, 1000,
tesSUCCESS,
XRP(1000) + f, USD( 1000), 0, 1},
2219 {
"rae",
XRP( 999) +
reserve(env, 2) + 1 * f, 1000, noPreTrust, 1000,
tesSUCCESS,
XRP(1000) + f, USD( 1000), 0, 1},
2220 {
"sue",
XRP(1000) +
reserve(env, 2) + 1 * f, 0, noPreTrust, 1000,
tesSUCCESS, f, USD( 0), 1, 1},
2222 {
"abe",
reserve(env, 0) + 0 * f, 1, gwPreTrust, 1000,
tecUNFUNDED_OFFER, f, USD( 0), 0, 0},
2223 {
"bud",
reserve(env, 0) + 1 * f, 1, gwPreTrust, 1000,
tecUNFUNDED_OFFER, f, USD( 0), 0, 0},
2224 {
"che",
reserve(env, 0) + 2 * f, 0, gwPreTrust, 1000,
tecINSUF_RESERVE_OFFER, f, USD( 0), 0, 0},
2225 {
"dan",
drops(10) +
reserve(env, 0) + 1 * f, 1, gwPreTrust, 1000,
tesSUCCESS,
drops(10) + f, USD(0.00001), 0, 0},
2226 {
"eli",
XRP( 20) +
reserve(env, 0) + 1 * f, 1000, gwPreTrust, 1000,
tesSUCCESS,
XRP(20) + 1 * f, USD( 20), 0, 0},
2227 {
"fyn",
reserve(env, 1) + 0 * f, 0, gwPreTrust, 1000,
tesSUCCESS, f, USD( 0), 1, 1},
2228 {
"gar",
reserve(env, 1) + 0 * f, 1, gwPreTrust, 1000,
tesSUCCESS,
XRP( 1) + f, USD( 1), 1, 1},
2229 {
"hal",
reserve(env, 1) + 1 * f, 1, gwPreTrust, 1000,
tesSUCCESS,
XRP( 1) + f, USD( 1), 1, 1},
2231 {
"ned",
reserve(env, 1) + 0 * f, 1, acctPreTrust, 1000,
tecUNFUNDED_OFFER, 2 * f, USD( 0), 0, 1},
2232 {
"ole",
reserve(env, 1) + 1 * f, 1, acctPreTrust, 1000,
tecUNFUNDED_OFFER, 2 * f, USD( 0), 0, 1},
2233 {
"pat",
reserve(env, 1) + 2 * f, 0, acctPreTrust, 1000,
tecUNFUNDED_OFFER, 2 * f, USD( 0), 0, 1},
2234 {
"quy",
reserve(env, 1) + 2 * f, 1, acctPreTrust, 1000,
tecUNFUNDED_OFFER, 2 * f, USD( 0), 0, 1},
2235 {
"ron",
reserve(env, 1) + 3 * f, 0, acctPreTrust, 1000,
tecINSUF_RESERVE_OFFER, 2 * f, USD( 0), 0, 1},
2236 {
"syd",
drops(10) +
reserve(env, 1) + 2 * f, 1, acctPreTrust, 1000,
tesSUCCESS,
drops(10) + 2 * f, USD(0.00001), 0, 1},
2237 {
"ted",
XRP( 20) +
reserve(env, 1) + 2 * f, 1000, acctPreTrust, 1000,
tesSUCCESS,
XRP(20) + 2 * f, USD( 20), 0, 1},
2238 {
"uli",
reserve(env, 2) + 0 * f, 0, acctPreTrust, 1000,
tecINSUF_RESERVE_OFFER, 2 * f, USD( 0), 0, 1},
2239 {
"vic",
reserve(env, 2) + 0 * f, 1, acctPreTrust, 1000,
tesSUCCESS,
XRP( 1) + 2 * f, USD( 1), 0, 1},
2240 {
"wes",
reserve(env, 2) + 1 * f, 0, acctPreTrust, 1000,
tesSUCCESS, 2 * f, USD( 0), 1, 2},
2241 {
"xan",
reserve(env, 2) + 1 * f, 1, acctPreTrust, 1000,
tesSUCCESS,
XRP( 1) + 2 * f, USD( 1), 1, 2},
2245 for (
auto const& t : tests)
2247 auto const acct =
Account(t.account);
2248 env.fund(t.fundXrp, acct);
2252 env.require(
offers(gw, 0));
2255 auto const book = t.bookAmount;
2257 env(
offer(gw,
XRP(book), USD(book)));
2262 if (t.preTrust == gwPreTrust)
2263 env(
trust(gw, acct[
"USD"](1)));
2269 if (t.preTrust == acctPreTrust)
2270 env(
trust(acct, USD(1)));
2275 auto const acctOffer = t.offerAmount;
2276 env(
offer(acct, USD(acctOffer),
XRP(acctOffer)),
ter(t.tec));
2281 BEAST_EXPECT(env.balance(acct, USD.issue()) == t.balanceUsd);
2282 BEAST_EXPECT(env.balance(acct,
xrpIssue()) == t.fundXrp - t.spentXrp);
2283 env.require(
offers(acct, t.offers));
2284 env.require(
owners(acct, t.owners));
2287 BEAST_EXPECT(acctOffers.size() == t.offers);
2288 if (!acctOffers.empty() && (t.offers != 0))
2290 auto const& acctOffer = *(acctOffers.front());
2292 auto const leftover = t.offerAmount - t.bookAmount;
2293 BEAST_EXPECT(acctOffer[sfTakerGets] ==
XRP(leftover));
2294 BEAST_EXPECT(acctOffer[sfTakerPays] == USD(leftover));
2297 if (t.preTrust == noPreTrust)
2299 if (t.balanceUsd.value().signum() != 0)
2307 auto const sleTrust = env.le(
keylet::line(acct, USD.issue()));
2308 BEAST_EXPECT(!sleTrust);
2618 using namespace jtx;
2620 auto const gw =
Account(
"gateway");
2621 auto const USD = gw[
"USD"];
2623 Env env{*
this, features};
2625 env.fund(
XRP(10000000), gw);
2629 auto const f = env.current()->fees().base;
2632 enum preTrustType { noPreTrust, gwPreTrust, acctPreTrust };
2666 : account(std::move(account_))
2671 , acctGets(acctGets_)
2672 , acctPays(acctPays_)
2674 , spentXrp(spentXrp_)
2675 , finalUsd(finalUsd_)
2678 , takerGets(takerGets_)
2679 , takerPays(takerPays_)
2698 std::move(account_),
2717 TestData
const tests[]{
2720 {
"ann",
XRP(10) +
reserve(env, 0) + 1 * f, USD( 0),
XRP(10), USD( 5), USD(10),
XRP(10),
tecINSUF_RESERVE_OFFER,
XRP( 0) + (1 * f), USD( 0), 0, 0},
2721 {
"bev",
XRP(10) +
reserve(env, 1) + 1 * f, USD( 0),
XRP(10), USD( 5), USD(10),
XRP(10),
tesSUCCESS,
XRP( 0) + (1 * f), USD( 0), 1, 1,
XRP(10), USD(10)},
2722 {
"cam",
XRP(10) +
reserve(env, 0) + 1 * f, USD( 0),
XRP(10), USD(10), USD(10),
XRP(10),
tesSUCCESS,
XRP( 10) + (1 * f), USD(10), 0, 1},
2723 {
"deb",
XRP(10) +
reserve(env, 0) + 1 * f, USD( 0),
XRP(10), USD(20), USD(10),
XRP(10),
tesSUCCESS,
XRP( 10) + (1 * f), USD(20), 0, 1},
2724 {
"eve",
XRP(10) +
reserve(env, 0) + 1 * f, USD( 0),
XRP(10), USD(20), USD( 5),
XRP( 5),
tesSUCCESS,
XRP( 5) + (1 * f), USD(10), 0, 1},
2725 {
"flo",
XRP(10) +
reserve(env, 0) + 1 * f, USD( 0),
XRP(10), USD(20), USD(20),
XRP(20),
tesSUCCESS,
XRP( 10) + (1 * f), USD(20), 0, 1},
2726 {
"gay",
XRP(20) +
reserve(env, 1) + 1 * f, USD( 0),
XRP(10), USD(20), USD(20),
XRP(20),
tesSUCCESS,
XRP( 10) + (1 * f), USD(20), 0, 1},
2727 {
"hye",
XRP(20) +
reserve(env, 2) + 1 * f, USD( 0),
XRP(10), USD(20), USD(20),
XRP(20),
tesSUCCESS,
XRP( 10) + (1 * f), USD(20), 1, 2,
XRP(10), USD(10)},
2729 {
"meg",
reserve(env, 1) + 2 * f, USD(10), USD(10),
XRP( 5),
XRP(10), USD(10),
tecINSUF_RESERVE_OFFER,
XRP( 0) + (2 * f), USD(10), 0, 1},
2730 {
"nia",
reserve(env, 2) + 2 * f, USD(10), USD(10),
XRP( 5),
XRP(10), USD(10),
tesSUCCESS,
XRP( 0) + (2 * f), USD(10), 1, 2, USD(10),
XRP(10)},
2731 {
"ova",
reserve(env, 1) + 2 * f, USD(10), USD(10),
XRP(10),
XRP(10), USD(10),
tesSUCCESS,
XRP(-10) + (2 * f), USD( 0), 0, 1},
2732 {
"pam",
reserve(env, 1) + 2 * f, USD(10), USD(10),
XRP(20),
XRP(10), USD(10),
tesSUCCESS,
XRP(-20) + (2 * f), USD( 0), 0, 1},
2733 {
"qui",
reserve(env, 1) + 2 * f, USD(10), USD(20),
XRP(40),
XRP(10), USD(10),
tesSUCCESS,
XRP(-20) + (2 * f), USD( 0), 0, 1},
2734 {
"rae",
reserve(env, 2) + 2 * f, USD(10), USD( 5),
XRP( 5),
XRP(10), USD(10),
tesSUCCESS,
XRP( -5) + (2 * f), USD( 5), 1, 2, USD( 5),
XRP( 5)},
2735 {
"sue",
reserve(env, 2) + 2 * f, USD(10), USD( 5),
XRP(10),
XRP(10), USD(10),
tesSUCCESS,
XRP(-10) + (2 * f), USD( 5), 1, 2, USD( 5),
XRP( 5)},
2739 auto const zeroUsd = USD(0);
2740 for (
auto const& t : tests)
2743 env.require(
offers(gw, 0));
2745 auto const acct =
Account(t.account);
2747 env.fund(t.fundXrp, acct);
2753 if (t.fundUSD != zeroUsd)
2755 env(
trust(acct, t.fundUSD));
2757 env(
pay(gw, acct, t.fundUSD));
2761 env(
offer(gw, t.gwGets, t.gwPays));
2766 env(
offer(acct, t.acctGets, t.acctPays, tfSell),
ter(t.tec));
2771 BEAST_EXPECT(env.balance(acct, USD.issue()) == t.finalUsd);
2772 BEAST_EXPECT(env.balance(acct,
xrpIssue()) == t.fundXrp - t.spentXrp);
2773 env.require(
offers(acct, t.offers));
2774 env.require(
owners(acct, t.owners));
2779 if (!acctOffers.empty())
2781 BEAST_EXPECT(acctOffers.size() == 1);
2782 auto const& acctOffer = *(acctOffers.front());
2784 BEAST_EXPECT(acctOffer[sfLedgerEntryType] == ltOFFER);
2785 BEAST_EXPECT(acctOffer[sfTakerGets] == t.takerGets);
2786 BEAST_EXPECT(acctOffer[sfTakerPays] == t.takerPays);
3262 using namespace jtx;
3264 auto const gw1 =
Account(
"gateway1");
3265 auto const gw2 =
Account(
"gateway2");
3266 auto const alice =
Account(
"alice");
3267 auto const USD = gw1[
"USD"];
3268 auto const EUR = gw2[
"EUR"];
3270 Env env{*
this, features};
3272 env.fund(
XRP(1000000), gw1, gw2);
3276 auto const f = env.current()->fees().base;
3290 TestData
const tests[]{
3301 for (
auto const& t : tests)
3303 auto const acct =
Account{t.acct};
3304 env.fund(t.fundXRP, acct);
3307 env(
trust(acct, USD(1000)));
3308 env(
trust(acct, EUR(1000)));
3311 if (t.fundUSD > USD(0))
3312 env(
pay(gw1, acct, t.fundUSD));
3313 if (t.fundEUR > EUR(0))
3314 env(
pay(gw2, acct, t.fundEUR));
3317 env(
offer(acct, USD(500), EUR(600)),
ter(t.firstOfferTec));
3321 int offerCount =
isTesSuccess(t.firstOfferTec) ? 1 : 0;
3322 env.require(
owners(acct, 2 + offerCount));
3323 env.require(
balance(acct, t.fundUSD));
3324 env.require(
balance(acct, t.fundEUR));
3327 BEAST_EXPECT(acctOffers.size() == offerCount);
3328 for (
auto const& offerPtr : acctOffers)
3330 auto const&
offer = *offerPtr;
3331 BEAST_EXPECT(
offer[sfLedgerEntryType] == ltOFFER);
3332 BEAST_EXPECT(
offer[sfTakerGets] == EUR(600));
3333 BEAST_EXPECT(
offer[sfTakerPays] == USD(500));
3336 env(
offer(acct, EUR(600), USD(500)),
ter(t.secondOfferTec));
3340 offerCount =
isTesSuccess(t.secondOfferTec) ? 1 : offerCount;
3341 env.require(
owners(acct, 2 + offerCount));
3342 env.require(
balance(acct, t.fundUSD));
3343 env.require(
balance(acct, t.fundEUR));
3346 BEAST_EXPECT(acctOffers.size() == offerCount);
3347 for (
auto const& offerPtr : acctOffers)
3349 auto const&
offer = *offerPtr;
3350 BEAST_EXPECT(
offer[sfLedgerEntryType] == ltOFFER);
3351 if (
offer[sfSequence] == firstOfferSeq)
3353 BEAST_EXPECT(
offer[sfTakerGets] == EUR(600));
3354 BEAST_EXPECT(
offer[sfTakerPays] == USD(500));
3358 BEAST_EXPECT(
offer[sfTakerGets] == USD(500));
3359 BEAST_EXPECT(
offer[sfTakerPays] == EUR(600));
3837 using namespace jtx;
3839 Env env{*
this, features};
3840 auto const baseFee = env.current()->fees().base.drops();
3842 auto const gw =
Account(
"gw");
3843 auto const BTC = gw[
"BTC"];
3844 auto const USD = gw[
"USD"];
3845 auto const startXrpBalance =
XRP(4000000);
3847 env.fund(startXrpBalance, gw);
3850 env(
rate(gw, 1.25));
3876 TestData
const tests[]{
3878 {0, 0, 1, BTC(20), {{
"ann", 0,
drops(3900000'000000 - (4 * baseFee)), BTC(20.0), USD(3000)}, {
"abe", 0,
drops(4100000'000000 - (3 * baseFee)), BTC( 0), USD(750)}}},
3879 {0, 1, 0, BTC(20), {{
"bev", 0,
drops(4100000'000000 - (4 * baseFee)), BTC( 7.5), USD(2000)}, {
"bob", 0,
drops(3900000'000000 - (3 * baseFee)), BTC(10), USD( 0)}}},
3880 {0, 0, 0, BTC(20), {{
"cam", 0,
drops(4000000'000000 - (5 * baseFee)), BTC(20.0), USD(2000)} }},
3881 {0, 1, 0, BTC( 5), {{
"deb", 1,
drops(4040000'000000 - (4 * baseFee)), BTC( 0.0), USD(2000)}, {
"dan", 1,
drops(3960000'000000 - (3 * baseFee)), BTC( 4), USD( 0)}}},
3885 for (
auto const& t : tests)
3887 Account const& self = t.actors[t.self].acct;
3888 Account const& leg0 = t.actors[t.leg0].acct;
3889 Account const& leg1 = t.actors[t.leg1].acct;
3891 for (
auto const& actor : t.actors)
3893 env.fund(
XRP(4000000), actor.acct);
3896 env(
trust(actor.acct, BTC(40)));
3897 env(
trust(actor.acct, USD(8000)));
3901 env(
pay(gw, self, t.btcStart));
3902 env(
pay(gw, self, USD(2000)));
3903 if (self.
id() != leg1.
id())
3904 env(
pay(gw, leg1, USD(2000)));
3909 env(
offer(leg0, BTC(10),
XRP(100000), tfPassive));
3913 env(
offer(leg1,
XRP(100000), USD(1000), tfPassive));
3918 env(
offer(self, USD(1000), BTC(10)));
3923 for (
auto const& actor : t.actors)
3929 actorOffers.begin(),
3931 actorOffers.begin(),
3934 return (*offer)[sfTakerGets].signum() == 0;
3936 BEAST_EXPECT(offerCount == actor.offers);
3938 env.require(
balance(actor.acct, actor.xrp));
3939 env.require(
balance(actor.acct, actor.btc));
3940 env.require(
balance(actor.acct, actor.usd));
4277 testcase(
"RippleConnect Smoketest payment flow");
4278 using namespace jtx;
4280 Env env{*
this, features};
4290 auto const hotUS =
Account(
"hotUS");
4291 auto const coldUS =
Account(
"coldUS");
4292 auto const hotEU =
Account(
"hotEU");
4293 auto const coldEU =
Account(
"coldEU");
4294 auto const mm =
Account(
"mm");
4296 auto const USD = coldUS[
"USD"];
4297 auto const EUR = coldEU[
"EUR"];
4299 env.fund(
XRP(100000), hotUS, coldUS, hotEU, coldEU, mm);
4303 for (
auto const& cold : {coldUS, coldEU})
4305 env(
fset(cold, asfRequireAuth));
4306 env(
fset(cold, asfDefaultRipple));
4311 env(
trust(hotUS, USD(10000000)),
txflags(tfSetNoRipple));
4312 env(
trust(hotEU, EUR(10000000)),
txflags(tfSetNoRipple));
4319 env(
trust(coldUS, USD(0), hotUS, tfSetfAuth));
4320 env(
trust(coldEU, EUR(0), hotEU, tfSetfAuth));
4321 env(
trust(coldUS, USD(0), mm, tfSetfAuth));
4322 env(
trust(coldEU, EUR(0), mm, tfSetfAuth));
4326 env(
pay(coldUS, hotUS, USD(5000000)));
4327 env(
pay(coldEU, hotEU, EUR(5000000)));
4328 env(
pay(coldUS, mm, USD(5000000)));
4329 env(
pay(coldEU, mm, EUR(5000000)));
4333 float const rate = 0.9f;
4334 env(
offer(mm, EUR(4000000 *
rate), USD(4000000)),
json(jss::Flags, tfSell));
4336 float const reverseRate = 1.0f /
rate * 1.00101f;
4337 env(
offer(mm, USD(4000000 * reverseRate), EUR(4000000)),
json(jss::Flags, tfSell));
4343 jvParams[jss::destination_account] = coldEU.human();
4344 jvParams[jss::destination_amount][jss::issuer] = coldEU.human();
4345 jvParams[jss::destination_amount][jss::currency] =
"EUR";
4346 jvParams[jss::destination_amount][jss::value] = 10;
4347 jvParams[jss::source_account] = hotUS.human();
4350 env.rpc(
"json",
"ripple_path_find",
to_string(jvParams))[jss::result]};
4352 BEAST_EXPECT(jrr[jss::status] ==
"success");
4353 BEAST_EXPECT(jrr[jss::alternatives].isArray() && jrr[jss::alternatives].size() > 0);
4356 env(
pay(hotUS, coldEU, EUR(10)),
sendmax(USD(11.1223326)));
4899 testcase(
"fixFillOrKill");
4900 using namespace jtx;
4901 Env env(*
this, features);
4902 Account const issuer(
"issuer");
4905 auto const USD = issuer[
"USD"];
4906 auto const EUR = issuer[
"EUR"];
4909 env.
fund(
XRP(1'000), maker, taker);
4912 env.
trust(USD(1'000), maker, taker);
4913 env.
trust(EUR(1'000), maker, taker);
4916 env(
pay(issuer, maker, USD(1'000)));
4917 env(
pay(issuer, taker, USD(1'000)));
4918 env(
pay(issuer, maker, EUR(1'000)));
4921 auto makerUSDBalance = env.
balance(maker, USD).
value();
4922 auto takerUSDBalance = env.
balance(taker, USD).
value();
4923 auto makerEURBalance = env.
balance(maker, EUR).
value();
4924 auto takerEURBalance = env.
balance(taker, EUR).
value();
4932 env(
offer(maker,
XRP(100), USD(100)));
4938 makerXRPBalance -=
txfee(env, 1);
4939 takerXRPBalance -=
txfee(env, 1);
4942 makerUSDBalance -= USD(100);
4943 takerUSDBalance += USD(100);
4944 makerXRPBalance +=
XRP(100).value();
4945 takerXRPBalance -=
XRP(100).value();
4949 env(
offer(maker, USD(100),
XRP(100)));
4955 makerXRPBalance -=
txfee(env, 1);
4956 takerXRPBalance -=
txfee(env, 1);
4959 makerUSDBalance += USD(100);
4960 takerUSDBalance -= USD(100);
4961 makerXRPBalance -=
XRP(100).value();
4962 takerXRPBalance +=
XRP(100).value();
4966 env(
offer(maker, USD(100), EUR(100)));
4969 env(
offer(taker, EUR(100), USD(101)),
txflags(tfFillOrKill),
ter(err));
4972 makerXRPBalance -=
txfee(env, 1);
4973 takerXRPBalance -=
txfee(env, 1);
4976 makerUSDBalance += USD(100);
4977 takerUSDBalance -= USD(100);
4978 makerEURBalance -= EUR(100);
4979 takerEURBalance += EUR(100);
4986 env(
offer(maker,
XRP(101), USD(101)));
4989 env(
offer(taker, USD(100),
XRP(101)),
txflags(tfFillOrKill | tfSell));
4992 makerUSDBalance -= USD(101);
4993 takerUSDBalance += USD(101);
4994 makerXRPBalance +=
XRP(101).value() -
txfee(env, 1);
4995 takerXRPBalance -=
XRP(101).value() +
txfee(env, 1);
4998 env(
offer(maker, USD(101),
XRP(101)));
5001 env(
offer(taker,
XRP(100), USD(101)),
txflags(tfFillOrKill | tfSell));
5004 makerUSDBalance += USD(101);
5005 takerUSDBalance -= USD(101);
5006 makerXRPBalance -=
XRP(101).value() +
txfee(env, 1);
5007 takerXRPBalance +=
XRP(101).value() -
txfee(env, 1);
5010 env(
offer(maker, USD(101), EUR(101)));
5013 env(
offer(taker, EUR(100), USD(101)),
txflags(tfFillOrKill | tfSell));
5016 makerUSDBalance += USD(101);
5017 takerUSDBalance -= USD(101);
5018 makerEURBalance -= EUR(101);
5019 takerEURBalance += EUR(101);
5020 makerXRPBalance -=
txfee(env, 1);
5021 takerXRPBalance -=
txfee(env, 1);
5026 for (
auto const flags : {tfFillOrKill, tfFillOrKill + tfSell})
5028 env(
offer(maker,
XRP(100), USD(100)));
5034 makerXRPBalance -=
txfee(env, 1);
5035 takerXRPBalance -=
txfee(env, 1);
5038 env(
offer(maker, USD(100),
XRP(100)));
5044 makerXRPBalance -=
txfee(env, 1);
5045 takerXRPBalance -=
txfee(env, 1);
5048 env(
offer(maker, USD(100), EUR(100)));
5054 makerXRPBalance -=
txfee(env, 1);
5055 takerXRPBalance -=
txfee(env, 1);
5060 env.
balance(maker, USD) == makerUSDBalance &&
5061 env.
balance(taker, USD) == takerUSDBalance &&
5062 env.
balance(maker, EUR) == makerEURBalance &&
5063 env.
balance(taker, EUR) == takerEURBalance &&
5064 env.
balance(maker,
XRP) == makerXRPBalance &&
5071 testCanceledOffer(features);
5072 testRmFundedOffer(features);
5073 testTinyPayment(features);
5074 testXRPTinyPayment(features);
5075 testEnforceNoRipple(features);
5076 testInsufficientReserve(features);
5077 testFillModes(features);
5078 testMalformed(features);
5079 testExpiration(features);
5080 testUnfundedCross(features);
5081 testSelfCross(
false, features);
5082 testSelfCross(
true, features);
5083 testNegativeBalance(features);
5084 testOfferCrossWithXRP(
true, features);
5085 testOfferCrossWithXRP(
false, features);
5086 testOfferCrossWithLimitOverride(features);
5087 testOfferAcceptThenCancel(features);
5088 testOfferCancelPastAndFuture(features);
5089 testCurrencyConversionEntire(features);
5090 testCurrencyConversionIntoDebt(features);
5091 testCurrencyConversionInParts(features);
5092 testCrossCurrencyStartXRP(features);
5093 testCrossCurrencyEndXRP(features);
5094 testCrossCurrencyBridged(features);
5095 testBridgedSecondLegDry(features);
5096 testOfferFeesConsumeFunds(features);
5097 testOfferCreateThenCross(features);
5098 testSellFlagBasic(features);
5099 testSellFlagExceedLimit(features);
5100 testGatewayCrossCurrency(features);
5101 testPartialCross(features);
5102 testXRPDirectCross(features);
5103 testDirectCross(features);
5104 testBridgedCross(features);
5105 testSellOffer(features);
5106 testSellWithFillOrKill(features);
5107 testTransferRateOffer(features);
5108 testSelfCrossOffer(features);
5109 testSelfIssueOffer(features);
5110 testBadPathAssert(features);
5111 testDirectToDirectPath(features);
5112 testSelfCrossLowQualityOffer(features);
5113 testOfferInScaling(features);
5114 testOfferInScalingWithXferRate(features);
5115 testOfferThresholdWithReducedFunds(features);
5116 testTinyOffer(features);
5117 testSelfPayXferFeeOffer(features);
5118 testSelfPayUnlimitedFunds(features);
5119 testRequireAuth(features);
5120 testMissingAuth(features);
5121 testRCSmoketest(features);
5122 testSelfAuth(features);
5123 testDeletedOfferIssuer(features);
5124 testTickSize(features);
5125 testTicketOffer(features);
5126 testTicketCancelOffer(features);
5127 testRmSmallIncreasedQOffersXRP(features);
5128 testRmSmallIncreasedQOffersIOU(features);
5129 testFillOrKill(features);