126 auto const gw =
Account(
"gateway");
133 auto test = [&](
auto&& issue1,
auto&& issue2) {
134 Env env(*
this, features);
136 env.
fund(
XRP(10'000), alice, bob, carol, gw);
139 auto const usd = issue1(
140 {.env = env, .token =
"USD", .issuer = gw, .holders = {alice, bob, carol}});
141 auto const btc = issue2(
142 {.env = env, .token =
"BTC", .issuer = gw, .holders = {alice, bob, carol}});
144 env(
pay(gw, alice, btc(50)));
145 env(
pay(gw, bob, usd(50)));
147 env(
offer(bob, btc(50), usd(50)));
155 BEAST_EXPECT(!
isOffer(env, bob, btc(50), usd(50)));
161 auto test = [&](
auto&& issue1,
auto&& issue2) {
162 Env env(*
this, features);
164 env.
fund(
XRP(10'000), alice, bob, carol, gw);
167 auto const usd = issue1(
168 {.env = env, .token =
"USD", .issuer = gw, .holders = {alice, bob, carol}});
169 auto const btc = issue2(
170 {.env = env, .token =
"BTC", .issuer = gw, .holders = {alice, bob, carol}});
172 env(
pay(gw, alice, btc(50)));
173 env(
pay(gw, bob, usd(50)));
184 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), usd(50)));
185 BEAST_EXPECT(!
isOffer(env, bob, btc(50),
XRP(50)));
191 Env env(*
this, features);
193 env.
fund(
XRP(10'000), alice, bob, carol, gw);
196 MPT const usd =
MPTTester({.env = env, .issuer = gw, .holders = {alice, bob, carol}});
197 MPT const btc =
MPTTester({.env = env, .issuer = gw, .holders = {alice, bob, carol}});
199 env(
pay(gw, bob, usd(50)));
211 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), usd(50)));
215 Env env(*
this, features);
217 env.
fund(
XRP(10'000), alice, bob, carol, gw);
220 MPT const usd =
MPTTester({.env = env, .issuer = gw, .holders = {alice, bob, carol}});
221 MPT const btc =
MPTTester({.env = env, .issuer = gw, .holders = {alice, bob, carol}});
223 env(
pay(gw, alice, usd(50)));
233 BEAST_EXPECT(!
isOffer(env, bob, usd(50),
XRP(50)));
237 auto test = [&](
auto&& issue1,
auto&& issue2,
auto&& issue3) {
238 Env env(*
this, features);
240 env.
fund(
XRP(10'000), alice, bob, carol, gw);
243 auto const usd = issue1(
244 {.env = env, .token =
"USD", .issuer = gw, .holders = {alice, bob, carol}});
245 auto const btc = issue2(
246 {.env = env, .token =
"BTC", .issuer = gw, .holders = {alice, bob, carol}});
247 auto const eur = issue3(
248 {.env = env, .token =
"EUR", .issuer = gw, .holders = {alice, bob, carol}});
250 env(
pay(gw, alice, btc(60)));
251 env(
pay(gw, bob, usd(50)));
252 env(
pay(gw, bob, eur(50)));
254 env(
offer(bob, btc(50), usd(50)));
255 env(
offer(bob, btc(40), eur(50)));
256 env(
offer(bob, eur(50), usd(50)));
259 env(
pay(bob, gw, eur(50)));
261 BEAST_EXPECT(
isOffer(env, bob, btc(50), usd(50)));
262 BEAST_EXPECT(
isOffer(env, bob, btc(40), eur(50)));
263 BEAST_EXPECT(
isOffer(env, bob, eur(50), usd(50)));
273 BEAST_EXPECT(!
isOffer(env, bob, btc(50), usd(50)));
275 BEAST_EXPECT(!
isOffer(env, bob, btc(40), eur(50)));
277 BEAST_EXPECT(
isOffer(env, bob, eur(50), usd(50)));
290 auto test = [&](
auto&& issue1,
auto&& issue2,
auto&& issue3) {
291 Env env(*
this, features);
293 env.
fund(
XRP(10'000), alice, bob, carol, gw);
296 auto const usd = issue1(
300 .holders = {alice, bob, carol},
302 auto const btc = issue2(
306 .holders = {alice, bob, carol},
308 auto const eur = issue3(
312 .holders = {alice, bob, carol},
315 env(
pay(gw, alice, btc(60)));
316 env(
pay(gw, bob, usd(6'000)));
317 env(
pay(gw, bob, eur(5'000)));
318 env(
pay(gw, carol, eur(100)));
320 env(
offer(bob, btc(50), usd(5'000)));
321 env(
offer(bob, btc(60), eur(5'000)));
322 env(
offer(carol, btc(1'000), eur(100)));
323 env(
offer(bob, eur(5'000), usd(5'000)));
326 env(
pay(bob, gw, eur(5'000)));
327 BEAST_EXPECT(
isOffer(env, bob, btc(50), usd(5'000)));
328 BEAST_EXPECT(
isOffer(env, bob, btc(60), eur(5'000)));
329 BEAST_EXPECT(
isOffer(env, carol, btc(1'000), eur(100)));
332 auto const flowResult = [&] {
369 BEAST_EXPECT(flowResult.removableOffers.size() == 1);
371 if (flowResult.removableOffers.empty())
374 for (
auto const& o : flowResult.removableOffers)
385 BEAST_EXPECT(
isOffer(env, bob, btc(50), usd(5'000)));
386 BEAST_EXPECT(
isOffer(env, carol, btc(1'000), eur(100)));
388 BEAST_EXPECT(!
isOffer(env, bob, btc(60), eur(5'000)));
401 auto test = [&](
auto&& issue1,
auto&& issue2) {
402 Env env(*
this, features);
403 env.
fund(
XRP(10'000), alice, bob, carol, gw);
405 auto const usd = issue1(
406 {.env = env, .token =
"USD", .issuer = gw, .holders = {alice, bob, carol}});
407 auto const eur = issue1(
408 {.env = env, .token =
"EUR", .issuer = gw, .holders = {alice, bob, carol}});
410 env(
pay(gw, alice, usd(1'000)));
411 env(
pay(gw, bob, eur(1'000)));
417 bool const reducedOffersV2 = features[fixReducedOffersV2];
425 env(
pay(alice, carol, eur(1)),
428 Txflags(tfNoRippleDirect | tfPartialPayment),
431 if (!reducedOffersV2)
439 if (BEAST_EXPECT(usdOffer))
446 bookDirStr.
erase(0, 48);
450 getRate(usdOffer->at(sfTakerGets), usdOffer->at(sfTakerPays));
457 BEAST_EXPECT(actualRate > bookRate);
1441 testcase(
"Max Flow/Self Payment Edge Cases");
1442 using namespace jtx;
1452 env.
fund(
XRP(1'000), gw, alice, carol);
1455 MPTTester({.env = env, .issuer = gw, .holders = {alice, carol}, .maxAmt = 100});
1457 env(
pay(gw, alice, usd(100)));
1459 env(
pay(alice, carol, usd(100)));
1461 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1462 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1463 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1471 env.
fund(
XRP(1'000), gw, alice, carol);
1474 MPTTester({.env = env, .issuer = gw, .holders = {alice, carol}, .maxAmt = 100});
1476 env(
pay(gw, alice, usd(80)));
1478 env(
pay(alice, carol, usd(100)),
Txflags(tfPartialPayment));
1480 BEAST_EXPECT(env.
balance(gw, usd) == usd(-80));
1481 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1482 BEAST_EXPECT(env.
balance(carol, usd) == usd(80));
1491 env.
fund(
XRP(1'000), gw, alice, carol, bob);
1494 {.env = env, .issuer = gw, .holders = {alice, carol, bob}, .maxAmt = 100});
1496 env(
pay(gw, bob, usd(20)));
1497 env(
pay(gw, alice, usd(80)));
1499 env(
pay(alice, carol, usd(100)),
Txflags(tfPartialPayment));
1501 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1502 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1503 BEAST_EXPECT(env.
balance(carol, usd) == usd(80));
1512 env.
fund(
XRP(1'000), gw, alice, carol, bob);
1515 MPTTester({.env = env, .issuer = gw, .holders = {alice, carol}, .maxAmt = 100});
1517 env(
pay(gw, alice, usd(100)));
1519 env(
offer(alice,
XRP(100), usd(100)));
1523 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1524 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1525 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1535 env.
fund(
XRP(1'000), gw, alice, carol);
1538 MPTTester({.env = env, .issuer = gw, .holders = {carol}, .maxAmt = 100});
1540 env(
pay(gw, carol, usd(100)));
1542 env(
offer(gw,
XRP(100), usd(100)));
1544 env(
pay(alice, carol, usd(100)),
1550 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1551 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1560 env.
fund(
XRP(1'000), gw, alice, carol);
1563 MPTTester({.env = env, .issuer = gw, .holders = {carol}, .maxAmt = 100});
1565 env(
pay(gw, carol, usd(80)));
1567 env(
offer(gw,
XRP(100), usd(100)));
1569 env(
pay(alice, carol, usd(100)),
1574 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1575 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1584 env.
fund(
XRP(1'000), gw, alice);
1587 MPTTester({.env = env, .issuer = gw, .holders = {alice}, .maxAmt = 100});
1589 env(
pay(gw, alice, usd(100)));
1591 env(
offer(alice, usd(100),
XRP(100)));
1595 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1596 BEAST_EXPECT(env.
balance(alice, usd) == usd(100));
1605 auto test = [&](
auto&& issue1,
auto&& issue2) {
1608 env.
fund(
XRP(1'000), gw, alice, carol);
1611 auto const usd = issue1(
1615 .holders = {alice, carol},
1618 auto const eur = issue2(
1622 .holders = {alice, carol},
1625 env(
pay(gw, alice, usd(100)));
1627 env(
offer(alice, eur(100), usd(100)));
1632 BEAST_EXPECT(env.
balance(gw, usd) == usd(-100));
1633 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1634 BEAST_EXPECT(env.
balance(alice, eur) == eur(100));
1635 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1645 env.
fund(
XRP(1'000), gw, alice, carol);
1648 MPTTester({.env = env, .issuer = gw, .holders = {carol}, .maxAmt = 120});
1650 env(
pay(gw, carol, usd(100)));
1652 env(
offer(carol,
XRP(100), usd(100)));
1654 env(
pay(alice, carol, usd(100)),
1659 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1668 env.
fund(
XRP(1'000), gw, alice, carol);
1671 MPTTester({.env = env, .issuer = gw, .holders = {carol}, .maxAmt = 100});
1673 env(
pay(gw, carol, usd(100)));
1675 env(
offer(carol,
XRP(100), usd(100)));
1677 env(
pay(alice, carol, usd(100)),
1682 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
1688 auto test = [&](
auto&& issue1,
auto&& issue2) {
1691 env.
fund(
XRP(1'000), gw, alice, carol, bob);
1694 auto const usd = issue1(
1698 .holders = {alice, carol, bob},
1701 auto const eur = issue2(
1705 .holders = {alice, carol, bob},
1709 env(
pay(gw, alice, usd(600)));
1710 env(
pay(gw, carol, eur(700)));
1712 env(
offer(alice, eur(100), usd(105)));
1713 env(
offer(gw, eur(100), usd(104)));
1714 env(
offer(gw, eur(100), usd(103)));
1715 env(
offer(gw, eur(100), usd(102)));
1716 env(
offer(gw, eur(100), usd(101)));
1717 env(
offer(gw, eur(100), usd(100)));
1719 env(
pay(carol, bob, usd(2'000)),
1726 BEAST_EXPECT(env.
balance(gw, usd) == usd(-1'000));
1727 BEAST_EXPECT(env.
balance(alice, usd) == usd(495));
1728 BEAST_EXPECT(env.
balance(bob, usd) == usd(505));
1732 BEAST_EXPECT(env.
balance(gw, usd) == usd(0));
1733 BEAST_EXPECT(env.
balance(alice, usd) == usd(495));
1736 BEAST_EXPECT(env.
balance(bob, usd) == usd(615));
1742 BEAST_EXPECT(env.
balance(carol, eur) == eur(210));
1747 BEAST_EXPECT(env.
balance(carol, eur) == eur(100));
1753 env.
balance(carol, eur) ==
STAmount(eur, UINT64_C(209'9009900990099), -13));
1770 env.
fund(
XRP(1'000), gw, alice, carol);
1773 MPTTester({.env = env, .issuer = gw, .holders = {alice, carol}, .maxAmt = 2'000});
1775 env(
pay(gw, carol, usd(1'000)));
1776 env(
pay(gw, alice, usd(600)));
1780 env(
offer(carol,
XRP(7), usd(15)));
1781 env(
offer(carol,
XRP(17), usd(35)));
1782 env(
offer(carol,
XRP(23), usd(47)));
1783 env(
offer(alice,
XRP(10), usd(19)));
1784 env(
offer(alice,
XRP(15), usd(28)));
1785 env(
offer(alice,
XRP(25), usd(46)));
1789 BEAST_EXPECT(env.
balance(gw, usd) == usd(-1'624));
1790 BEAST_EXPECT(env.
balance(carol, usd) == usd(1'102));
1794 BEAST_EXPECT(
isOffer(env, alice,
XRP(8), usd(15)));
1801 env.
fund(
XRP(1'000), gw, alice, carol, bob);
1804 MPTTester({.env = env, .issuer = gw, .holders = {alice, carol, bob}, .maxAmt = 30});
1806 env(
pay(gw, alice, usd(12)));
1807 env(
pay(gw, bob, usd(5)));
1809 env(
offer(alice,
XRP(10), usd(12)));
1814 BEAST_EXPECT(env.
balance(gw, usd) == usd(-28));
1815 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1817 BEAST_EXPECT(env.
balance(bob, usd) == usd(28));
1843 expOffersBob()
const
1845 return expBobSellUSD == 0 ? 1 : 0;
1851 return expEdBuyUSD < 100 ? 1 : 0;
1854 expOffersDan()
const
1856 return expDanBuyUSD == 0 ? 1 : 0;
1860 auto test = [&](TestData
const& d) {
1862 env.
fund(
XRP(1'000), gw, alice, carol, bob, dan, john, ed, sam, bill);
1866 {.env = env, .issuer = gw, .holders = {alice, carol, bob}, .maxAmt = d.maxAmt});
1867 auto const eur = gw[
"EUR"];
1869 env(
pay(gw, alice, usd(100)));
1870 env(
pay(gw, carol, usd(100)));
1871 env(
pay(gw, bob, usd(100)));
1873 BEAST_EXPECT(env.
balance(gw, usd) == usd(-300));
1875 env(
trust(john, eur(100)));
1876 env(
trust(dan, eur(100)));
1877 env(
trust(ed, eur(100)));
1878 env(
trust(bill, eur(d.dstTrustLimit)));
1880 env(
pay(gw, john, eur(100)));
1881 env(
pay(gw, dan, eur(100)));
1882 env(
pay(gw, ed, eur(100)));
1886 env(
offer(alice,
XRP(100), usd(100)));
1889 env(
offer(carol,
XRP(100), usd(100)));
1891 if (!d.lastGwBuyUSD)
1893 env(
offer(gw,
XRP(100), usd(100)));
1896 env(
offer(bob,
XRP(100), usd(100)));
1900 env(
offer(gw,
XRP(100), usd(100)));
1909 env(
offer(john, usd(100), eur(100)));
1911 env(
offer(gw, usd(100), eur(100)));
1913 env(
offer(dan, usd(100), eur(100)));
1915 env(
offer(ed, usd(100), eur(100)));
1922 env(
pay(sam, bill, eur(400)),
1925 Txflags(tfPartialPayment | tfNoRippleDirect));
1928 auto const baseFee = env.
current()->fees().base.drops();
1929 BEAST_EXPECT(env.
balance(bill, eur) == eur(d.dstExpectEUR));
1930 BEAST_EXPECT(env.
balance(john, usd) == usd(100));
1931 BEAST_EXPECT(env.
balance(dan, usd) == usd(d.expDanBuyUSD));
1932 BEAST_EXPECT(env.
balance(ed, usd) == usd(d.expEdBuyUSD));
1933 BEAST_EXPECT(env.
balance(gw, usd) == usd(-d.outstandingUSD));
1934 BEAST_EXPECT(env.
balance(alice, usd) == usd(0));
1935 BEAST_EXPECT(env.
balance(carol, usd) == usd(0));
1936 BEAST_EXPECT(env.
balance(bob, usd) == usd(100 - d.expBobSellUSD));
1937 BEAST_EXPECT(env.
balance(gw) ==
XRPAmount{d.expGwXRP * kDropsPerXrp - baseFee * 9});
1940 BEAST_EXPECT(
expectOffers(env, dan, d.expOffersDan()));
1944 BEAST_EXPECT(
expectOffers(env, bob, d.expOffersBob()));
1955 { .maxAmt=400, .sendMax=400, .dstTrustLimit=400, .dstExpectEUR=400, .outstandingUSD=300, .expEdBuyUSD=100, .expDanBuyUSD=100, .expBobSellUSD=100, .expGwXRP=1100, .expOffersGw=0, .lastGwBuyUSD=
false},
1964 { .maxAmt=350, .sendMax=400, .dstTrustLimit=400, .dstExpectEUR=350, .outstandingUSD=250, .expEdBuyUSD=50, .expDanBuyUSD=100, .expBobSellUSD=100, .expGwXRP=1050, .expOffersGw=0, .lastGwBuyUSD=
false},
1970 { .maxAmt=300, .sendMax=400, .dstTrustLimit=400, .dstExpectEUR=300, .outstandingUSD=200, .expEdBuyUSD=0, .expDanBuyUSD=100, .expBobSellUSD=100, .expGwXRP=1000, .expOffersGw=0, .lastGwBuyUSD=
false},
1973 { .maxAmt=300, .sendMax=400, .dstTrustLimit=300, .dstExpectEUR=300, .outstandingUSD=200, .expEdBuyUSD=0, .expDanBuyUSD=100, .expBobSellUSD=100, .expGwXRP=1000, .expOffersGw=0, .lastGwBuyUSD=
false},
1979 { .maxAmt=300, .sendMax=400, .dstTrustLimit=300, .dstExpectEUR=300, .outstandingUSD=200, .expEdBuyUSD=0, .expDanBuyUSD=100, .expBobSellUSD=100, .expGwXRP=1000, .expOffersGw=0, .lastGwBuyUSD=
true},
1986 { .maxAmt=300, .sendMax=200, .dstTrustLimit=300, .dstExpectEUR=200, .outstandingUSD=200, .expEdBuyUSD=0, .expDanBuyUSD=0, .expBobSellUSD=0, .expGwXRP=1000, .expOffersGw=0, .lastGwBuyUSD=
false},
1989 { .maxAmt=300, .sendMax=380, .dstTrustLimit=400, .dstExpectEUR=300, .outstandingUSD=200, .expEdBuyUSD=0, .expDanBuyUSD=100, .expBobSellUSD=100, .expGwXRP=1000, .expOffersGw=0, .lastGwBuyUSD=
false},
1992 for (
auto const& t :
tests)
2013 expOffersBob()
const
2016 return expBobBuyUSD < 100 ? 1 : 0;
2020 auto test = [&](TestData
const& d) {
2022 env.
fund(
XRP(1'000), gw, alice, carol, bob, ed);
2026 MPTTester({.env = env, .issuer = gw, .holders = {alice}, .maxAmt = d.maxAmt});
2028 env(
pay(gw, alice, usd(300)));
2031 env(
offer(carol, usd(100),
XRP(100)));
2033 if (!d.lastGwBuyUSD)
2035 env(
offer(gw, usd(d.gwOffer),
XRP(d.gwOffer)));
2038 env(
offer(bob, usd(100),
XRP(100)));
2042 env(
offer(gw, usd(d.gwOffer),
XRP(d.gwOffer)));
2049 BEAST_EXPECT(env.
balance(gw, usd) == usd(-300));
2051 env(
pay(alice, ed,
XRP(300)),
2054 Txflags(tfPartialPayment | tfNoRippleDirect));
2057 auto const baseFee = env.
current()->fees().base.drops();
2058 BEAST_EXPECT(env.
balance(alice, usd) == usd(300 - d.sendMax));
2059 BEAST_EXPECT(env.
balance(carol, usd) == usd(100));
2060 BEAST_EXPECT(env.
balance(bob, usd) == usd(d.expBobBuyUSD));
2061 BEAST_EXPECT(env.
balance(ed) ==
XRP(d.dstExpectXRP));
2062 BEAST_EXPECT(env.
balance(gw, usd) == usd(-d.outstandingUSD));
2063 BEAST_EXPECT(env.
balance(gw) ==
XRPAmount{d.expGwXRP * kDropsPerXrp - baseFee * 3});
2065 BEAST_EXPECT(
expectOffers(env, bob, d.expOffersBob()));
2075 { .maxAmt=300, .sendMax=300, .gwOffer=100, .dstExpectXRP=1300, .outstandingUSD=200, .expBobBuyUSD=100, .expGwXRP=900, .expOffersGw=0, .lastGwBuyUSD=
false},
2078 { .maxAmt=300, .sendMax=300, .gwOffer=100, .dstExpectXRP=1300, .outstandingUSD=200, .expBobBuyUSD=100, .expGwXRP=900, .expOffersGw=0, .lastGwBuyUSD=
true},
2083 { .maxAmt=300, .sendMax=300, .gwOffer=200, .dstExpectXRP=1300, .outstandingUSD=100, .expBobBuyUSD=0, .expGwXRP=800, .expOffersGw=0, .lastGwBuyUSD=
false},
2088 { .maxAmt=300, .sendMax=300, .gwOffer=200, .dstExpectXRP=1300, .outstandingUSD=200, .expBobBuyUSD=100, .expGwXRP=900, .expOffersGw=1, .lastGwBuyUSD=
true},
2094 { .maxAmt=300, .sendMax=250, .gwOffer=200, .dstExpectXRP=1250, .outstandingUSD=250, .expBobBuyUSD=100, .expGwXRP=950, .expOffersGw=1, .lastGwBuyUSD=
true},
2097 for (
auto const& t :
tests)
2120 expOffersBob()
const
2122 return expBobSellUSD > 0 && expBobSellUSD < 100 ? 1 : 0;
2126 auto test = [&](TestData
const& d) {
2128 env.
fund(
XRP(1'000), gw, alice, carol, bob, ed);
2132 {.env = env, .issuer = gw, .holders = {carol, bob, ed}, .maxAmt = d.maxAmt});
2135 env(
pay(gw, ed, usd(d.initDst)));
2136 env(
pay(gw, carol, usd(100)));
2137 env(
pay(gw, bob, usd(100)));
2140 env(
offer(carol,
XRP(100), usd(100)));
2142 if (!d.lastGwBuyUSD)
2144 env(
offer(gw,
XRP(d.gwOffer), usd(d.gwOffer)));
2147 env(
offer(bob,
XRP(100), usd(100)));
2151 env(
offer(gw,
XRP(d.gwOffer), usd(d.gwOffer)));
2158 BEAST_EXPECT(env.
balance(gw, usd) == usd(-200 - d.initDst));
2160 env(
pay(alice, ed, usd(300)),
2163 Txflags(tfPartialPayment | tfNoRippleDirect));
2166 auto const baseFee = env.
current()->fees().base.drops();
2169 BEAST_EXPECT(env.
balance(carol, usd) == usd(0));
2170 BEAST_EXPECT(env.
balance(bob, usd) == usd(100 - d.expBobSellUSD));
2171 BEAST_EXPECT(env.
balance(ed, usd) == usd(d.dstExpectUSD));
2172 BEAST_EXPECT(env.
balance(gw, usd) == usd(-d.outstandingUSD));
2176 d.expGwXRP * kDropsPerXrp - baseFee * (4 + (d.initDst != 0 ? 1 : 0))});
2178 BEAST_EXPECT(
expectOffers(env, bob, d.expOffersBob()));
2187 { .maxAmt=300, .sendMax=300, .initDst=0, .gwOffer=100, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=700, .expBobSellUSD=100, .expGwXRP=1100, .expOffersGw=0, .lastGwBuyUSD=
false},
2190 { .maxAmt=300, .sendMax=300, .initDst=0, .gwOffer=100, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=700, .expBobSellUSD=100, .expGwXRP=1100, .expOffersGw=0, .lastGwBuyUSD=
true},
2198 { .maxAmt=300, .sendMax=300, .initDst=50, .gwOffer=100, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=750, .expBobSellUSD=100, .expGwXRP=1050, .expOffersGw=0, .lastGwBuyUSD=
false},
2201 { .maxAmt=300, .sendMax=300, .initDst=50, .gwOffer=100, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=750, .expBobSellUSD=100, .expGwXRP=1050, .expOffersGw=0, .lastGwBuyUSD=
true},
2204 { .maxAmt=300, .sendMax=300, .initDst=50, .gwOffer=200, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=750, .expBobSellUSD=100, .expGwXRP=1050, .expOffersGw=0, .lastGwBuyUSD=
true},
2209 { .maxAmt=300, .sendMax=250, .initDst=0, .gwOffer=100, .dstExpectUSD=250, .outstandingUSD=300, .expAliceXRP=750, .expBobSellUSD=50, .expGwXRP=1100, .expOffersGw=0, .lastGwBuyUSD=
false},
2214 { .maxAmt=300, .sendMax=250, .initDst=0, .gwOffer=100, .dstExpectUSD=250, .outstandingUSD=250, .expAliceXRP=750, .expBobSellUSD=100, .expGwXRP=1050, .expOffersGw=1, .lastGwBuyUSD=
true},
2219 { .maxAmt=300, .sendMax=250, .initDst=50, .gwOffer=100, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=750, .expBobSellUSD=100, .expGwXRP=1050, .expOffersGw=0, .lastGwBuyUSD=
true},
2224 { .maxAmt=300, .sendMax=250, .initDst=100, .gwOffer=100, .dstExpectUSD=300, .outstandingUSD=300, .expAliceXRP=800, .expBobSellUSD=100, .expGwXRP=1000, .expOffersGw=0, .lastGwBuyUSD=
true},
2227 for (
auto const& t :
tests)
2236 env.
fund(
XRP(1'000), gw, alice, carol);
2238 MPT const usd =
MPTTester({.env = env, .issuer = gw, .maxAmt = 300});
2240 env(
offer(carol, usd(400),
XRP(400)));
2241 env(
offer(gw, usd(100),
XRP(100)));
2245 env(
pay(gw, alice,
XRP(500)),
2248 Txflags(tfPartialPayment | tfNoRippleDirect));
2250 BEAST_EXPECT(env.
balance(alice) ==
XRP(dstXRP));
2251 BEAST_EXPECT(env.
balance(gw, usd) == usd(-300));
2252 BEAST_EXPECT(env.
balance(carol, usd) == usd(300));
2262 test(500, 1'400, 0);
2270 test(350, 1'350, 1);