mirror of
https://github.com/Xahau/xahaud.git
synced 2026-03-16 17:42:22 +00:00
Merge fixAMMv1_3 amendment into featureAMM amendment
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
// If you add an amendment here, then do not forget to increment `numFeatures`
|
||||
// in include/xrpl/protocol/Feature.h.
|
||||
|
||||
XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(HookAPISerializedType240, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionedDomains, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicNFT, Supported::no, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -581,12 +581,8 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
AMM amm(env, alice, EUR(5000), USD(4000), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4000), EUR(5000), IOUAmount{4472135954999580, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4000), EUR(5000), IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4000), EUR(5000), IOUAmount{4472135954999579, -12}));
|
||||
|
||||
// gw clawback 1000 USD from the AMM pool
|
||||
env(amm::ammClawback(gw, alice, USD, EUR, USD(1000)),
|
||||
@@ -605,20 +601,12 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
|
||||
// 1000 USD and 1250 EUR was withdrawn from the AMM pool, so the
|
||||
// current balance is 3000 USD and 3750 EUR.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(3000), EUR(3750), IOUAmount{3354101966249685, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(3000), EUR(3750), IOUAmount{3354101966249684, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(3000), EUR(3750), IOUAmount{3354101966249684, -12}));
|
||||
|
||||
// Alice has 3/4 of its initial lptokens Left.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{3354101966249685, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{3354101966249684, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{3354101966249684, -12}));
|
||||
|
||||
// gw clawback another 500 USD from the AMM pool.
|
||||
env(amm::ammClawback(gw, alice, USD, EUR, USD(500)),
|
||||
@@ -629,21 +617,10 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
// AMM pool.
|
||||
env.require(balance(alice, gw["USD"](2000)));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(2500000000000001), -12},
|
||||
STAmount{EUR, UINT64_C(3125000000000001), -12},
|
||||
IOUAmount{2795084971874738, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), EUR(3125), IOUAmount{2795084971874737, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), EUR(3125), IOUAmount{2795084971874737, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
env.balance(alice, EUR) ==
|
||||
STAmount(EUR, UINT64_C(2874999999999999), -12));
|
||||
else
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(2875));
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(2875));
|
||||
|
||||
// gw clawback small amount, 1 USD.
|
||||
env(amm::ammClawback(gw, alice, USD, EUR, USD(1)), ter(tesSUCCESS));
|
||||
@@ -652,21 +629,10 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
// Another 1 USD / 1.25 EUR was withdrawn.
|
||||
env.require(balance(alice, gw["USD"](2000)));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(2499000000000002), -12},
|
||||
STAmount{EUR, UINT64_C(3123750000000002), -12},
|
||||
IOUAmount{2793966937885989, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2499), EUR(3123.75), IOUAmount{2793966937885987, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2499), EUR(3123.75), IOUAmount{2793966937885987, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
env.balance(alice, EUR) ==
|
||||
STAmount(EUR, UINT64_C(2'876'249999999998), -12));
|
||||
else
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(2876.25));
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(2876.25));
|
||||
|
||||
// gw clawback 4000 USD, exceeding the current balance. We
|
||||
// will clawback all.
|
||||
@@ -739,26 +705,14 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
|
||||
// gw2 creates AMM pool of XRP/EUR, alice and bob deposit XRP/EUR.
|
||||
AMM amm2(env, gw2, XRP(3000), EUR(1000), ter(tesSUCCESS));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(1000), XRP(3000), IOUAmount{1732050807568878, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(1000), XRP(3000), IOUAmount{1732050807568877, -9}));
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(1000), XRP(3000), IOUAmount{1732050807568877, -9}));
|
||||
amm2.deposit(alice, EUR(1000), XRP(3000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2000), XRP(6000), IOUAmount{3464101615137756, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2000), XRP(6000), IOUAmount{3464101615137754, -9}));
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2000), XRP(6000), IOUAmount{3464101615137754, -9}));
|
||||
amm2.deposit(bob, EUR(1000), XRP(3000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(3000), XRP(9000), IOUAmount{5196152422706634, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(3000), XRP(9000), IOUAmount{5196152422706631, -9}));
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(3000), XRP(9000), IOUAmount{5196152422706631, -9}));
|
||||
env.close();
|
||||
|
||||
auto aliceXrpBalance = env.balance(alice, XRP);
|
||||
@@ -781,18 +735,10 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(
|
||||
expectLedgerEntryRoot(env, alice, aliceXrpBalance + XRP(1000)));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), XRP(5000), IOUAmount{3535533905932738, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), XRP(5000), IOUAmount{3535533905932737, -9}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{7071067811865480, -10}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{7071067811865474, -10}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), XRP(5000), IOUAmount{3535533905932737, -9}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{7071067811865474, -10}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1414213562373095, -9}));
|
||||
|
||||
@@ -806,26 +752,12 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
// Bob gets 20 XRP back.
|
||||
BEAST_EXPECT(
|
||||
expectLedgerEntryRoot(env, bob, bobXrpBalance + XRP(20)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(2490000000000001), -12},
|
||||
XRP(4980),
|
||||
IOUAmount{3521391770309008, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2'490), XRP(4980), IOUAmount{3521391770309006, -9}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{7071067811865480, -10}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{7071067811865474, -10}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1400071426749365, -9}));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1400071426749364, -9}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2'490), XRP(4980), IOUAmount{3521391770309006, -9}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{7071067811865474, -10}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1400071426749364, -9}));
|
||||
|
||||
// gw2 clawback 200 EUR from amm2.
|
||||
env(amm::ammClawback(gw2, alice, EUR, XRP, EUR(200)),
|
||||
@@ -838,24 +770,12 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
// Alice gets 600 XRP back.
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(1000) + XRP(600)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2800), XRP(8400), IOUAmount{4849742261192859, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2800), XRP(8400), IOUAmount{4849742261192856, -9}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectLPTokens(
|
||||
alice, IOUAmount{1385640646055103, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectLPTokens(
|
||||
alice, IOUAmount{1385640646055102, -9}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
amm2.expectLPTokens(bob, IOUAmount{1732050807568878, -9}));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
amm2.expectLPTokens(bob, IOUAmount{1732050807568877, -9}));
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2800), XRP(8400), IOUAmount{4849742261192856, -9}));
|
||||
BEAST_EXPECT(
|
||||
amm2.expectLPTokens(alice, IOUAmount{1385640646055102, -9}));
|
||||
BEAST_EXPECT(
|
||||
amm2.expectLPTokens(bob, IOUAmount{1732050807568877, -9}));
|
||||
|
||||
// gw claw back 1000 USD from alice in amm, which exceeds alice's
|
||||
// balance. This will clawback all the remaining LP tokens of alice
|
||||
@@ -868,34 +788,18 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
env.require(balance(bob, gw["USD"](4000)));
|
||||
|
||||
// Alice gets 1000 XRP back.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000)));
|
||||
else
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) -
|
||||
XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) -
|
||||
XRPAmount{1}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(alice, IOUAmount(0)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1400071426749365, -9}));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1400071426749364, -9}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(1990000000000001), -12},
|
||||
XRP(3980),
|
||||
IOUAmount{2814284989122460, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(1'990),
|
||||
XRPAmount{3'980'000'001},
|
||||
IOUAmount{2814284989122459, -9}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{1400071426749364, -9}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(1'990),
|
||||
XRPAmount{3'980'000'001},
|
||||
IOUAmount{2814284989122459, -9}));
|
||||
|
||||
// gw clawback 1000 USD from bob in amm, which also exceeds bob's
|
||||
// balance in amm. All bob's lptoken in amm will be consumed, which
|
||||
@@ -907,17 +811,11 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
env.require(balance(alice, gw["USD"](5000)));
|
||||
env.require(balance(bob, gw["USD"](4000)));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000)));
|
||||
else
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) -
|
||||
XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) -
|
||||
XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, bob, bobXrpBalance + XRP(20) + XRP(1980)));
|
||||
|
||||
@@ -937,30 +835,19 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
|
||||
// Alice gets another 2400 XRP back, bob's XRP balance remains the
|
||||
// same.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) +
|
||||
XRP(2400)));
|
||||
else
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) +
|
||||
XRP(2400) - XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) + XRP(2400) -
|
||||
XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, bob, bobXrpBalance + XRP(20) + XRP(1980)));
|
||||
|
||||
// Alice now does not have any lptoken in amm2
|
||||
BEAST_EXPECT(amm2.expectLPTokens(alice, IOUAmount(0)));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2000), XRP(6000), IOUAmount{3464101615137756, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2000), XRP(6000), IOUAmount{3464101615137754, -9}));
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(2000), XRP(6000), IOUAmount{3464101615137754, -9}));
|
||||
|
||||
// gw2 claw back 2000 EUR from bob in amm2, which exceeds bob's
|
||||
// balance. All bob's lptokens will be consumed, which corresponds
|
||||
@@ -974,18 +861,11 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
|
||||
// Bob gets another 3000 XRP back. Alice's XRP balance remains the
|
||||
// same.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) +
|
||||
XRP(2400)));
|
||||
else
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) +
|
||||
XRP(2400) - XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env,
|
||||
alice,
|
||||
aliceXrpBalance + XRP(1000) + XRP(600) + XRP(1000) + XRP(2400) -
|
||||
XRPAmount{1}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, bob, bobXrpBalance + XRP(20) + XRP(1980) + XRP(3000)));
|
||||
|
||||
@@ -993,12 +873,8 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(amm2.expectLPTokens(alice, IOUAmount(0)));
|
||||
BEAST_EXPECT(amm2.expectLPTokens(bob, IOUAmount(0)));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(1000), XRP(3000), IOUAmount{1732050807568878, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(1000), XRP(3000), IOUAmount{1732050807568877, -9}));
|
||||
BEAST_EXPECT(amm2.expectBalances(
|
||||
EUR(1000), XRP(3000), IOUAmount{1732050807568877, -9}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1056,45 +932,21 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
AMM amm(env, alice, EUR(5000), USD(4000), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4000), EUR(5000), IOUAmount{4472135954999580, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4000), EUR(5000), IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4000), EUR(5000), IOUAmount{4472135954999579, -12}));
|
||||
amm.deposit(bob, USD(2000), EUR(2500));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(6000), EUR(7500), IOUAmount{6708203932499370, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(6000), EUR(7500), IOUAmount{6708203932499368, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(6000), EUR(7500), IOUAmount{6708203932499368, -12}));
|
||||
amm.deposit(carol, USD(1000), EUR(1250));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(7000), EUR(8750), IOUAmount{7826237921249265, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(7000), EUR(8750), IOUAmount{7826237921249262, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(7000), EUR(8750), IOUAmount{7826237921249262, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{4472135954999580, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{4472135954999579, -12}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{2236067977499790, -12}));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{2236067977499789, -12}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
carol, IOUAmount{1118033988749895, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
carol, IOUAmount{1118033988749894, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(bob, IOUAmount{2236067977499789, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(carol, IOUAmount{1118033988749894, -12}));
|
||||
|
||||
env.require(balance(alice, gw["USD"](2000)));
|
||||
env.require(balance(alice, gw2["EUR"](1000)));
|
||||
@@ -1108,30 +960,16 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(4999999999999999), -12},
|
||||
STAmount{EUR, UINT64_C(6249999999999999), -12},
|
||||
IOUAmount{5590169943749475, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(5000000000000001), -12},
|
||||
STAmount{EUR, UINT64_C(6250000000000001), -12},
|
||||
IOUAmount{5590169943749473, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(5000000000000001), -12},
|
||||
STAmount{EUR, UINT64_C(6250000000000001), -12},
|
||||
IOUAmount{5590169943749473, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{4472135954999580, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(bob, IOUAmount(0)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
carol, IOUAmount{1118033988749895, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
carol, IOUAmount{1118033988749894, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(carol, IOUAmount{1118033988749894, -12}));
|
||||
|
||||
// Bob will get 2500 EUR back.
|
||||
env.require(balance(alice, gw["USD"](2000)));
|
||||
@@ -1140,14 +978,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
env.balance(bob, USD) ==
|
||||
STAmount(USD, UINT64_C(3000000000000000), -12));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
env.balance(bob, EUR) ==
|
||||
STAmount(EUR, UINT64_C(5000000000000001), -12));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(bob, EUR) ==
|
||||
STAmount(EUR, UINT64_C(4999999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(bob, EUR) ==
|
||||
STAmount(EUR, UINT64_C(4999999999999999), -12));
|
||||
env.require(balance(carol, gw["USD"](3000)));
|
||||
env.require(balance(carol, gw2["EUR"](2750)));
|
||||
|
||||
@@ -1155,23 +988,13 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
env(amm::ammClawback(gw2, carol, EUR, USD, std::nullopt),
|
||||
ter(tesSUCCESS));
|
||||
env.close();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(3999999999999999), -12},
|
||||
STAmount{EUR, UINT64_C(4999999999999999), -12},
|
||||
IOUAmount{4472135954999580, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(4000000000000001), -12},
|
||||
STAmount{EUR, UINT64_C(5000000000000002), -12},
|
||||
IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount{USD, UINT64_C(4000000000000001), -12},
|
||||
STAmount{EUR, UINT64_C(5000000000000002), -12},
|
||||
IOUAmount{4472135954999579, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{4472135954999580, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectLPTokens(
|
||||
alice, IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{4472135954999579, -12}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(bob, IOUAmount(0)));
|
||||
BEAST_EXPECT(amm.expectLPTokens(carol, IOUAmount(0)));
|
||||
|
||||
@@ -1210,26 +1033,14 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
|
||||
// gw creates AMM pool of XRP/USD, alice and bob deposit XRP/USD.
|
||||
AMM amm(env, gw, XRP(2000), USD(10000), ter(tesSUCCESS));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(10000), XRP(2000), IOUAmount{4472135954999580, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(10000), XRP(2000), IOUAmount{4472135954999579, -9}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(10000), XRP(2000), IOUAmount{4472135954999579, -9}));
|
||||
amm.deposit(alice, USD(1000), XRP(200));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(11000), XRP(2200), IOUAmount{4919349550499538, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(11000), XRP(2200), IOUAmount{4919349550499536, -9}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(11000), XRP(2200), IOUAmount{4919349550499536, -9}));
|
||||
amm.deposit(bob, USD(2000), XRP(400));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(13000), XRP(2600), IOUAmount{5813776741499453, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(13000), XRP(2600), IOUAmount{5813776741499451, -9}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(13000), XRP(2600), IOUAmount{5813776741499451, -9}));
|
||||
env.close();
|
||||
|
||||
auto aliceXrpBalance = env.balance(alice, XRP);
|
||||
@@ -1239,34 +1050,22 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
env(amm::ammClawback(gw, alice, USD, XRP, std::nullopt),
|
||||
ter(tesSUCCESS));
|
||||
env.close();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(12000), XRP(2400), IOUAmount{5366563145999495, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(12000),
|
||||
XRPAmount(2400000001),
|
||||
IOUAmount{5366563145999494, -9}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(200)));
|
||||
else
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(200) - XRPAmount{1}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(12000),
|
||||
XRPAmount(2400000001),
|
||||
IOUAmount{5366563145999494, -9}));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(200) - XRPAmount{1}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(alice, IOUAmount(0)));
|
||||
|
||||
// gw clawback all bob's USD in amm. (2000 USD / 400 XRP)
|
||||
env(amm::ammClawback(gw, bob, USD, XRP, std::nullopt),
|
||||
ter(tesSUCCESS));
|
||||
env.close();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(10000), XRP(2000), IOUAmount{4472135954999580, -9}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(10000),
|
||||
XRPAmount(2000000001),
|
||||
IOUAmount{4472135954999579, -9}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(10000),
|
||||
XRPAmount(2000000001),
|
||||
IOUAmount{4472135954999579, -9}));
|
||||
BEAST_EXPECT(
|
||||
expectLedgerEntryRoot(env, bob, bobXrpBalance + XRP(400)));
|
||||
BEAST_EXPECT(amm.expectLPTokens(alice, IOUAmount(0)));
|
||||
@@ -1322,10 +1121,7 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
amm.deposit(bob, USD(4000), EUR(1000));
|
||||
BEAST_EXPECT(
|
||||
amm.expectBalances(USD(12000), EUR(3000), IOUAmount(6000)));
|
||||
if (!features[fixAMMv1_3])
|
||||
amm.deposit(carol, USD(2000), EUR(500));
|
||||
else
|
||||
amm.deposit(carol, USD(2000.25), EUR(500));
|
||||
amm.deposit(carol, USD(2000.25), EUR(500));
|
||||
BEAST_EXPECT(
|
||||
amm.expectBalances(USD(14000), EUR(3500), IOUAmount(7000)));
|
||||
// gw clawback 1000 USD from carol.
|
||||
@@ -1341,12 +1137,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(8000));
|
||||
BEAST_EXPECT(env.balance(bob, USD) == USD(5000));
|
||||
BEAST_EXPECT(env.balance(bob, EUR) == EUR(8000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(env.balance(carol, USD) == USD(6000));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
// 250 EUR goes back to carol.
|
||||
BEAST_EXPECT(env.balance(carol, EUR) == EUR(7750));
|
||||
|
||||
@@ -1368,12 +1161,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(env.balance(bob, USD) == USD(5000));
|
||||
// 250 EUR did not go back to bob because tfClawTwoAssets is set.
|
||||
BEAST_EXPECT(env.balance(bob, EUR) == EUR(8000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(env.balance(carol, USD) == USD(6000));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(env.balance(carol, EUR) == EUR(7750));
|
||||
|
||||
// gw clawback all USD from alice and set tfClawTwoAssets.
|
||||
@@ -1390,12 +1180,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(8000));
|
||||
BEAST_EXPECT(env.balance(bob, USD) == USD(5000));
|
||||
BEAST_EXPECT(env.balance(bob, EUR) == EUR(8000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(env.balance(carol, USD) == USD(6000));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(env.balance(carol, EUR) == EUR(7750));
|
||||
}
|
||||
|
||||
@@ -1580,21 +1367,10 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
// gw2 claws back 1000 EUR from gw.
|
||||
env(amm::ammClawback(gw2, gw, EUR, USD, EUR(1000)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4500),
|
||||
STAmount(EUR, UINT64_C(9000000000000001), -12),
|
||||
IOUAmount{6363961030678928, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4500), EUR(9000), IOUAmount{6363961030678928, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(4500), EUR(9000), IOUAmount{6363961030678928, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(gw, IOUAmount{7071067811865480, -13}));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(gw, IOUAmount{7071067811865475, -13}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(gw, IOUAmount{7071067811865475, -13}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(gw2, IOUAmount{1414213562373095, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{4242640687119285, -12}));
|
||||
@@ -1607,21 +1383,10 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
// gw2 claws back 4000 EUR from alice.
|
||||
env(amm::ammClawback(gw2, alice, EUR, USD, EUR(4000)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500),
|
||||
STAmount(EUR, UINT64_C(5000000000000001), -12),
|
||||
IOUAmount{3535533905932738, -12}));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), EUR(5000), IOUAmount{3535533905932738, -12}));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
USD(2500), EUR(5000), IOUAmount{3535533905932738, -12}));
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(gw, IOUAmount{7071067811865480, -13}));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(gw, IOUAmount{7071067811865475, -13}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(gw, IOUAmount{7071067811865475, -13}));
|
||||
BEAST_EXPECT(amm.expectLPTokens(gw2, IOUAmount{1414213562373095, -12}));
|
||||
BEAST_EXPECT(
|
||||
amm.expectLPTokens(alice, IOUAmount{1414213562373095, -12}));
|
||||
@@ -1885,10 +1650,7 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
amm.deposit(bob, USD(4000), EUR(1000));
|
||||
BEAST_EXPECT(
|
||||
amm.expectBalances(USD(12000), EUR(3000), IOUAmount(6000)));
|
||||
if (!features[fixAMMv1_3])
|
||||
amm.deposit(carol, USD(2000), EUR(500));
|
||||
else
|
||||
amm.deposit(carol, USD(2000.25), EUR(500));
|
||||
amm.deposit(carol, USD(2000.25), EUR(500));
|
||||
BEAST_EXPECT(
|
||||
amm.expectBalances(USD(14000), EUR(3500), IOUAmount(7000)));
|
||||
|
||||
@@ -1910,12 +1672,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(8000));
|
||||
BEAST_EXPECT(env.balance(bob, USD) == USD(5000));
|
||||
BEAST_EXPECT(env.balance(bob, EUR) == EUR(8000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(env.balance(carol, USD) == USD(6000));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
// 250 EUR goes back to carol.
|
||||
BEAST_EXPECT(env.balance(carol, EUR) == EUR(7750));
|
||||
|
||||
@@ -1937,12 +1696,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(env.balance(bob, USD) == USD(5000));
|
||||
// 250 EUR did not go back to bob because tfClawTwoAssets is set.
|
||||
BEAST_EXPECT(env.balance(bob, EUR) == EUR(8000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(env.balance(carol, USD) == USD(6000));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(env.balance(carol, EUR) == EUR(7750));
|
||||
|
||||
// gw clawback all USD from alice and set tfClawTwoAssets.
|
||||
@@ -1960,12 +1716,9 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
BEAST_EXPECT(env.balance(alice, EUR) == EUR(8000));
|
||||
BEAST_EXPECT(env.balance(bob, USD) == USD(5000));
|
||||
BEAST_EXPECT(env.balance(bob, EUR) == EUR(8000));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(env.balance(carol, USD) == USD(6000));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(5999'999999999999), -12));
|
||||
BEAST_EXPECT(env.balance(carol, EUR) == EUR(7750));
|
||||
}
|
||||
}
|
||||
@@ -2013,23 +1766,13 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
env(amm::ammClawback(gw, alice, USD, XRP, USD(400)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount(USD, UINT64_C(5656854249492380), -13),
|
||||
XRP(70.710678),
|
||||
IOUAmount(200000)));
|
||||
else
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount(USD, UINT64_C(565'685424949238), -12),
|
||||
XRP(70.710679),
|
||||
IOUAmount(200000)));
|
||||
BEAST_EXPECT(amm.expectBalances(
|
||||
STAmount(USD, UINT64_C(565'685424949238), -12),
|
||||
XRP(70.710679),
|
||||
IOUAmount(200000)));
|
||||
BEAST_EXPECT(amm.expectLPTokens(alice, IOUAmount(0)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(29.289322)));
|
||||
else
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(29.289321)));
|
||||
BEAST_EXPECT(expectLedgerEntryRoot(
|
||||
env, alice, aliceXrpBalance + XRP(29.289321)));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2040,18 +1783,13 @@ class AMMClawback_test : public jtx::AMMTest
|
||||
testFeatureDisabled(all - featureAMMClawback);
|
||||
testAMMClawbackSpecificAmount(all);
|
||||
testAMMClawbackExceedBalance(all);
|
||||
testAMMClawbackExceedBalance(all - fixAMMv1_3);
|
||||
testAMMClawbackAll(all);
|
||||
testAMMClawbackAll(all - fixAMMv1_3);
|
||||
testAMMClawbackSameIssuerAssets(all);
|
||||
testAMMClawbackSameIssuerAssets(all - fixAMMv1_3);
|
||||
testAMMClawbackSameCurrency(all);
|
||||
testAMMClawbackIssuesEachOther(all);
|
||||
testNotHoldingLptoken(all);
|
||||
testAssetFrozen(all);
|
||||
testAssetFrozen(all - fixAMMv1_3);
|
||||
testSingleDepositAndClawback(all);
|
||||
testSingleDepositAndClawback(all - fixAMMv1_3);
|
||||
}
|
||||
};
|
||||
BEAST_DEFINE_TESTSUITE(AMMClawback, app, ripple);
|
||||
|
||||
@@ -1405,7 +1405,6 @@ private:
|
||||
using namespace jtx;
|
||||
FeatureBitset const all{supported_amendments()};
|
||||
testRmFundedOffer(all);
|
||||
testRmFundedOffer(all - fixAMMv1_3);
|
||||
testEnforceNoRipple(all);
|
||||
testFillModes(all);
|
||||
testOfferCrossWithXRP(all);
|
||||
@@ -1419,7 +1418,6 @@ private:
|
||||
testOfferCreateThenCross(all);
|
||||
testSellFlagExceedLimit(all);
|
||||
testGatewayCrossCurrency(all);
|
||||
testGatewayCrossCurrency(all - fixAMMv1_3);
|
||||
testBridgedCross(all);
|
||||
testSellWithFillOrKill(all);
|
||||
testTransferRateOffer(all);
|
||||
@@ -1427,7 +1425,6 @@ private:
|
||||
testBadPathAssert(all);
|
||||
testSellFlagBasic(all);
|
||||
testDirectToDirectPath(all);
|
||||
testDirectToDirectPath(all - fixAMMv1_3);
|
||||
testRequireAuth(all);
|
||||
testMissingAuth(all);
|
||||
}
|
||||
@@ -3838,9 +3835,7 @@ private:
|
||||
testBookStep(all);
|
||||
testBookStep(all | ownerPaysFee);
|
||||
testTransferRate(all | ownerPaysFee);
|
||||
testTransferRate((all - fixAMMv1_3) | ownerPaysFee);
|
||||
testTransferRateNoOwnerFee(all);
|
||||
testTransferRateNoOwnerFee(all - fixAMMv1_3);
|
||||
testLimitQuality();
|
||||
testXRPPathLoop();
|
||||
}
|
||||
@@ -3851,7 +3846,6 @@ private:
|
||||
using namespace jtx;
|
||||
FeatureBitset const all{supported_amendments()};
|
||||
testStepLimit(all);
|
||||
testStepLimit(all - fixAMMv1_3);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3860,7 +3854,6 @@ private:
|
||||
using namespace jtx;
|
||||
FeatureBitset const all{supported_amendments()};
|
||||
test_convert_all_of_an_asset(all);
|
||||
test_convert_all_of_an_asset(all - fixAMMv1_3);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -833,10 +833,7 @@ private:
|
||||
// Tiny deposit
|
||||
testAMM(
|
||||
[&](AMM& ammAlice, Env& env) {
|
||||
auto const enabledv1_3 =
|
||||
env.current()->rules().enabled(fixAMMv1_3);
|
||||
auto const err =
|
||||
!enabledv1_3 ? ter(temBAD_AMOUNT) : ter(tesSUCCESS);
|
||||
auto const err = ter(tesSUCCESS);
|
||||
// Pre-amendment XRP deposit side is rounded to 0
|
||||
// and deposit fails.
|
||||
// Post-amendment XRP deposit side is rounded to 1
|
||||
@@ -856,7 +853,7 @@ private:
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{features, features - fixAMMv1_3});
|
||||
{features});
|
||||
|
||||
// Invalid AMM
|
||||
testAMM([&](AMM& ammAlice, Env& env) {
|
||||
@@ -1322,15 +1319,6 @@ private:
|
||||
});
|
||||
|
||||
// Equal deposit limit, tokens rounded to 0
|
||||
testAMM(
|
||||
[&](AMM& amm, Env& env) {
|
||||
amm.deposit(DepositArg{
|
||||
.asset1In = STAmount{USD, 1, -15},
|
||||
.asset2In = XRPAmount{1},
|
||||
.err = ter(tecAMM_INVALID_TOKENS)});
|
||||
},
|
||||
{.pool = {{USD(1'000'000), XRP(1'000'000)}},
|
||||
.features = {features - fixAMMv1_3}});
|
||||
testAMM([&](AMM& amm, Env& env) {
|
||||
amm.deposit(DepositArg{
|
||||
.asset1In = STAmount{USD, 1, -15},
|
||||
@@ -1573,7 +1561,7 @@ private:
|
||||
});
|
||||
|
||||
// Issuer create/deposit
|
||||
for (auto const& feat : {all, all - fixAMMv1_3})
|
||||
for (auto const& feat : {all})
|
||||
{
|
||||
Env env(*this, feat);
|
||||
env.fund(XRP(30000), gw);
|
||||
@@ -2003,22 +1991,20 @@ private:
|
||||
// while leaving a tiny amount in USD pool.
|
||||
// Post-amendment:
|
||||
// Most of the pool is withdrawn with remaining tiny amounts
|
||||
auto err = env.enabled(fixAMMv1_3) ? ter(tesSUCCESS)
|
||||
: ter(tecAMM_BALANCE);
|
||||
auto err = ter(tesSUCCESS);
|
||||
ammAlice.withdraw(
|
||||
alice,
|
||||
IOUAmount{9'999'999'9999, -4},
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
err);
|
||||
if (env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(1), STAmount{USD, 1, -7}, IOUAmount{1, -4}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(1), STAmount{USD, 1, -7}, IOUAmount{1, -4}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
|
||||
testAMM(
|
||||
[&](AMM& ammAlice, Env& env) {
|
||||
@@ -2028,22 +2014,20 @@ private:
|
||||
// Equal withdraw but due to XRP precision limit,
|
||||
// this results in full withdraw of XRP pool only,
|
||||
// while leaving a tiny amount in USD pool.
|
||||
auto err = env.enabled(fixAMMv1_3) ? ter(tesSUCCESS)
|
||||
: ter(tecAMM_BALANCE);
|
||||
auto err = ter(tesSUCCESS);
|
||||
ammAlice.withdraw(
|
||||
alice,
|
||||
IOUAmount{9'999'999'999999999, -9},
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
err);
|
||||
if (env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(1), STAmount{USD, 1, -11}, IOUAmount{1, -8}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(1), STAmount{USD, 1, -11}, IOUAmount{1, -8}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
|
||||
// Invalid AMM
|
||||
testAMM([&](AMM& ammAlice, Env& env) {
|
||||
@@ -2111,16 +2095,14 @@ private:
|
||||
testAMM(
|
||||
[&](AMM& ammAlice, Env& env) {
|
||||
ammAlice.deposit(carol, 1'000'000);
|
||||
auto const err = env.enabled(fixAMMv1_3)
|
||||
? ter(tecAMM_INVALID_TOKENS)
|
||||
: ter(tecAMM_FAILED);
|
||||
auto const err = ter(tecAMM_INVALID_TOKENS);
|
||||
ammAlice.withdraw(
|
||||
carol, USD(100), std::nullopt, IOUAmount{500, 0}, err);
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
|
||||
// Withdraw with EPrice limit. Fails to withdraw, calculated tokens
|
||||
// to withdraw are greater than the LP shares.
|
||||
@@ -2187,9 +2169,7 @@ private:
|
||||
// are rounded to all LP tokens.
|
||||
testAMM(
|
||||
[&](AMM& ammAlice, Env& env) {
|
||||
auto const err = env.enabled(fixAMMv1_3)
|
||||
? ter(tecINVARIANT_FAILED)
|
||||
: ter(tecAMM_BALANCE);
|
||||
auto const err = ter(tecINVARIANT_FAILED);
|
||||
ammAlice.withdraw(
|
||||
alice,
|
||||
STAmount{USD, UINT64_C(9'999'999999999999), -12},
|
||||
@@ -2197,7 +2177,7 @@ private:
|
||||
std::nullopt,
|
||||
err);
|
||||
},
|
||||
{.features = {all, all - fixAMMv1_3}, .noLog = true});
|
||||
{.features = {all}, .noLog = true});
|
||||
|
||||
// Tiny withdraw
|
||||
testAMM([&](AMM& ammAlice, Env&) {
|
||||
@@ -2305,21 +2285,15 @@ private:
|
||||
testAMM(
|
||||
[&](AMM& ammAlice, Env& env) {
|
||||
ammAlice.withdraw(alice, XRP(1'000));
|
||||
if (!env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(9'000),
|
||||
USD(10'000),
|
||||
IOUAmount{9'486'832'98050514, -8}));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{9'000'000'001},
|
||||
USD(10'000),
|
||||
IOUAmount{9'486'832'98050514, -8}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{9'000'000'001},
|
||||
USD(10'000),
|
||||
IOUAmount{9'486'832'98050514, -8}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
|
||||
// Single withdrawal by tokens 10000.
|
||||
testAMM([&](AMM& ammAlice, Env&) {
|
||||
@@ -2381,20 +2355,14 @@ private:
|
||||
ammAlice.withdraw(carol, lpTokens, USD(0));
|
||||
lpTokens = ammAlice.deposit(carol, XRPAmount(1));
|
||||
ammAlice.withdraw(carol, lpTokens, XRPAmount(0));
|
||||
if (!env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000), USD(10'000), ammAlice.tokens()));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(10'000'000'001),
|
||||
USD(10'000),
|
||||
ammAlice.tokens()));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(10'000'000'001), USD(10'000), ammAlice.tokens()));
|
||||
BEAST_EXPECT(ammAlice.expectLPTokens(carol, IOUAmount{0}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
|
||||
// Single deposit by different accounts and then withdraw
|
||||
// in reverse.
|
||||
@@ -2445,20 +2413,14 @@ private:
|
||||
carol, USD(100), std::nullopt, IOUAmount{520, 0});
|
||||
BEAST_EXPECT(ammAlice.expectLPTokens(
|
||||
carol, IOUAmount{153'846'15384616, -8}));
|
||||
if (!env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(11'000'000'000),
|
||||
STAmount{USD, UINT64_C(9'372'781065088769), -12},
|
||||
IOUAmount{10'153'846'15384616, -8}));
|
||||
else if (env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(11'000'000'000),
|
||||
STAmount{USD, UINT64_C(9'372'78106508877), -11},
|
||||
IOUAmount{10'153'846'15384616, -8}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(11'000'000'000),
|
||||
STAmount{USD, UINT64_C(9'372'78106508877), -11},
|
||||
IOUAmount{10'153'846'15384616, -8}));
|
||||
ammAlice.withdrawAll(carol);
|
||||
BEAST_EXPECT(ammAlice.expectLPTokens(carol, IOUAmount{0}));
|
||||
},
|
||||
{.features = {all, all - fixAMMv1_3}, .noLog = true});
|
||||
{.features = {all}, .noLog = true});
|
||||
|
||||
// Withdraw with EPrice limit. AssetOut is 0.
|
||||
testAMM(
|
||||
@@ -2468,21 +2430,15 @@ private:
|
||||
carol, USD(0), std::nullopt, IOUAmount{520, 0});
|
||||
BEAST_EXPECT(ammAlice.expectLPTokens(
|
||||
carol, IOUAmount{153'846'15384616, -8}));
|
||||
if (!env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(11'000),
|
||||
STAmount{USD, UINT64_C(9'372'781065088769), -12},
|
||||
IOUAmount{10'153'846'15384616, -8}));
|
||||
else if (env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(11'000),
|
||||
STAmount{USD, UINT64_C(9'372'78106508877), -11},
|
||||
IOUAmount{10'153'846'15384616, -8}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(11'000),
|
||||
STAmount{USD, UINT64_C(9'372'78106508877), -11},
|
||||
IOUAmount{10'153'846'15384616, -8}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
|
||||
// IOU to IOU + transfer fee
|
||||
{
|
||||
@@ -2525,21 +2481,13 @@ private:
|
||||
[&](AMM& ammAlice, Env& env) {
|
||||
// Single XRP pool
|
||||
ammAlice.withdraw(alice, std::nullopt, XRPAmount{1});
|
||||
if (!env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{9'999'999'999},
|
||||
USD(10'000),
|
||||
IOUAmount{9'999'999'9995, -4}));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000),
|
||||
USD(10'000),
|
||||
IOUAmount{9'999'999'9995, -4}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000), USD(10'000), IOUAmount{9'999'999'9995, -4}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
std::nullopt,
|
||||
{all, all - fixAMMv1_3});
|
||||
{all});
|
||||
testAMM([&](AMM& ammAlice, Env&) {
|
||||
// Single USD pool
|
||||
ammAlice.withdraw(alice, std::nullopt, STAmount{USD, 1, -10});
|
||||
@@ -2679,8 +2627,7 @@ private:
|
||||
// in order to ensure AMM invariant sqrt(asset1 * asset2) >= tokens
|
||||
// fund just one USD higher in this case, which is enough for
|
||||
// deposit to succeed
|
||||
if (env.enabled(fixAMMv1_3))
|
||||
++fundUSD;
|
||||
++fundUSD;
|
||||
fund(env, gw, {a}, {USD(fundUSD)}, Fund::Acct);
|
||||
ammAlice.deposit(a, tokens);
|
||||
ammAlice.vote(a, 50 * (i + 1));
|
||||
@@ -3092,14 +3039,10 @@ private:
|
||||
|
||||
fund(env, gw, {bob}, {USD(10'000)}, Fund::Acct);
|
||||
ammAlice.deposit(bob, 1'000'000);
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(12'000), USD(12'000), IOUAmount{12'000'000, 0}));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{12'000'000'001},
|
||||
USD(12'000),
|
||||
IOUAmount{12'000'000, 0}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{12'000'000'001},
|
||||
USD(12'000),
|
||||
IOUAmount{12'000'000, 0}));
|
||||
|
||||
// Initial state. Pay bidMin.
|
||||
env(ammAlice.bid({.account = carol, .bidMin = 110})).close();
|
||||
@@ -3131,16 +3074,10 @@ private:
|
||||
BEAST_EXPECT(ammAlice.expectAuctionSlot(
|
||||
0, std::nullopt, IOUAmount{110}));
|
||||
// ~321.09 tokens burnt on bidding fees.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(12'000),
|
||||
USD(12'000),
|
||||
IOUAmount{11'999'678'91, -2}));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{12'000'000'001},
|
||||
USD(12'000),
|
||||
IOUAmount{11'999'678'91, -2}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{12'000'000'001},
|
||||
USD(12'000),
|
||||
IOUAmount{11'999'678'91, -2}));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
@@ -3169,12 +3106,8 @@ private:
|
||||
auto const slotPrice = IOUAmount{5'200};
|
||||
ammTokens -= slotPrice;
|
||||
BEAST_EXPECT(ammAlice.expectAuctionSlot(100, 0, slotPrice));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(13'000), USD(13'000), ammTokens));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003}, USD(13'000), ammTokens));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003}, USD(13'000), ammTokens));
|
||||
// Discounted trade
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
@@ -3196,16 +3129,10 @@ private:
|
||||
env.balance(ed, USD) ==
|
||||
STAmount(USD, UINT64_C(18'999'0057261184), -10));
|
||||
// USD pool is slightly higher because of the fees.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(13'000),
|
||||
STAmount(USD, UINT64_C(13'002'98282151422), -11),
|
||||
ammTokens));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003},
|
||||
STAmount(USD, UINT64_C(13'002'98282151422), -11),
|
||||
ammTokens));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003},
|
||||
STAmount(USD, UINT64_C(13'002'98282151422), -11),
|
||||
ammTokens));
|
||||
ammTokens = ammAlice.getLPTokensBalance();
|
||||
// Trade with the fee
|
||||
for (int i = 0; i < 10; ++i)
|
||||
@@ -3217,80 +3144,44 @@ private:
|
||||
// carol, bob, ed. the discounted fee is 10 times less
|
||||
// than the trading fee.
|
||||
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
env.balance(dan, USD) ==
|
||||
STAmount(USD, UINT64_C(19'490'05672274399), -11));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(dan, USD) ==
|
||||
STAmount(USD, UINT64_C(19'490'05672274398), -11));
|
||||
BEAST_EXPECT(
|
||||
env.balance(dan, USD) ==
|
||||
STAmount(USD, UINT64_C(19'490'05672274398), -11));
|
||||
// USD pool gains more in dan's fees.
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(13'000),
|
||||
STAmount{USD, UINT64_C(13'012'92609877023), -11},
|
||||
ammTokens));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003},
|
||||
STAmount{USD, UINT64_C(13'012'92609877024), -11},
|
||||
ammTokens));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003},
|
||||
STAmount{USD, UINT64_C(13'012'92609877024), -11},
|
||||
ammTokens));
|
||||
// Discounted fee payment
|
||||
ammAlice.deposit(carol, USD(100));
|
||||
ammTokens = ammAlice.getLPTokensBalance();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(13'000),
|
||||
STAmount{USD, UINT64_C(13'112'92609877023), -11},
|
||||
ammTokens));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003},
|
||||
STAmount{USD, UINT64_C(13'112'92609877024), -11},
|
||||
ammTokens));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'003},
|
||||
STAmount{USD, UINT64_C(13'112'92609877024), -11},
|
||||
ammTokens));
|
||||
env(pay(carol, bob, USD(100)), path(~USD), sendmax(XRP(110)));
|
||||
env.close();
|
||||
// carol pays 100000 drops in fees
|
||||
// 99900668XRP swapped in for 100USD
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'100'000'668},
|
||||
STAmount{USD, UINT64_C(13'012'92609877023), -11},
|
||||
ammTokens));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'100'000'671},
|
||||
STAmount{USD, UINT64_C(13'012'92609877024), -11},
|
||||
ammTokens));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'100'000'671},
|
||||
STAmount{USD, UINT64_C(13'012'92609877024), -11},
|
||||
ammTokens));
|
||||
// Payment with the trading fee
|
||||
env(pay(alice, carol, XRP(100)), path(~XRP), sendmax(USD(110)));
|
||||
env.close();
|
||||
// alice pays ~1.011USD in fees, which is ~10 times more
|
||||
// than carol's fee
|
||||
// 100.099431529USD swapped in for 100XRP
|
||||
if (!features[fixAMMv1_3])
|
||||
{
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'668},
|
||||
STAmount{USD, UINT64_C(13'114'03663047269), -11},
|
||||
ammTokens));
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'671},
|
||||
STAmount{USD, UINT64_C(13'114'03663044937), -11},
|
||||
ammTokens));
|
||||
}
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'671},
|
||||
STAmount{USD, UINT64_C(13'114'03663044937), -11},
|
||||
ammTokens));
|
||||
|
||||
// Auction slot expired, no discounted fee
|
||||
env.close(seconds(TOTAL_TIME_SLOT_SECS + 1));
|
||||
// clock is parent's based
|
||||
env.close();
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(29'399'00572620544), -11));
|
||||
ammTokens = ammAlice.getLPTokensBalance();
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
@@ -3299,45 +3190,23 @@ private:
|
||||
}
|
||||
// carol pays ~9.94USD in fees, which is ~10 times more in
|
||||
// trading fees vs discounted fee.
|
||||
if (!features[fixAMMv1_3])
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(29'389'06197177124), -11));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'668},
|
||||
STAmount{USD, UINT64_C(13'123'98038490689), -11},
|
||||
ammTokens));
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(29'389'06197177129), -11));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'671},
|
||||
STAmount{USD, UINT64_C(13'123'98038488352), -11},
|
||||
ammTokens));
|
||||
}
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(29'389'06197177129), -11));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount{13'000'000'671},
|
||||
STAmount{USD, UINT64_C(13'123'98038488352), -11},
|
||||
ammTokens));
|
||||
|
||||
env(pay(carol, bob, USD(100)), path(~USD), sendmax(XRP(110)));
|
||||
env.close();
|
||||
// carol pays ~1.008XRP in trading fee, which is
|
||||
// ~10 times more than the discounted fee.
|
||||
// 99.815876XRP is swapped in for 100USD
|
||||
if (!features[fixAMMv1_3])
|
||||
{
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(13'100'824'790),
|
||||
STAmount{USD, UINT64_C(13'023'98038490689), -11},
|
||||
ammTokens));
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(13'100'824'793),
|
||||
STAmount{USD, UINT64_C(13'023'98038488352), -11},
|
||||
ammTokens));
|
||||
}
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(13'100'824'793),
|
||||
STAmount{USD, UINT64_C(13'023'98038488352), -11},
|
||||
ammTokens));
|
||||
},
|
||||
std::nullopt,
|
||||
1'000,
|
||||
@@ -4819,10 +4688,7 @@ private:
|
||||
carol, USD(100), std::nullopt, IOUAmount{520, 0});
|
||||
// carol withdraws ~1,443.44USD
|
||||
auto const balanceAfterWithdraw = [&]() {
|
||||
if (!features[fixAMMv1_3])
|
||||
return STAmount(USD, UINT64_C(30'443'43891402714), -11);
|
||||
else
|
||||
return STAmount(USD, UINT64_C(30'443'43891402713), -11);
|
||||
return STAmount(USD, UINT64_C(30'443'43891402713), -11);
|
||||
}();
|
||||
BEAST_EXPECT(env.balance(carol, USD) == balanceAfterWithdraw);
|
||||
// Set to original pool size
|
||||
@@ -4832,22 +4698,12 @@ private:
|
||||
ammAlice.vote(alice, 0);
|
||||
BEAST_EXPECT(ammAlice.expectTradingFee(0));
|
||||
auto const tokensNoFee = ammAlice.withdraw(carol, deposit);
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(30'443'43891402716), -11));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(30'443'43891402713), -11));
|
||||
BEAST_EXPECT(
|
||||
env.balance(carol, USD) ==
|
||||
STAmount(USD, UINT64_C(30'443'43891402713), -11));
|
||||
// carol pays ~4008 LPTokens in fees or ~0.5% of the no-fee
|
||||
// LPTokens
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(
|
||||
tokensNoFee == IOUAmount(746'579'80779912, -8));
|
||||
else
|
||||
BEAST_EXPECT(
|
||||
tokensNoFee == IOUAmount(746'579'80779911, -8));
|
||||
BEAST_EXPECT(tokensNoFee == IOUAmount(746'579'80779911, -8));
|
||||
BEAST_EXPECT(tokensFee == IOUAmount(750'588'23529411, -8));
|
||||
},
|
||||
std::nullopt,
|
||||
@@ -5109,40 +4965,24 @@ private:
|
||||
// Due to round off some accounts have a tiny gain, while
|
||||
// other have a tiny loss. The last account to withdraw
|
||||
// gets everything in the pool.
|
||||
if (features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000),
|
||||
STAmount{USD, UINT64_C(10'000'0000000003), -10},
|
||||
IOUAmount{10'000'000}));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000), USD(10'000), IOUAmount{10'000'000}));
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000),
|
||||
STAmount{USD, UINT64_C(10'000'0000000003), -10},
|
||||
IOUAmount{10'000'000}));
|
||||
BEAST_EXPECT(expectLine(env, ben, USD(1'500'000)));
|
||||
BEAST_EXPECT(expectLine(env, simon, USD(1'500'000)));
|
||||
BEAST_EXPECT(expectLine(env, chris, USD(1'500'000)));
|
||||
BEAST_EXPECT(expectLine(env, dan, USD(1'500'000)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLine(env, carol, USD(30'000)));
|
||||
else
|
||||
BEAST_EXPECT(expectLine(env, carol, USD(30'000)));
|
||||
BEAST_EXPECT(expectLine(env, carol, USD(30'000)));
|
||||
BEAST_EXPECT(expectLine(env, ed, USD(1'500'000)));
|
||||
BEAST_EXPECT(expectLine(env, paul, USD(1'500'000)));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLine(
|
||||
env,
|
||||
nataly,
|
||||
STAmount{USD, UINT64_C(1'500'000'000000005), -9}));
|
||||
else
|
||||
BEAST_EXPECT(expectLine(env, nataly, USD(1'500'000)));
|
||||
BEAST_EXPECT(expectLine(env, nataly, USD(1'500'000)));
|
||||
ammAlice.withdrawAll(alice);
|
||||
BEAST_EXPECT(!ammAlice.ammExists());
|
||||
if (features[fixAMMv1_3])
|
||||
BEAST_EXPECT(expectLine(
|
||||
env,
|
||||
alice,
|
||||
STAmount{USD, UINT64_C(30'000'0000000003), -10}));
|
||||
else
|
||||
BEAST_EXPECT(expectLine(env, alice, USD(30'000)));
|
||||
BEAST_EXPECT(expectLine(
|
||||
env,
|
||||
alice,
|
||||
STAmount{USD, UINT64_C(30'000'0000000003), -10}));
|
||||
// alice XRP balance is 30,000initial - 50 ammcreate fee -
|
||||
// 10drops fee
|
||||
BEAST_EXPECT(accountBalance(env, alice) == "29949999990");
|
||||
@@ -5192,66 +5032,36 @@ private:
|
||||
ammAlice.withdrawAll(nataly, XRP(0));
|
||||
}
|
||||
auto const baseFee = env.current()->fees().base.drops();
|
||||
if (!features[fixAMMv1_3])
|
||||
{
|
||||
// No round off with XRP in this test
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRP(10'000), USD(10'000), IOUAmount{10'000'000}));
|
||||
ammAlice.withdrawAll(alice);
|
||||
BEAST_EXPECT(!ammAlice.ammExists());
|
||||
// 20,000 initial - (deposit+withdraw) * 10
|
||||
auto const xrpBalance =
|
||||
(XRP(2'000'000) - txfee(env, 20)).getText();
|
||||
BEAST_EXPECT(accountBalance(env, ben) == xrpBalance);
|
||||
BEAST_EXPECT(accountBalance(env, simon) == xrpBalance);
|
||||
BEAST_EXPECT(accountBalance(env, chris) == xrpBalance);
|
||||
BEAST_EXPECT(accountBalance(env, dan) == xrpBalance);
|
||||
|
||||
// 30,000 initial - (deposit+withdraw) * 10
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, carol) ==
|
||||
std::to_string(30'000'000'000 - 20 * baseFee));
|
||||
BEAST_EXPECT(accountBalance(env, ed) == xrpBalance);
|
||||
BEAST_EXPECT(accountBalance(env, paul) == xrpBalance);
|
||||
BEAST_EXPECT(accountBalance(env, nataly) == xrpBalance);
|
||||
// 30,000 initial - 50 ammcreate fee - 10drops withdraw fee
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, alice) ==
|
||||
std::to_string(29'950'000'000 - baseFee));
|
||||
}
|
||||
else
|
||||
{
|
||||
// post-amendment the rounding takes place to ensure
|
||||
// AMM invariant
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(10'000'000'080),
|
||||
USD(10'000),
|
||||
IOUAmount{10'000'000}));
|
||||
ammAlice.withdrawAll(alice);
|
||||
BEAST_EXPECT(!ammAlice.ammExists());
|
||||
auto const xrpBalance =
|
||||
XRP(2'000'000) - txfee(env, 20) - drops(10);
|
||||
auto const xrpBalanceText = xrpBalance.getText();
|
||||
BEAST_EXPECT(accountBalance(env, ben) == xrpBalanceText);
|
||||
BEAST_EXPECT(accountBalance(env, simon) == xrpBalanceText);
|
||||
BEAST_EXPECT(accountBalance(env, chris) == xrpBalanceText);
|
||||
BEAST_EXPECT(accountBalance(env, dan) == xrpBalanceText);
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, carol) ==
|
||||
std::to_string(30'000'000'000 - 20 * baseFee - 10));
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, ed) ==
|
||||
(xrpBalance + drops(2)).getText());
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, paul) ==
|
||||
(xrpBalance + drops(3)).getText());
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, nataly) ==
|
||||
(xrpBalance + drops(5)).getText());
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, alice) ==
|
||||
std::to_string(29'950'000'000 - baseFee + 80));
|
||||
}
|
||||
// post-amendment the rounding takes place to ensure
|
||||
// AMM invariant
|
||||
BEAST_EXPECT(ammAlice.expectBalances(
|
||||
XRPAmount(10'000'000'080),
|
||||
USD(10'000),
|
||||
IOUAmount{10'000'000}));
|
||||
ammAlice.withdrawAll(alice);
|
||||
BEAST_EXPECT(!ammAlice.ammExists());
|
||||
auto const xrpBalance =
|
||||
XRP(2'000'000) - txfee(env, 20) - drops(10);
|
||||
auto const xrpBalanceText = xrpBalance.getText();
|
||||
BEAST_EXPECT(accountBalance(env, ben) == xrpBalanceText);
|
||||
BEAST_EXPECT(accountBalance(env, simon) == xrpBalanceText);
|
||||
BEAST_EXPECT(accountBalance(env, chris) == xrpBalanceText);
|
||||
BEAST_EXPECT(accountBalance(env, dan) == xrpBalanceText);
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, carol) ==
|
||||
std::to_string(30'000'000'000 - 20 * baseFee - 10));
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, ed) ==
|
||||
(xrpBalance + drops(2)).getText());
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, paul) ==
|
||||
(xrpBalance + drops(3)).getText());
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, nataly) ==
|
||||
(xrpBalance + drops(5)).getText());
|
||||
BEAST_EXPECT(
|
||||
accountBalance(env, alice) ==
|
||||
std::to_string(29'950'000'000 - baseFee + 80));
|
||||
},
|
||||
std::nullopt,
|
||||
0,
|
||||
@@ -6374,7 +6184,7 @@ private:
|
||||
})
|
||||
{
|
||||
testcase(input.testCase);
|
||||
for (auto const& features : {all - fixAMMv1_3, all})
|
||||
for (auto const& features : {all})
|
||||
{
|
||||
// Env env(*this, features,
|
||||
// std::make_unique<CaptureLogs>(&logs));
|
||||
@@ -6432,8 +6242,7 @@ private:
|
||||
auto const goodUsdGH = input.goodUsdGHr;
|
||||
auto const goodUsdBIT = input.goodUsdBITr;
|
||||
|
||||
auto const lpTokenBalance =
|
||||
env.enabled(fixAMMv1_3) && input.lpTokenBalanceAlt
|
||||
auto const lpTokenBalance = input.lpTokenBalanceAlt
|
||||
? *input.lpTokenBalanceAlt
|
||||
: input.lpTokenBalance;
|
||||
|
||||
@@ -6973,8 +6782,7 @@ private:
|
||||
};
|
||||
test(
|
||||
[&](AMM& amm, Env& env) {
|
||||
auto const err = env.enabled(fixAMMv1_3) ? ter(tesSUCCESS)
|
||||
: ter(tecUNFUNDED_AMM);
|
||||
auto const err = ter(tesSUCCESS);
|
||||
amm.deposit(DepositArg{
|
||||
.account = alice, .asset1In = amount, .err = err});
|
||||
},
|
||||
@@ -6986,10 +6794,7 @@ private:
|
||||
amm.withdraw(WithdrawArg{.asset1Out = STAmount{XPM, 1, -5}});
|
||||
auto const [amount_, amount2_, lptAMM_] =
|
||||
amm.balances(XRP, XPM);
|
||||
if (!env.enabled(fixAMMv1_3))
|
||||
BEAST_EXPECT((amount2 - amount2_) > withdraw);
|
||||
else
|
||||
BEAST_EXPECT((amount2 - amount2_) <= withdraw);
|
||||
BEAST_EXPECT((amount2 - amount2_) <= withdraw);
|
||||
},
|
||||
0);
|
||||
}
|
||||
@@ -7003,8 +6808,7 @@ private:
|
||||
{
|
||||
auto const [amount, amount2, lptBalance] = amm.balances(GBP, EUR);
|
||||
|
||||
NumberRoundModeGuard g(
|
||||
env.enabled(fixAMMv1_3) ? Number::upward : Number::getround());
|
||||
NumberRoundModeGuard g(Number::upward);
|
||||
auto const res = root2(amount * amount2);
|
||||
|
||||
if (shouldFail)
|
||||
@@ -7046,7 +6850,7 @@ private:
|
||||
env,
|
||||
"dep1",
|
||||
deposit == STAmount{EUR, 1, -3} &&
|
||||
!env.enabled(fixAMMv1_3));
|
||||
!true /*env.enabled(fixAMMv1_3)*/);
|
||||
},
|
||||
{{GBP(30'000), EUR(30'000)}},
|
||||
0,
|
||||
@@ -7107,7 +6911,7 @@ private:
|
||||
ammAlice,
|
||||
env,
|
||||
"dep3",
|
||||
exponent != -3 && !env.enabled(fixAMMv1_3));
|
||||
exponent != -3 && !true /*env.enabled(fixAMMv1_3)*/);
|
||||
},
|
||||
{{GBP(10'000), EUR(30'000)}},
|
||||
0,
|
||||
@@ -7329,51 +7133,35 @@ private:
|
||||
testFeeVote();
|
||||
testInvalidBid();
|
||||
testBid(all);
|
||||
testBid(all - fixAMMv1_3);
|
||||
testInvalidAMMPayment();
|
||||
testBasicPaymentEngine(all);
|
||||
testBasicPaymentEngine(all - fixAMMv1_3);
|
||||
testBasicPaymentEngine(all - fixReducedOffersV2);
|
||||
testBasicPaymentEngine(all - fixAMMv1_3 - fixReducedOffersV2);
|
||||
testAMMTokens();
|
||||
testAmendment();
|
||||
testFlags();
|
||||
testRippling();
|
||||
testAMMAndCLOB(all);
|
||||
testAMMAndCLOB(all - fixAMMv1_3);
|
||||
testTradingFee(all);
|
||||
testTradingFee(all - fixAMMv1_3);
|
||||
testAdjustedTokens(all);
|
||||
testAdjustedTokens(all - fixAMMv1_3);
|
||||
testAutoDelete();
|
||||
testClawback();
|
||||
testAMMID();
|
||||
testSelection(all);
|
||||
testSelection(all - fixAMMv1_3);
|
||||
testFixDefaultInnerObj();
|
||||
testMalformed();
|
||||
testFixOverflowOffer(all);
|
||||
testFixOverflowOffer(all - fixAMMv1_3);
|
||||
testSwapRounding();
|
||||
testFixChangeSpotPriceQuality(all);
|
||||
testFixChangeSpotPriceQuality(all - fixAMMv1_3);
|
||||
testFixAMMOfferBlockedByLOB(all);
|
||||
testFixAMMOfferBlockedByLOB(all - fixAMMv1_3);
|
||||
testLPTokenBalance(all);
|
||||
testLPTokenBalance(all - fixAMMv1_3);
|
||||
testAMMClawback(all);
|
||||
testAMMClawback(all - featureAMMClawback);
|
||||
testAMMClawback(all - fixAMMv1_3 - featureAMMClawback);
|
||||
testAMMDepositWithFrozenAssets(all);
|
||||
testAMMDepositWithFrozenAssets(all - featureAMMClawback);
|
||||
testAMMDepositWithFrozenAssets(all - fixAMMv1_3 - featureAMMClawback);
|
||||
testFixReserveCheckOnWithdrawal(all);
|
||||
testDepositAndWithdrawRounding(all);
|
||||
testDepositAndWithdrawRounding(all - fixAMMv1_3);
|
||||
testDepositRounding(all);
|
||||
testDepositRounding(all - fixAMMv1_3);
|
||||
testWithdrawRounding(all);
|
||||
testWithdrawRounding(all - fixAMMv1_3);
|
||||
// testFailedPseudoAccount();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,12 +42,6 @@ number(STAmount const& a)
|
||||
IOUAmount
|
||||
AMM::initialTokens()
|
||||
{
|
||||
if (!env_.enabled(fixAMMv1_3))
|
||||
{
|
||||
auto const product = number(asset1_) * number(asset2_);
|
||||
return (IOUAmount)(product.mantissa() >= 0 ? root2(product)
|
||||
: root2(-product));
|
||||
}
|
||||
return getLPTokensBalance();
|
||||
}
|
||||
|
||||
|
||||
@@ -218,10 +218,7 @@ public:
|
||||
{
|
||||
Account a(std::to_string(i));
|
||||
votes.insert({a.human(), 50 * (i + 1)});
|
||||
if (!features[fixAMMv1_3])
|
||||
fund(env, gw, {a}, {USD(10000)}, Fund::Acct);
|
||||
else
|
||||
fund(env, gw, {a}, {USD(10001)}, Fund::Acct);
|
||||
fund(env, gw, {a}, {USD(10001)}, Fund::Acct);
|
||||
ammAlice.deposit(a, 10000000);
|
||||
ammAlice.vote(a, 50 * (i + 1));
|
||||
}
|
||||
@@ -231,22 +228,13 @@ public:
|
||||
env.fund(XRP(1000), bob, ed, bill);
|
||||
env(ammAlice.bid(
|
||||
{.bidMin = 100, .authAccounts = {carol, bob, ed, bill}}));
|
||||
if (!features[fixAMMv1_3])
|
||||
BEAST_EXPECT(ammAlice.expectAmmRpcInfo(
|
||||
XRP(80000),
|
||||
USD(80000),
|
||||
IOUAmount{79994400},
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
ammAlice.ammAccount()));
|
||||
else
|
||||
BEAST_EXPECT(ammAlice.expectAmmRpcInfo(
|
||||
XRPAmount(80000000005),
|
||||
STAmount{USD, UINT64_C(80'000'00000000005), -11},
|
||||
IOUAmount{79994400},
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
ammAlice.ammAccount()));
|
||||
BEAST_EXPECT(ammAlice.expectAmmRpcInfo(
|
||||
XRPAmount(80000000005),
|
||||
STAmount{USD, UINT64_C(80'000'00000000005), -11},
|
||||
IOUAmount{79994400},
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
ammAlice.ammAccount()));
|
||||
for (auto i = 0; i < 2; ++i)
|
||||
{
|
||||
std::unordered_set<std::string> authAccounts = {
|
||||
@@ -363,7 +351,6 @@ public:
|
||||
testErrors();
|
||||
testSimpleRpc();
|
||||
testVoteAndBid(all);
|
||||
testVoteAndBid(all - fixAMMv1_3);
|
||||
testFreeze();
|
||||
testInvalidAmmField();
|
||||
}
|
||||
|
||||
@@ -590,13 +590,6 @@ getRoundedAsset(
|
||||
A const& frac,
|
||||
IsDeposit isDeposit)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
{
|
||||
if constexpr (std::is_same_v<A, STAmount>)
|
||||
return multiply(balance, frac, balance.issue());
|
||||
else
|
||||
return toSTAmount(balance.issue(), balance * frac);
|
||||
}
|
||||
auto const rm = detail::getAssetRounding(isDeposit);
|
||||
return multiply(balance, frac, rm);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,7 @@ ammLPTokens(
|
||||
Issue const& lptIssue)
|
||||
{
|
||||
// AMM invariant: sqrt(asset1 * asset2) >= LPTokensBalance
|
||||
auto const rounding =
|
||||
isFeatureEnabled(fixAMMv1_3) ? Number::downward : Number::getround();
|
||||
auto const rounding = Number::downward;
|
||||
NumberRoundModeGuard g(rounding);
|
||||
auto const tokens = root2(asset1 * asset2);
|
||||
return toSTAmount(lptIssue, tokens);
|
||||
@@ -52,17 +51,10 @@ lpTokensOut(
|
||||
auto const f2 = feeMultHalf(tfee) / f1;
|
||||
Number const r = asset1Deposit / asset1Balance;
|
||||
auto const c = root2(f2 * f2 + r / f1) - f2;
|
||||
if (!isFeatureEnabled(fixAMMv1_3))
|
||||
{
|
||||
auto const t = lptAMMBalance * (r - c) / (1 + c);
|
||||
return toSTAmount(lptAMMBalance.issue(), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
// minimize tokens out
|
||||
auto const frac = (r - c) / (1 + c);
|
||||
return multiply(lptAMMBalance, frac, Number::downward);
|
||||
}
|
||||
|
||||
// minimize tokens out
|
||||
auto const frac = (r - c) / (1 + c);
|
||||
return multiply(lptAMMBalance, frac, Number::downward);
|
||||
}
|
||||
|
||||
/* Equation 4 solves equation 3 for b:
|
||||
@@ -91,17 +83,10 @@ ammAssetIn(
|
||||
auto const a = 1 / (t2 * t2);
|
||||
auto const b = 2 * d / t2 - 1 / f1;
|
||||
auto const c = d * d - f2 * f2;
|
||||
if (!isFeatureEnabled(fixAMMv1_3))
|
||||
{
|
||||
return toSTAmount(
|
||||
asset1Balance.issue(), asset1Balance * solveQuadraticEq(a, b, c));
|
||||
}
|
||||
else
|
||||
{
|
||||
// maximize deposit
|
||||
auto const frac = solveQuadraticEq(a, b, c);
|
||||
return multiply(asset1Balance, frac, Number::upward);
|
||||
}
|
||||
|
||||
// maximize deposit
|
||||
auto const frac = solveQuadraticEq(a, b, c);
|
||||
return multiply(asset1Balance, frac, Number::upward);
|
||||
}
|
||||
|
||||
/* Equation 7:
|
||||
@@ -118,17 +103,10 @@ lpTokensIn(
|
||||
Number const fr = asset1Withdraw / asset1Balance;
|
||||
auto const f1 = getFee(tfee);
|
||||
auto const c = fr * f1 + 2 - f1;
|
||||
if (!isFeatureEnabled(fixAMMv1_3))
|
||||
{
|
||||
auto const t = lptAMMBalance * (c - root2(c * c - 4 * fr)) / 2;
|
||||
return toSTAmount(lptAMMBalance.issue(), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
// maximize tokens in
|
||||
auto const frac = (c - root2(c * c - 4 * fr)) / 2;
|
||||
return multiply(lptAMMBalance, frac, Number::upward);
|
||||
}
|
||||
|
||||
// maximize tokens in
|
||||
auto const frac = (c - root2(c * c - 4 * fr)) / 2;
|
||||
return multiply(lptAMMBalance, frac, Number::upward);
|
||||
}
|
||||
|
||||
/* Equation 8 solves equation 7 for b:
|
||||
@@ -150,17 +128,10 @@ ammAssetOut(
|
||||
{
|
||||
auto const f = getFee(tfee);
|
||||
Number const t1 = lpTokens / lptAMMBalance;
|
||||
if (!isFeatureEnabled(fixAMMv1_3))
|
||||
{
|
||||
auto const b = assetBalance * (t1 * t1 - t1 * (2 - f)) / (t1 * f - 1);
|
||||
return toSTAmount(assetBalance.issue(), b);
|
||||
}
|
||||
else
|
||||
{
|
||||
// minimize withdraw
|
||||
auto const frac = (t1 * t1 - t1 * (2 - f)) / (t1 * f - 1);
|
||||
return multiply(assetBalance, frac, Number::downward);
|
||||
}
|
||||
|
||||
// minimize withdraw
|
||||
auto const frac = (t1 * t1 - t1 * (2 - f)) / (t1 * f - 1);
|
||||
return multiply(assetBalance, frac, Number::downward);
|
||||
}
|
||||
|
||||
Number
|
||||
@@ -194,48 +165,7 @@ adjustAmountsByLPTokens(
|
||||
IsDeposit isDeposit)
|
||||
{
|
||||
// AMMv1_3 amendment adjusts tokens and amounts in deposit/withdraw
|
||||
if (isFeatureEnabled(fixAMMv1_3))
|
||||
return std::make_tuple(amount, amount2, lpTokens);
|
||||
|
||||
auto const lpTokensActual =
|
||||
adjustLPTokens(lptAMMBalance, lpTokens, isDeposit);
|
||||
|
||||
if (lpTokensActual == beast::zero)
|
||||
{
|
||||
auto const amount2Opt =
|
||||
amount2 ? std::make_optional(STAmount{}) : std::nullopt;
|
||||
return std::make_tuple(STAmount{}, amount2Opt, lpTokensActual);
|
||||
}
|
||||
|
||||
if (lpTokensActual < lpTokens)
|
||||
{
|
||||
// Equal trade
|
||||
if (amount2)
|
||||
{
|
||||
Number const fr = lpTokensActual / lpTokens;
|
||||
auto const amountActual = toSTAmount(amount.issue(), fr * amount);
|
||||
auto const amount2Actual =
|
||||
toSTAmount(amount2->issue(), fr * *amount2);
|
||||
return std::make_tuple(amountActual, amount2Actual, lpTokensActual);
|
||||
}
|
||||
|
||||
// Single trade
|
||||
auto const amountActual = [&]() {
|
||||
if (isDeposit == IsDeposit::Yes)
|
||||
return ammAssetIn(
|
||||
amountBalance, lptAMMBalance, lpTokensActual, tfee);
|
||||
return ammAssetOut(
|
||||
amountBalance, lptAMMBalance, lpTokensActual, tfee);
|
||||
}();
|
||||
|
||||
return std::make_tuple(amountActual, std::nullopt, lpTokensActual);
|
||||
}
|
||||
|
||||
XRPL_ASSERT(
|
||||
lpTokensActual == lpTokens,
|
||||
"ripple::adjustAmountsByLPTokens : LP tokens match actual");
|
||||
|
||||
return {amount, amount2, lpTokensActual};
|
||||
return std::make_tuple(amount, amount2, lpTokens);
|
||||
}
|
||||
|
||||
Number
|
||||
@@ -275,9 +205,6 @@ getRoundedAsset(
|
||||
std::function<Number()>&& productCb,
|
||||
IsDeposit isDeposit)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return toSTAmount(balance.issue(), noRoundCb());
|
||||
|
||||
auto const rm = detail::getAssetRounding(isDeposit);
|
||||
if (isDeposit == IsDeposit::Yes)
|
||||
return multiply(balance, productCb(), rm);
|
||||
@@ -292,9 +219,6 @@ getRoundedLPTokens(
|
||||
Number const& frac,
|
||||
IsDeposit isDeposit)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return toSTAmount(balance.issue(), balance * frac);
|
||||
|
||||
auto const rm = detail::getLPTokenRounding(isDeposit);
|
||||
auto const tokens = multiply(balance, frac, rm);
|
||||
return adjustLPTokens(balance, tokens, isDeposit);
|
||||
@@ -308,9 +232,6 @@ getRoundedLPTokens(
|
||||
std::function<Number()>&& productCb,
|
||||
IsDeposit isDeposit)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return toSTAmount(lptAMMBalance.issue(), noRoundCb());
|
||||
|
||||
auto const tokens = [&] {
|
||||
auto const rm = detail::getLPTokenRounding(isDeposit);
|
||||
if (isDeposit == IsDeposit::Yes)
|
||||
@@ -332,8 +253,6 @@ adjustAssetInByTokens(
|
||||
STAmount const& tokens,
|
||||
std::uint16_t tfee)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return {tokens, amount};
|
||||
auto assetAdj = ammAssetIn(balance, lptAMMBalance, tokens, tfee);
|
||||
auto tokensAdj = tokens;
|
||||
// Rounding didn't work the right way.
|
||||
@@ -358,8 +277,6 @@ adjustAssetOutByTokens(
|
||||
STAmount const& tokens,
|
||||
std::uint16_t tfee)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return {tokens, amount};
|
||||
auto assetAdj = ammAssetOut(balance, lptAMMBalance, tokens, tfee);
|
||||
auto tokensAdj = tokens;
|
||||
// Rounding didn't work the right way.
|
||||
@@ -382,8 +299,6 @@ adjustFracByTokens(
|
||||
STAmount const& tokens,
|
||||
Number const& frac)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return frac;
|
||||
return tokens / lptAMMBalance;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ AMMBid::preflight(PreflightContext const& ctx)
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid number of AuthAccounts.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
else if (ctx.rules.enabled(fixAMMv1_3))
|
||||
else
|
||||
{
|
||||
AccountID account = ctx.tx[sfAccount];
|
||||
std::set<AccountID> unique;
|
||||
|
||||
@@ -634,8 +634,6 @@ adjustLPTokensOut(
|
||||
STAmount const& lptAMMBalance,
|
||||
STAmount const& lpTokensDeposit)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3))
|
||||
return lpTokensDeposit;
|
||||
return adjustLPTokens(lptAMMBalance, lpTokensDeposit, IsDeposit::Yes);
|
||||
}
|
||||
|
||||
@@ -658,7 +656,7 @@ AMMDeposit::equalDepositTokens(
|
||||
{
|
||||
auto const tokensAdj =
|
||||
adjustLPTokensOut(view.rules(), lptAMMBalance, lpTokensDeposit);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
auto const frac =
|
||||
divide(tokensAdj, lptAMMBalance, lptAMMBalance.issue());
|
||||
@@ -735,10 +733,7 @@ AMMDeposit::equalDepositLimit(
|
||||
getRoundedLPTokens(view.rules(), lptAMMBalance, frac, IsDeposit::Yes);
|
||||
if (tokensAdj == beast::zero)
|
||||
{
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
return {tecAMM_FAILED, STAmount{}}; // LCOV_EXCL_LINE
|
||||
else
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
}
|
||||
// factor in the adjusted tokens
|
||||
frac = adjustFracByTokens(view.rules(), lptAMMBalance, tokensAdj, frac);
|
||||
@@ -762,10 +757,7 @@ AMMDeposit::equalDepositLimit(
|
||||
getRoundedLPTokens(view.rules(), lptAMMBalance, frac, IsDeposit::Yes);
|
||||
if (tokensAdj == beast::zero)
|
||||
{
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
return {tecAMM_FAILED, STAmount{}}; // LCOV_EXCL_LINE
|
||||
else
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
}
|
||||
// factor in the adjusted tokens
|
||||
frac = adjustFracByTokens(view.rules(), lptAMMBalance, tokensAdj, frac);
|
||||
@@ -811,15 +803,12 @@ AMMDeposit::singleDeposit(
|
||||
lpTokensOut(amountBalance, amount, lptAMMBalance, tfee));
|
||||
if (tokens == beast::zero)
|
||||
{
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
return {tecAMM_FAILED, STAmount{}}; // LCOV_EXCL_LINE
|
||||
else
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
}
|
||||
// factor in the adjusted tokens
|
||||
auto const [tokensAdj, amountDepositAdj] = adjustAssetInByTokens(
|
||||
view.rules(), amountBalance, amount, lptAMMBalance, tokens, tfee);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
return deposit(
|
||||
view,
|
||||
@@ -854,7 +843,7 @@ AMMDeposit::singleDepositTokens(
|
||||
{
|
||||
auto const tokensAdj =
|
||||
adjustLPTokensOut(view.rules(), lptAMMBalance, lpTokensDeposit);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
// the adjusted tokens are factored in
|
||||
auto const amountDeposit =
|
||||
@@ -918,15 +907,12 @@ AMMDeposit::singleDepositEPrice(
|
||||
lpTokensOut(amountBalance, amount, lptAMMBalance, tfee));
|
||||
if (tokens <= beast::zero)
|
||||
{
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
return {tecAMM_FAILED, STAmount{}}; // LCOV_EXCL_LINE
|
||||
else
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
}
|
||||
// factor in the adjusted tokens
|
||||
auto const [tokensAdj, amountDepositAdj] = adjustAssetInByTokens(
|
||||
view.rules(), amountBalance, amount, lptAMMBalance, tokens, tfee);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
auto const ep = Number{amountDepositAdj} / tokensAdj;
|
||||
if (ep <= ePrice)
|
||||
@@ -988,7 +974,7 @@ AMMDeposit::singleDepositEPrice(
|
||||
lptAMMBalance,
|
||||
tokens,
|
||||
tfee);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
|
||||
return deposit(
|
||||
|
||||
@@ -689,7 +689,7 @@ adjustLPTokensIn(
|
||||
STAmount const& lpTokensWithdraw,
|
||||
WithdrawAll withdrawAll)
|
||||
{
|
||||
if (!rules.enabled(fixAMMv1_3) || withdrawAll == WithdrawAll::Yes)
|
||||
if (withdrawAll == WithdrawAll::Yes)
|
||||
return lpTokensWithdraw;
|
||||
return adjustLPTokens(lptAMMBalance, lpTokensWithdraw, IsDeposit::No);
|
||||
}
|
||||
@@ -801,7 +801,7 @@ AMMWithdraw::equalWithdrawTokens(
|
||||
|
||||
auto const tokensAdj = adjustLPTokensIn(
|
||||
view.rules(), lptAMMBalance, lpTokensWithdraw, withdrawAll);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {
|
||||
tecAMM_INVALID_TOKENS, STAmount{}, STAmount{}, std::nullopt};
|
||||
// the adjusted tokens are factored in
|
||||
@@ -885,7 +885,7 @@ AMMWithdraw::equalWithdrawLimit(
|
||||
getRoundedAsset(view.rules(), amount2Balance, frac, IsDeposit::No);
|
||||
auto tokensAdj =
|
||||
getRoundedLPTokens(view.rules(), lptAMMBalance, frac, IsDeposit::No);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
// factor in the adjusted tokens
|
||||
frac = adjustFracByTokens(view.rules(), lptAMMBalance, tokensAdj, frac);
|
||||
@@ -910,21 +910,13 @@ AMMWithdraw::equalWithdrawLimit(
|
||||
getRoundedAsset(view.rules(), amountBalance, frac, IsDeposit::No);
|
||||
tokensAdj =
|
||||
getRoundedLPTokens(view.rules(), lptAMMBalance, frac, IsDeposit::No);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
// factor in the adjusted tokens
|
||||
frac = adjustFracByTokens(view.rules(), lptAMMBalance, tokensAdj, frac);
|
||||
amountWithdraw =
|
||||
getRoundedAsset(view.rules(), amountBalance, frac, IsDeposit::No);
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
XRPL_ASSERT(
|
||||
amountWithdraw <= amount,
|
||||
"ripple::AMMWithdraw::equalWithdrawLimit : maximum amountWithdraw");
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
else if (amountWithdraw > amount)
|
||||
if (amountWithdraw > amount)
|
||||
return {tecAMM_FAILED, STAmount{}}; // LCOV_EXCL_LINE
|
||||
return withdraw(
|
||||
view,
|
||||
@@ -960,15 +952,12 @@ AMMWithdraw::singleWithdraw(
|
||||
isWithdrawAll(ctx_.tx));
|
||||
if (tokens == beast::zero)
|
||||
{
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
return {tecAMM_FAILED, STAmount{}}; // LCOV_EXCL_LINE
|
||||
else
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
}
|
||||
// factor in the adjusted tokens
|
||||
auto const [tokensAdj, amountWithdrawAdj] = adjustAssetOutByTokens(
|
||||
view.rules(), amountBalance, amount, lptAMMBalance, tokens, tfee);
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}}; // LCOV_EXCL_LINE
|
||||
return withdraw(
|
||||
view,
|
||||
@@ -1005,7 +994,7 @@ AMMWithdraw::singleWithdrawTokens(
|
||||
{
|
||||
auto const tokensAdj = adjustLPTokensIn(
|
||||
view.rules(), lptAMMBalance, lpTokensWithdraw, isWithdrawAll(ctx_.tx));
|
||||
if (view.rules().enabled(fixAMMv1_3) && tokensAdj == beast::zero)
|
||||
if (tokensAdj == beast::zero)
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
// the adjusted tokens are factored in
|
||||
auto const amountWithdraw =
|
||||
@@ -1080,10 +1069,7 @@ AMMWithdraw::singleWithdrawEPrice(
|
||||
view.rules(), tokNoRoundCb, lptAMMBalance, tokProdCb, IsDeposit::No);
|
||||
if (tokensAdj <= beast::zero)
|
||||
{
|
||||
if (!view.rules().enabled(fixAMMv1_3))
|
||||
return {tecAMM_FAILED, STAmount{}};
|
||||
else
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
return {tecAMM_INVALID_TOKENS, STAmount{}};
|
||||
}
|
||||
auto amtNoRoundCb = [&] { return tokensAdj / ePrice; };
|
||||
auto amtProdCb = [&] { return tokensAdj / ePrice; };
|
||||
|
||||
@@ -1954,7 +1954,7 @@ ValidAMM::finalize(
|
||||
if (result != tesSUCCESS && result != tecINCOMPLETE)
|
||||
return true;
|
||||
|
||||
bool const enforce = view.rules().enabled(fixAMMv1_3);
|
||||
bool const enforce = true; // view.rules().enabled(fixAMMv1_3);
|
||||
|
||||
switch (tx.getTxnType())
|
||||
{
|
||||
|
||||
@@ -173,9 +173,6 @@ public:
|
||||
bool
|
||||
checkInvariant(TAmounts<TIn, TOut> const& consumed, beast::Journal j) const
|
||||
{
|
||||
if (!isFeatureEnabled(fixAMMv1_3))
|
||||
return true;
|
||||
|
||||
if (consumed.in > m_amounts.in || consumed.out > m_amounts.out)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
Reference in New Issue
Block a user