diff --git a/include/xrpl/protocol/Feature.h b/include/xrpl/protocol/Feature.h index a54bfdf40..cdac4530f 100644 --- a/include/xrpl/protocol/Feature.h +++ b/include/xrpl/protocol/Feature.h @@ -80,7 +80,7 @@ namespace detail { // Feature.cpp. Because it's only used to reserve storage, and determine how // large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than // the actual number of amendments. A LogicError on startup will verify this. -static constexpr std::size_t numFeatures = 107; +static constexpr std::size_t numFeatures = 103; /** Amendments that this server supports and the default voting behavior. Whether they are enabled depends on the Rules defined in the validated diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index 965af745a..f83008a67 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -29,13 +29,11 @@ // If you add an amendment here, then do not forget to increment `numFeatures` // in include/xrpl/protocol/Feature.h. -XRPL_FIX (FrozenLPTokenTransfer, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(DeepFreeze, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(PermissionedDomains, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(DynamicNFT, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(Credentials, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(AMMClawback, Supported::yes, VoteBehavior::DefaultNo) -XRPL_FIX (AMMv1_2, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(MPTokensV1, Supported::yes, VoteBehavior::DefaultNo) // InvariantsV1_1 will be changes to Supported::yes when all the // invariants expected to be included under it are complete. @@ -44,10 +42,8 @@ XRPL_FIX (NFTokenPageLinks, Supported::yes, VoteBehavior::DefaultNo XRPL_FIX (EnforceNFTokenTrustline, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (ReducedOffersV2, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(NFTokenMintOffer, Supported::yes, VoteBehavior::DefaultNo) -XRPL_FIX (AMMv1_1, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (PreviousTxnID, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(PriceOracle, Supported::yes, VoteBehavior::DefaultNo) -XRPL_FIX (AMMOverflowOffer, Supported::yes, VoteBehavior::DefaultYes) XRPL_FIX (InnerObjTemplate, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (NFTokenReserve, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (FillOrKill, Supported::yes, VoteBehavior::DefaultNo) diff --git a/include/xrpl/protocol/detail/ledger_entries.macro b/include/xrpl/protocol/detail/ledger_entries.macro index f23b39651..f7397fd38 100644 --- a/include/xrpl/protocol/detail/ledger_entries.macro +++ b/include/xrpl/protocol/detail/ledger_entries.macro @@ -482,8 +482,8 @@ LEDGER_ENTRY(ltAMM, 0x0079, AMM, amm, ({ {sfAsset, soeREQUIRED}, {sfAsset2, soeREQUIRED}, {sfOwnerNode, soeREQUIRED}, - {sfPreviousTxnID, soeOPTIONAL}, - {sfPreviousTxnLgrSeq, soeOPTIONAL}, + {sfPreviousTxnID, soeREQUIRED}, + {sfPreviousTxnLgrSeq, soeREQUIRED}, })) /** A ledger object which tracks Oracle diff --git a/src/libxrpl/protocol/STLedgerEntry.cpp b/src/libxrpl/protocol/STLedgerEntry.cpp index c4339f042..2f5feeb9d 100644 --- a/src/libxrpl/protocol/STLedgerEntry.cpp +++ b/src/libxrpl/protocol/STLedgerEntry.cpp @@ -135,12 +135,11 @@ STLedgerEntry::getJson(JsonOptions options) const bool STLedgerEntry::isThreadedType(Rules const& rules) const { - static constexpr std::array newPreviousTxnIDTypes = { + static constexpr std::array newPreviousTxnIDTypes = { ltDIR_NODE, ltAMENDMENTS, ltFEE_SETTINGS, ltNEGATIVE_UNL, - ltAMM, ltHOOK_STATE, ltHOOK_DEFINITION, ltIMPORT_VLSEQ, diff --git a/src/test/app/AMMExtended_test.cpp b/src/test/app/AMMExtended_test.cpp index e09b14e89..5bc88f40a 100644 --- a/src/test/app/AMMExtended_test.cpp +++ b/src/test/app/AMMExtended_test.cpp @@ -94,20 +94,10 @@ private: sendmax(BTC(1'000)), txflags(tfPartialPayment)); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammCarol.expectBalances( - STAmount{BTC, UINT64_C(1'001'000000374812), -12}, - USD(100'000), - ammCarol.tokens())); - } - else - { - BEAST_EXPECT(ammCarol.expectBalances( - STAmount{BTC, UINT64_C(1'001'000000374815), -12}, - USD(100'000), - ammCarol.tokens())); - } + BEAST_EXPECT(ammCarol.expectBalances( + STAmount{BTC, UINT64_C(1'001'000000374815), -12}, + USD(100'000), + ammCarol.tokens())); env.require(balance(bob, USD(200'100))); BEAST_EXPECT(isOffer(env, carol, BTC(49), XRP(49))); @@ -720,24 +710,12 @@ private: auto const jrr = env.rpc("json", "submit", to_string(payment)); BEAST_EXPECT(jrr[jss::result][jss::status] == "success"); BEAST_EXPECT(jrr[jss::result][jss::engine_result] == "tesSUCCESS"); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammAlice.expectBalances( - STAmount(XTS, UINT64_C(101'010101010101), -12), - XXX(99), - ammAlice.tokens())); - BEAST_EXPECT(expectLine( - env, bob, STAmount{XTS, UINT64_C(98'989898989899), -12})); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - STAmount(XTS, UINT64_C(101'0101010101011), -13), - XXX(99), - ammAlice.tokens())); - BEAST_EXPECT(expectLine( - env, bob, STAmount{XTS, UINT64_C(98'9898989898989), -13})); - } + BEAST_EXPECT(ammAlice.expectBalances( + STAmount(XTS, UINT64_C(101'0101010101011), -13), + XXX(99), + ammAlice.tokens())); + BEAST_EXPECT(expectLine( + env, bob, STAmount{XTS, UINT64_C(98'9898989898989), -13})); BEAST_EXPECT(expectLine(env, bob, XXX(101))); } @@ -1291,34 +1269,17 @@ private: env(offer(cam, B_BUX(30), A_BUX(30))); // AMM is consumed up to the first cam Offer quality - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammCarol.expectBalances( - STAmount{A_BUX, UINT64_C(309'3541659651605), -13}, - STAmount{B_BUX, UINT64_C(320'0215509984417), -13}, - ammCarol.tokens())); - BEAST_EXPECT(expectOffers( - env, - cam, - 1, - {{Amounts{ - STAmount{B_BUX, UINT64_C(20'0215509984417), -13}, - STAmount{A_BUX, UINT64_C(20'0215509984417), -13}}}})); - } - else - { - BEAST_EXPECT(ammCarol.expectBalances( - STAmount{A_BUX, UINT64_C(309'3541659651604), -13}, - STAmount{B_BUX, UINT64_C(320'0215509984419), -13}, - ammCarol.tokens())); - BEAST_EXPECT(expectOffers( - env, - cam, - 1, - {{Amounts{ - STAmount{B_BUX, UINT64_C(20'0215509984419), -13}, - STAmount{A_BUX, UINT64_C(20'0215509984419), -13}}}})); - } + BEAST_EXPECT(ammCarol.expectBalances( + STAmount{A_BUX, UINT64_C(309'3541659651604), -13}, + STAmount{B_BUX, UINT64_C(320'0215509984419), -13}, + ammCarol.tokens())); + BEAST_EXPECT(expectOffers( + env, + cam, + 1, + {{Amounts{ + STAmount{B_BUX, UINT64_C(20'0215509984419), -13}, + STAmount{A_BUX, UINT64_C(20'0215509984419), -13}}}})); } void @@ -1444,7 +1405,6 @@ private: using namespace jtx; FeatureBitset const all{supported_amendments()}; testRmFundedOffer(all); - testRmFundedOffer(all - fixAMMv1_1); testEnforceNoRipple(all); testFillModes(all); testOfferCrossWithXRP(all); @@ -1458,7 +1418,6 @@ private: testOfferCreateThenCross(all); testSellFlagExceedLimit(all); testGatewayCrossCurrency(all); - testGatewayCrossCurrency(all - fixAMMv1_1); testBridgedCross(all); testSellWithFillOrKill(all); testTransferRateOffer(all); @@ -1466,7 +1425,6 @@ private: testBadPathAssert(all); testSellFlagBasic(all); testDirectToDirectPath(all); - testDirectToDirectPath(all - fixAMMv1_1); testRequireAuth(all); testMissingAuth(all); } @@ -2326,36 +2284,16 @@ private: txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality)); env.close(); - if (!features[fixAMMv1_1]) - { - // alice buys 77.2727USD with 75.5555GBP and pays 25% tr fee - // on 75.5555GBP - // 1,200 - 75.55555*1.25 = 1200 - 94.4444 = 1105.55555GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'105'555555555555), -12})); - // 75.5555GBP is swapped in for 77.7272USD - BEAST_EXPECT(amm.expectBalances( - STAmount{GBP, UINT64_C(1'075'555555555556), -12}, - STAmount{USD, UINT64_C(1'022'727272727272), -12}, - amm.tokens())); - } - else - { - // alice buys 77.2727USD with 75.5555GBP and pays 25% tr fee - // on 75.5555GBP - // 1,200 - 75.55555*1.25 = 1200 - 94.4444 = 1105.55555GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'105'555555555554), -12})); - // 75.5555GBP is swapped in for 77.7272USD - BEAST_EXPECT(amm.expectBalances( - STAmount{GBP, UINT64_C(1'075'555555555557), -12}, - STAmount{USD, UINT64_C(1'022'727272727272), -12}, - amm.tokens())); - } + // alice buys 77.2727USD with 75.5555GBP and pays 25% tr fee + // on 75.5555GBP + // 1,200 - 75.55555*1.25 = 1200 - 94.4444 = 1105.55555GBP + BEAST_EXPECT(expectLine( + env, alice, STAmount{GBP, UINT64_C(1'105'555555555554), -12})); + // 75.5555GBP is swapped in for 77.7272USD + BEAST_EXPECT(amm.expectBalances( + STAmount{GBP, UINT64_C(1'075'555555555557), -12}, + STAmount{USD, UINT64_C(1'022'727272727272), -12}, + amm.tokens())); BEAST_EXPECT(expectLine( env, carol, STAmount{USD, UINT64_C(1'277'272727272728), -12})); } @@ -2373,36 +2311,18 @@ private: env(offer(alice, EUR(100), USD(100))); env.close(); - if (!features[fixAMMv1_1]) - { - // 95.2380USD is swapped in for 100EUR - BEAST_EXPECT(amm.expectBalances( - STAmount{USD, UINT64_C(1'095'238095238095), -12}, - EUR(1'050), - amm.tokens())); - // alice pays 25% tr fee on 95.2380USD - // 1200-95.2380*1.25 = 1200 - 119.0477 = 1080.9523USD - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{USD, UINT64_C(1'080'952380952381), -12}, - EUR(1'300))); - } - else - { - // 95.2380USD is swapped in for 100EUR - BEAST_EXPECT(amm.expectBalances( - STAmount{USD, UINT64_C(1'095'238095238096), -12}, - EUR(1'050), - amm.tokens())); - // alice pays 25% tr fee on 95.2380USD - // 1200-95.2380*1.25 = 1200 - 119.0477 = 1080.9523USD - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{USD, UINT64_C(1'080'95238095238), -11}, - EUR(1'300))); - } + // 95.2380USD is swapped in for 100EUR + BEAST_EXPECT(amm.expectBalances( + STAmount{USD, UINT64_C(1'095'238095238096), -12}, + EUR(1'050), + amm.tokens())); + // alice pays 25% tr fee on 95.2380USD + // 1200-95.2380*1.25 = 1200 - 119.0477 = 1080.9523USD + BEAST_EXPECT(expectLine( + env, + alice, + STAmount{USD, UINT64_C(1'080'95238095238), -11}, + EUR(1'300))); BEAST_EXPECT(expectOffers(env, alice, 0)); } @@ -2426,42 +2346,23 @@ private: env(pay(gw, dan, USD(1'000))); AMM ammDan(env, dan, USD(1'000), EUR(1'050)); - if (!features[fixAMMv1_1]) - { - // alice -> bob -> gw -> carol. $50 should have transfer fee; - // $10, no fee - env(pay(alice, carol, EUR(50)), - path(bob, gw, ~EUR), - sendmax(USDA(60)), - txflags(tfNoRippleDirect)); - BEAST_EXPECT(ammDan.expectBalances( - USD(1'050), EUR(1'000), ammDan.tokens())); - BEAST_EXPECT(expectLine(env, dan, USD(0))); - BEAST_EXPECT(expectLine(env, dan, EUR(0))); - BEAST_EXPECT(expectLine(env, bob, USD(-10))); - BEAST_EXPECT(expectLine(env, bob, USDA(60))); - BEAST_EXPECT(expectLine(env, carol, EUR(50))); - } - else - { - // alice -> bob -> gw -> carol. $50 should have transfer fee; - // $10, no fee - env(pay(alice, carol, EUR(50)), - path(bob, gw, ~EUR), - sendmax(USDA(60.1)), - txflags(tfNoRippleDirect)); - BEAST_EXPECT(ammDan.expectBalances( - STAmount{USD, UINT64_C(1'050'000000000001), -12}, - EUR(1'000), - ammDan.tokens())); - BEAST_EXPECT(expectLine(env, dan, USD(0))); - BEAST_EXPECT(expectLine(env, dan, EUR(0))); - BEAST_EXPECT(expectLine( - env, bob, STAmount{USD, INT64_C(-10'000000000001), -12})); - BEAST_EXPECT(expectLine( - env, bob, STAmount{USDA, UINT64_C(60'000000000001), -12})); - BEAST_EXPECT(expectLine(env, carol, EUR(50))); - } + // alice -> bob -> gw -> carol. $50 should have transfer fee; + // $10, no fee + env(pay(alice, carol, EUR(50)), + path(bob, gw, ~EUR), + sendmax(USDA(60.1)), + txflags(tfNoRippleDirect)); + BEAST_EXPECT(ammDan.expectBalances( + STAmount{USD, UINT64_C(1'050'000000000001), -12}, + EUR(1'000), + ammDan.tokens())); + BEAST_EXPECT(expectLine(env, dan, USD(0))); + BEAST_EXPECT(expectLine(env, dan, EUR(0))); + BEAST_EXPECT(expectLine( + env, bob, STAmount{USD, INT64_C(-10'000000000001), -12})); + BEAST_EXPECT(expectLine( + env, bob, STAmount{USDA, UINT64_C(60'000000000001), -12})); + BEAST_EXPECT(expectLine(env, carol, EUR(50))); } } @@ -2495,21 +2396,11 @@ private: // alice buys 107.1428USD with 120GBP and pays 25% tr fee on 120GBP // 1,000 - 120*1.25 = 850GBP BEAST_EXPECT(expectLine(env, alice, GBP(850))); - if (!features[fixAMMv1_1]) - { - // 120GBP is swapped in for 107.1428USD - BEAST_EXPECT(amm.expectBalances( - GBP(1'120), - STAmount{USD, UINT64_C(892'8571428571428), -13}, - amm.tokens())); - } - else - { - BEAST_EXPECT(amm.expectBalances( - GBP(1'120), - STAmount{USD, UINT64_C(892'8571428571429), -13}, - amm.tokens())); - } + BEAST_EXPECT(amm.expectBalances( + GBP(1'120), + STAmount{USD, UINT64_C(892'8571428571429), -13}, + amm.tokens())); + // 25% of 85.7142USD is paid in tr fee // 85.7142*1.25 = 107.1428USD BEAST_EXPECT(expectLine( @@ -2584,38 +2475,20 @@ private: env.close(); BEAST_EXPECT(expectLine(env, alice, GBP(850))); - if (!features[fixAMMv1_1]) - { - // alice buys 107.1428EUR with 120GBP and pays 25% tr fee on - // 120GBP 1,000 - 120*1.25 = 850GBP 120GBP is swapped in for - // 107.1428EUR - BEAST_EXPECT(amm1.expectBalances( - GBP(1'120), - STAmount{EUR, UINT64_C(892'8571428571428), -13}, - amm1.tokens())); - // 25% on 85.7142EUR is paid in tr fee 85.7142*1.25 = - // 107.1428EUR 85.7142EUR is swapped in for 78.9473USD - BEAST_EXPECT(amm2.expectBalances( - STAmount(EUR, UINT64_C(1'085'714285714286), -12), - STAmount{USD, UINT64_C(921'0526315789471), -13}, - amm2.tokens())); - } - else - { - // alice buys 107.1428EUR with 120GBP and pays 25% tr fee on - // 120GBP 1,000 - 120*1.25 = 850GBP 120GBP is swapped in for - // 107.1428EUR - BEAST_EXPECT(amm1.expectBalances( - GBP(1'120), - STAmount{EUR, UINT64_C(892'8571428571429), -13}, - amm1.tokens())); - // 25% on 85.7142EUR is paid in tr fee 85.7142*1.25 = - // 107.1428EUR 85.7142EUR is swapped in for 78.9473USD - BEAST_EXPECT(amm2.expectBalances( - STAmount(EUR, UINT64_C(1'085'714285714286), -12), - STAmount{USD, UINT64_C(921'052631578948), -12}, - amm2.tokens())); - } + // alice buys 107.1428EUR with 120GBP and pays 25% tr fee on + // 120GBP 1,000 - 120*1.25 = 850GBP 120GBP is swapped in for + // 107.1428EUR + BEAST_EXPECT(amm1.expectBalances( + GBP(1'120), + STAmount{EUR, UINT64_C(892'8571428571429), -13}, + amm1.tokens())); + // 25% on 85.7142EUR is paid in tr fee 85.7142*1.25 = + // 107.1428EUR 85.7142EUR is swapped in for 78.9473USD + BEAST_EXPECT(amm2.expectBalances( + STAmount(EUR, UINT64_C(1'085'714285714286), -12), + STAmount{USD, UINT64_C(921'052631578948), -12}, + amm2.tokens())); + // 25% on 63.1578USD is paid in tr fee 63.1578*1.25 = 78.9473USD BEAST_EXPECT(expectLine( env, carol, STAmount(USD, UINT64_C(1'063'157894736842), -12))); @@ -2701,31 +2574,17 @@ private: txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality)); env.close(); - if (!features[fixAMMv1_1]) - { - // alice buys 28.125USD with 24GBP and pays 25% tr fee - // on 24GBP - // 1,200 - 24*1.25 = 1,170GBP - BEAST_EXPECT(expectLine(env, alice, GBP(1'170))); - // 24GBP is swapped in for 28.125USD - BEAST_EXPECT(amm.expectBalances( - GBP(1'024), USD(1'171.875), amm.tokens())); - } - else - { - // alice buys 28.125USD with 24GBP and pays 25% tr fee - // on 24GBP - // 1,200 - 24*1.25 =~ 1,170GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'169'999999999999), -12})); - // 24GBP is swapped in for 28.125USD - BEAST_EXPECT(amm.expectBalances( - STAmount{GBP, UINT64_C(1'024'000000000001), -12}, - USD(1'171.875), - amm.tokens())); - } + // alice buys 28.125USD with 24GBP and pays 25% tr fee + // on 24GBP + // 1,200 - 24*1.25 =~ 1,170GBP + BEAST_EXPECT(expectLine( + env, alice, STAmount{GBP, UINT64_C(1'169'999999999999), -12})); + // 24GBP is swapped in for 28.125USD + BEAST_EXPECT(amm.expectBalances( + STAmount{GBP, UINT64_C(1'024'000000000001), -12}, + USD(1'171.875), + amm.tokens())); + // 25% on 22.5USD is paid in tr fee // 22.5*1.25 = 28.125USD BEAST_EXPECT(expectLine(env, carol, USD(1'222.5))); @@ -2758,66 +2617,32 @@ private: txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality)); env.close(); - if (!features[fixAMMv1_1]) - { - // alice buys 70.4210EUR with 70.4210GBP via the offer - // and pays 25% tr fee on 70.4210GBP - // 1,400 - 70.4210*1.25 = 1400 - 88.0262 = 1311.9736GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'311'973684210527), -12})); - // ed doesn't pay tr fee, the balances reflect consumed offer - // 70.4210GBP/70.4210EUR - BEAST_EXPECT(expectLine( - env, - ed, - STAmount{EUR, UINT64_C(1'329'578947368421), -12}, - STAmount{GBP, UINT64_C(1'470'421052631579), -12})); - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {Amounts{ - STAmount{GBP, UINT64_C(929'5789473684212), -13}, - STAmount{EUR, UINT64_C(929'5789473684212), -13}}})); - // 25% on 56.3368EUR is paid in tr fee 56.3368*1.25 = 70.4210EUR - // 56.3368EUR is swapped in for 74.6651USD - BEAST_EXPECT(amm.expectBalances( - STAmount{EUR, UINT64_C(1'056'336842105263), -12}, - STAmount{USD, UINT64_C(1'325'334821428571), -12}, - amm.tokens())); - } - else - { - // alice buys 70.4210EUR with 70.4210GBP via the offer - // and pays 25% tr fee on 70.4210GBP - // 1,400 - 70.4210*1.25 = 1400 - 88.0262 = 1311.9736GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'311'973684210525), -12})); - // ed doesn't pay tr fee, the balances reflect consumed offer - // 70.4210GBP/70.4210EUR - BEAST_EXPECT(expectLine( - env, - ed, - STAmount{EUR, UINT64_C(1'329'57894736842), -11}, - STAmount{GBP, UINT64_C(1'470'42105263158), -11})); - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {Amounts{ - STAmount{GBP, UINT64_C(929'57894736842), -11}, - STAmount{EUR, UINT64_C(929'57894736842), -11}}})); - // 25% on 56.3368EUR is paid in tr fee 56.3368*1.25 = 70.4210EUR - // 56.3368EUR is swapped in for 74.6651USD - BEAST_EXPECT(amm.expectBalances( - STAmount{EUR, UINT64_C(1'056'336842105264), -12}, - STAmount{USD, UINT64_C(1'325'334821428571), -12}, - amm.tokens())); - } + // alice buys 70.4210EUR with 70.4210GBP via the offer + // and pays 25% tr fee on 70.4210GBP + // 1,400 - 70.4210*1.25 = 1400 - 88.0262 = 1311.9736GBP + BEAST_EXPECT(expectLine( + env, alice, STAmount{GBP, UINT64_C(1'311'973684210525), -12})); + // ed doesn't pay tr fee, the balances reflect consumed offer + // 70.4210GBP/70.4210EUR + BEAST_EXPECT(expectLine( + env, + ed, + STAmount{EUR, UINT64_C(1'329'57894736842), -11}, + STAmount{GBP, UINT64_C(1'470'42105263158), -11})); + BEAST_EXPECT(expectOffers( + env, + ed, + 1, + {Amounts{ + STAmount{GBP, UINT64_C(929'57894736842), -11}, + STAmount{EUR, UINT64_C(929'57894736842), -11}}})); + // 25% on 56.3368EUR is paid in tr fee 56.3368*1.25 = 70.4210EUR + // 56.3368EUR is swapped in for 74.6651USD + BEAST_EXPECT(amm.expectBalances( + STAmount{EUR, UINT64_C(1'056'336842105264), -12}, + STAmount{USD, UINT64_C(1'325'334821428571), -12}, + amm.tokens())); + // 25% on 59.7321USD is paid in tr fee 59.7321*1.25 = 74.6651USD BEAST_EXPECT(expectLine( env, carol, STAmount(USD, UINT64_C(1'459'732142857143), -12))); @@ -2850,40 +2675,19 @@ private: txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality)); env.close(); - if (!features[fixAMMv1_1]) - { - // alice buys 53.3322EUR with 56.3368GBP via the amm - // and pays 25% tr fee on 56.3368GBP - // 1,400 - 56.3368*1.25 = 1400 - 70.4210 = 1329.5789GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'329'578947368421), -12})); - //// 25% on 56.3368EUR is paid in tr fee 56.3368*1.25 - ///= 70.4210EUR - // 56.3368GBP is swapped in for 53.3322EUR - BEAST_EXPECT(amm.expectBalances( - STAmount{GBP, UINT64_C(1'056'336842105263), -12}, - STAmount{EUR, UINT64_C(946'6677295918366), -13}, - amm.tokens())); - } - else - { - // alice buys 53.3322EUR with 56.3368GBP via the amm - // and pays 25% tr fee on 56.3368GBP - // 1,400 - 56.3368*1.25 = 1400 - 70.4210 = 1329.5789GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'329'57894736842), -11})); - //// 25% on 56.3368EUR is paid in tr fee 56.3368*1.25 - ///= 70.4210EUR - // 56.3368GBP is swapped in for 53.3322EUR - BEAST_EXPECT(amm.expectBalances( - STAmount{GBP, UINT64_C(1'056'336842105264), -12}, - STAmount{EUR, UINT64_C(946'6677295918366), -13}, - amm.tokens())); - } + // alice buys 53.3322EUR with 56.3368GBP via the amm + // and pays 25% tr fee on 56.3368GBP + // 1,400 - 56.3368*1.25 = 1400 - 70.4210 = 1329.5789GBP + BEAST_EXPECT(expectLine( + env, alice, STAmount{GBP, UINT64_C(1'329'57894736842), -11})); + //// 25% on 56.3368EUR is paid in tr fee 56.3368*1.25 + ///= 70.4210EUR + // 56.3368GBP is swapped in for 53.3322EUR + BEAST_EXPECT(amm.expectBalances( + STAmount{GBP, UINT64_C(1'056'336842105264), -12}, + STAmount{EUR, UINT64_C(946'6677295918366), -13}, + amm.tokens())); + // 25% on 42.6658EUR is paid in tr fee 42.6658*1.25 = 53.3322EUR // 42.6658EUR/59.7321USD BEAST_EXPECT(expectLine( @@ -2928,48 +2732,23 @@ private: txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality)); env.close(); - if (!features[fixAMMv1_1]) - { - // alice buys 53.3322EUR with 107.5308GBP - // 25% on 86.0246GBP is paid in tr fee - // 1,400 - 86.0246*1.25 = 1400 - 107.5308 = 1229.4691GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'292'469135802469), -12})); - // 86.0246GBP is swapped in for 79.2106EUR - BEAST_EXPECT(amm1.expectBalances( - STAmount{GBP, UINT64_C(1'086'024691358025), -12}, - STAmount{EUR, UINT64_C(920'78937795562), -11}, - amm1.tokens())); - // 25% on 63.3684EUR is paid in tr fee 63.3684*1.25 = 79.2106EUR - // 63.3684EUR is swapped in for 83.4291USD - BEAST_EXPECT(amm2.expectBalances( - STAmount{EUR, UINT64_C(1'063'368497635504), -12}, - STAmount{USD, UINT64_C(1'316'570881226053), -12}, - amm2.tokens())); - } - else - { - // alice buys 53.3322EUR with 107.5308GBP - // 25% on 86.0246GBP is paid in tr fee - // 1,400 - 86.0246*1.25 = 1400 - 107.5308 = 1229.4691GBP - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{GBP, UINT64_C(1'292'469135802466), -12})); - // 86.0246GBP is swapped in for 79.2106EUR - BEAST_EXPECT(amm1.expectBalances( - STAmount{GBP, UINT64_C(1'086'024691358027), -12}, - STAmount{EUR, UINT64_C(920'7893779556188), -13}, - amm1.tokens())); - // 25% on 63.3684EUR is paid in tr fee 63.3684*1.25 = 79.2106EUR - // 63.3684EUR is swapped in for 83.4291USD - BEAST_EXPECT(amm2.expectBalances( - STAmount{EUR, UINT64_C(1'063'368497635505), -12}, - STAmount{USD, UINT64_C(1'316'570881226053), -12}, - amm2.tokens())); - } + // alice buys 53.3322EUR with 107.5308GBP + // 25% on 86.0246GBP is paid in tr fee + // 1,400 - 86.0246*1.25 = 1400 - 107.5308 = 1229.4691GBP + BEAST_EXPECT(expectLine( + env, alice, STAmount{GBP, UINT64_C(1'292'469135802466), -12})); + // 86.0246GBP is swapped in for 79.2106EUR + BEAST_EXPECT(amm1.expectBalances( + STAmount{GBP, UINT64_C(1'086'024691358027), -12}, + STAmount{EUR, UINT64_C(920'7893779556188), -13}, + amm1.tokens())); + // 25% on 63.3684EUR is paid in tr fee 63.3684*1.25 = 79.2106EUR + // 63.3684EUR is swapped in for 83.4291USD + BEAST_EXPECT(amm2.expectBalances( + STAmount{EUR, UINT64_C(1'063'368497635505), -12}, + STAmount{USD, UINT64_C(1'316'570881226053), -12}, + amm2.tokens())); + // 25% on 66.7432USD is paid in tr fee 66.7432*1.25 = 83.4291USD BEAST_EXPECT(expectLine( env, carol, STAmount(USD, UINT64_C(1'466'743295019157), -12))); @@ -2999,34 +2778,18 @@ private: txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality)); env.close(); - if (!features[fixAMMv1_1]) - { - // 108.1481GBP is swapped in for 97.5935EUR - BEAST_EXPECT(amm1.expectBalances( - STAmount{GBP, UINT64_C(1'108'148148148149), -12}, - STAmount{EUR, UINT64_C(902'4064171122988), -13}, - amm1.tokens())); - // 25% on 78.0748EUR is paid in tr fee 78.0748*1.25 = 97.5935EUR - // 78.0748EUR is swapped in for 101.3888USD - BEAST_EXPECT(amm2.expectBalances( - STAmount{EUR, UINT64_C(1'078'074866310161), -12}, - STAmount{USD, UINT64_C(1'298'611111111111), -12}, - amm2.tokens())); - } - else - { - // 108.1481GBP is swapped in for 97.5935EUR - BEAST_EXPECT(amm1.expectBalances( - STAmount{GBP, UINT64_C(1'108'148148148151), -12}, - STAmount{EUR, UINT64_C(902'4064171122975), -13}, - amm1.tokens())); - // 25% on 78.0748EUR is paid in tr fee 78.0748*1.25 = 97.5935EUR - // 78.0748EUR is swapped in for 101.3888USD - BEAST_EXPECT(amm2.expectBalances( - STAmount{EUR, UINT64_C(1'078'074866310162), -12}, - STAmount{USD, UINT64_C(1'298'611111111111), -12}, - amm2.tokens())); - } + // 108.1481GBP is swapped in for 97.5935EUR + BEAST_EXPECT(amm1.expectBalances( + STAmount{GBP, UINT64_C(1'108'148148148151), -12}, + STAmount{EUR, UINT64_C(902'4064171122975), -13}, + amm1.tokens())); + // 25% on 78.0748EUR is paid in tr fee 78.0748*1.25 = 97.5935EUR + // 78.0748EUR is swapped in for 101.3888USD + BEAST_EXPECT(amm2.expectBalances( + STAmount{EUR, UINT64_C(1'078'074866310162), -12}, + STAmount{USD, UINT64_C(1'298'611111111111), -12}, + amm2.tokens())); + // 25% on 81.1111USD is paid in tr fee 81.1111*1.25 = 101.3888USD BEAST_EXPECT(expectLine( env, carol, STAmount{USD, UINT64_C(1'481'111111111111), -12})); @@ -3172,12 +2935,8 @@ private: // Alice offers to buy 1000 XRP for 1000 USD. She takes Bob's first // offer, removes 999 more as unfunded, then hits the step limit. env(offer(alice, USD(1'000), XRP(1'000))); - if (!features[fixAMMv1_1]) - env.require(balance( - alice, STAmount{USD, UINT64_C(2'050126257867561), -15})); - else - env.require(balance( - alice, STAmount{USD, UINT64_C(2'050125257867587), -15})); + env.require( + balance(alice, STAmount{USD, UINT64_C(2'050125257867587), -15})); env.require(owners(alice, 2)); env.require(balance(bob, USD(0))); env.require(owners(bob, 1'001)); @@ -3283,33 +3042,19 @@ private: env(offer(bob, XRP(100), USD(100))); env(offer(bob, XRP(1'000), USD(100))); AMM ammDan(env, dan, XRP(1'000), USD(1'100)); - if (!features[fixAMMv1_1]) - { - env(pay(alice, carol, USD(10'000)), - paths(XRP), - delivermin(USD(200)), - txflags(tfPartialPayment), - sendmax(XRP(200))); - env.require(balance(bob, USD(0))); - env.require(balance(carol, USD(200))); - BEAST_EXPECT(ammDan.expectBalances( - XRP(1'100), USD(1'000), ammDan.tokens())); - } - else - { - env(pay(alice, carol, USD(10'000)), - paths(XRP), - delivermin(USD(200)), - txflags(tfPartialPayment), - sendmax(XRPAmount(200'000'001))); - env.require(balance(bob, USD(0))); - env.require(balance( - carol, STAmount{USD, UINT64_C(200'00000090909), -11})); - BEAST_EXPECT(ammDan.expectBalances( - XRPAmount{1'100'000'001}, - STAmount{USD, UINT64_C(999'99999909091), -11}, - ammDan.tokens())); - } + + env(pay(alice, carol, USD(10'000)), + paths(XRP), + delivermin(USD(200)), + txflags(tfPartialPayment), + sendmax(XRPAmount(200'000'001))); + env.require(balance(bob, USD(0))); + env.require( + balance(carol, STAmount{USD, UINT64_C(200'00000090909), -11})); + BEAST_EXPECT(ammDan.expectBalances( + XRPAmount{1'100'000'001}, + STAmount{USD, UINT64_C(999'99999909091), -11}, + ammDan.tokens())); } } @@ -4100,9 +3845,7 @@ private: testBookStep(all); testBookStep(all | ownerPaysFee); testTransferRate(all | ownerPaysFee); - testTransferRate((all - fixAMMv1_1) | ownerPaysFee); testTransferRateNoOwnerFee(all); - testTransferRateNoOwnerFee(all - fixAMMv1_1); testLimitQuality(); testXRPPathLoop(); } @@ -4113,7 +3856,6 @@ private: using namespace jtx; FeatureBitset const all{supported_amendments()}; testStepLimit(all); - testStepLimit(all - fixAMMv1_1); } void @@ -4122,7 +3864,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_1); } void diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index 518c45559..b23fc352b 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -2296,29 +2296,20 @@ private: ammAlice.deposit(carol, 1'000'000); ammAlice.withdraw( carol, USD(100), std::nullopt, IOUAmount{520, 0}); - if (!env.current()->rules().enabled(fixAMMv1_1)) - BEAST_EXPECT( - ammAlice.expectBalances( - XRPAmount(11'000'000'000), - STAmount{USD, UINT64_C(9'372'781065088757), -12}, - IOUAmount{10'153'846'15384616, -8}) && - ammAlice.expectLPTokens( - carol, IOUAmount{153'846'15384616, -8})); - else - BEAST_EXPECT( - ammAlice.expectBalances( - XRPAmount(11'000'000'000), - STAmount{USD, UINT64_C(9'372'781065088769), -12}, - IOUAmount{10'153'846'15384616, -8}) && - ammAlice.expectLPTokens( - carol, IOUAmount{153'846'15384616, -8})); + BEAST_EXPECT( + ammAlice.expectBalances( + XRPAmount(11'000'000'000), + STAmount{USD, UINT64_C(9'372'781065088769), -12}, + IOUAmount{10'153'846'15384616, -8}) && + ammAlice.expectLPTokens( + carol, IOUAmount{153'846'15384616, -8})); ammAlice.withdrawAll(carol); BEAST_EXPECT(ammAlice.expectLPTokens(carol, IOUAmount{0})); }, std::nullopt, 0, std::nullopt, - {all, all - fixAMMv1_1}); + {all}); // Withdraw with EPrice limit. AssetOut is 0. testAMM( @@ -2326,27 +2317,18 @@ private: ammAlice.deposit(carol, 1'000'000); ammAlice.withdraw( carol, USD(0), std::nullopt, IOUAmount{520, 0}); - if (!env.current()->rules().enabled(fixAMMv1_1)) - BEAST_EXPECT( - ammAlice.expectBalances( - XRPAmount(11'000'000'000), - STAmount{USD, UINT64_C(9'372'781065088757), -12}, - IOUAmount{10'153'846'15384616, -8}) && - ammAlice.expectLPTokens( - carol, IOUAmount{153'846'15384616, -8})); - else - BEAST_EXPECT( - ammAlice.expectBalances( - XRPAmount(11'000'000'000), - STAmount{USD, UINT64_C(9'372'781065088769), -12}, - IOUAmount{10'153'846'15384616, -8}) && - ammAlice.expectLPTokens( - carol, IOUAmount{153'846'15384616, -8})); + BEAST_EXPECT( + ammAlice.expectBalances( + XRPAmount(11'000'000'000), + STAmount{USD, UINT64_C(9'372'781065088769), -12}, + IOUAmount{10'153'846'15384616, -8}) && + ammAlice.expectLPTokens( + carol, IOUAmount{153'846'15384616, -8})); }, std::nullopt, 0, std::nullopt, - {all, all - fixAMMv1_1}); + {all}); // IOU to IOU + transfer fee { @@ -3009,40 +2991,21 @@ private: ammAlice.withdraw(ed, tokens, USD(0)); } // carol, bob, and ed pay ~0.99USD in fees. - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(29'499'00572620545), -11)); - BEAST_EXPECT( - env.balance(bob, USD) == - STAmount(USD, UINT64_C(18'999'00572616195), -11)); - BEAST_EXPECT( - env.balance(ed, USD) == - STAmount(USD, UINT64_C(18'999'00572611841), -11)); - // USD pool is slightly higher because of the fees. - BEAST_EXPECT(ammAlice.expectBalances( - XRP(13'000), - STAmount(USD, UINT64_C(13'002'98282151419), -11), - ammTokens)); - } - else - { - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(29'499'00572620544), -11)); - BEAST_EXPECT( - env.balance(bob, USD) == - STAmount(USD, UINT64_C(18'999'00572616194), -11)); - BEAST_EXPECT( - env.balance(ed, USD) == - STAmount(USD, UINT64_C(18'999'0057261184), -10)); - // USD pool is slightly higher because of the fees. - BEAST_EXPECT(ammAlice.expectBalances( - XRP(13'000), - STAmount(USD, UINT64_C(13'002'98282151422), -11), - ammTokens)); - } + BEAST_EXPECT( + env.balance(carol, USD) == + STAmount(USD, UINT64_C(29'499'00572620544), -11)); + BEAST_EXPECT( + env.balance(bob, USD) == + STAmount(USD, UINT64_C(18'999'00572616194), -11)); + BEAST_EXPECT( + env.balance(ed, USD) == + STAmount(USD, UINT64_C(18'999'0057261184), -10)); + // USD pool is slightly higher because of the fees. + BEAST_EXPECT(ammAlice.expectBalances( + XRP(13'000), + STAmount(USD, UINT64_C(13'002'98282151422), -11), + ammTokens)); + ammTokens = ammAlice.getLPTokensBalance(); // Trade with the fee for (int i = 0; i < 10; ++i) @@ -3053,94 +3016,48 @@ private: // dan pays ~9.94USD, which is ~10 times more in fees than // carol, bob, ed. the discounted fee is 10 times less // than the trading fee. - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT( - env.balance(dan, USD) == - STAmount(USD, UINT64_C(19'490'056722744), -9)); - // USD pool gains more in dan's fees. - BEAST_EXPECT(ammAlice.expectBalances( - XRP(13'000), - STAmount{USD, UINT64_C(13'012'92609877019), -11}, - ammTokens)); - // Discounted fee payment - ammAlice.deposit(carol, USD(100)); - ammTokens = ammAlice.getLPTokensBalance(); - BEAST_EXPECT(ammAlice.expectBalances( - XRP(13'000), - STAmount{USD, UINT64_C(13'112'92609877019), -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 - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{13'100'000'668}, - STAmount{USD, UINT64_C(13'012'92609877019), -11}, - ammTokens)); - } - else - { - BEAST_EXPECT( - env.balance(dan, USD) == - STAmount(USD, UINT64_C(19'490'05672274399), -11)); - // USD pool gains more in dan's fees. - BEAST_EXPECT(ammAlice.expectBalances( - XRP(13'000), - STAmount{USD, UINT64_C(13'012'92609877023), -11}, - ammTokens)); - // Discounted fee payment - ammAlice.deposit(carol, USD(100)); - ammTokens = ammAlice.getLPTokensBalance(); - BEAST_EXPECT(ammAlice.expectBalances( - XRP(13'000), - STAmount{USD, UINT64_C(13'112'92609877023), -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 - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{13'100'000'668}, - STAmount{USD, UINT64_C(13'012'92609877023), -11}, - ammTokens)); - } + BEAST_EXPECT( + env.balance(dan, USD) == + STAmount(USD, UINT64_C(19'490'05672274399), -11)); + // USD pool gains more in dan's fees. + BEAST_EXPECT(ammAlice.expectBalances( + XRP(13'000), + STAmount{USD, UINT64_C(13'012'92609877023), -11}, + ammTokens)); + // Discounted fee payment + ammAlice.deposit(carol, USD(100)); + ammTokens = ammAlice.getLPTokensBalance(); + BEAST_EXPECT(ammAlice.expectBalances( + XRP(13'000), + STAmount{USD, UINT64_C(13'112'92609877023), -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 + BEAST_EXPECT(ammAlice.expectBalances( + XRPAmount{13'100'000'668}, + STAmount{USD, UINT64_C(13'012'92609877023), -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_1]) - { - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{13'000'000'668}, - STAmount{USD, UINT64_C(13'114'03663047264), -11}, - ammTokens)); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{13'000'000'668}, - STAmount{USD, UINT64_C(13'114'03663047269), -11}, - ammTokens)); - } + BEAST_EXPECT(ammAlice.expectBalances( + XRPAmount{13'000'000'668}, + STAmount{USD, UINT64_C(13'114'03663047269), -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_1]) - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(29'399'00572620545), -11)); - else - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(29'399'00572620544), -11)); + BEAST_EXPECT( + env.balance(carol, USD) == + STAmount(USD, UINT64_C(29'399'00572620544), -11)); ammTokens = ammAlice.getLPTokensBalance(); for (int i = 0; i < 10; ++i) { @@ -3149,45 +3066,23 @@ private: } // carol pays ~9.94USD in fees, which is ~10 times more in // trading fees vs discounted fee. - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(29'389'06197177128), -11)); - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{13'000'000'668}, - STAmount{USD, UINT64_C(13'123'98038490681), -11}, - ammTokens)); - } - else - { - 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)); - } + 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)); + 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_1]) - { - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount(13'100'824'790), - STAmount{USD, UINT64_C(13'023'98038490681), -11}, - ammTokens)); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount(13'100'824'790), - STAmount{USD, UINT64_C(13'023'98038490689), -11}, - ammTokens)); - } + BEAST_EXPECT(ammAlice.expectBalances( + XRPAmount(13'100'824'790), + STAmount{USD, UINT64_C(13'023'98038490689), -11}, + ammTokens)); }, std::nullopt, 1'000, @@ -3276,20 +3171,10 @@ private: IOUAmount{1'004'487'562112089, -9})); // Bob pays the full fee ~0.1USD env(pay(bob, alice, XRP(10)), path(~XRP), sendmax(USD(11))); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(amm.expectBalances( - XRPAmount{1'000'010'011}, - STAmount{USD, UINT64_C(1'010'10090898081), -11}, - IOUAmount{1'004'487'562112089, -9})); - } - else - { - BEAST_EXPECT(amm.expectBalances( - XRPAmount{1'000'010'011}, - STAmount{USD, UINT64_C(1'010'100908980811), -12}, - IOUAmount{1'004'487'562112089, -9})); - } + BEAST_EXPECT(amm.expectBalances( + XRPAmount{1'000'010'011}, + STAmount{USD, UINT64_C(1'010'100908980811), -12}, + IOUAmount{1'004'487'562112089, -9})); } // preflight tests @@ -3685,40 +3570,22 @@ private: XRPAmount(10'030'082'730), STAmount(EUR, UINT64_C(9'970'007498125468), -12), ammEUR_XRP.tokens())); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammUSD_EUR.expectBalances( - STAmount(USD, UINT64_C(9'970'097277662122), -12), - STAmount(EUR, UINT64_C(10'029'99250187452), -11), - ammUSD_EUR.tokens())); - // fixReducedOffersV2 changes the expected results slightly. - Amounts const expectedAmounts = - env.closed()->rules().enabled(fixReducedOffersV2) - ? Amounts{XRPAmount(30'201'749), STAmount(USD, UINT64_C(29'90272233787816), -14)} - : Amounts{ - XRPAmount(30'201'749), - STAmount(USD, UINT64_C(29'90272233787818), -14)}; + BEAST_EXPECT(ammUSD_EUR.expectBalances( + STAmount(USD, UINT64_C(9'970'097277662172), -12), + STAmount(EUR, UINT64_C(10'029'99250187452), -11), + ammUSD_EUR.tokens())); - BEAST_EXPECT(expectOffers(env, alice, 1, {{expectedAmounts}})); - } - else - { - BEAST_EXPECT(ammUSD_EUR.expectBalances( - STAmount(USD, UINT64_C(9'970'097277662172), -12), - STAmount(EUR, UINT64_C(10'029'99250187452), -11), - ammUSD_EUR.tokens())); + // fixReducedOffersV2 changes the expected results slightly. + Amounts const expectedAmounts = + env.closed()->rules().enabled(fixReducedOffersV2) + ? Amounts{XRPAmount(30'201'749), STAmount(USD, UINT64_C(29'90272233782839), -14)} + : Amounts{ + XRPAmount(30'201'749), + STAmount(USD, UINT64_C(29'90272233782840), -14)}; - // fixReducedOffersV2 changes the expected results slightly. - Amounts const expectedAmounts = - env.closed()->rules().enabled(fixReducedOffersV2) - ? Amounts{XRPAmount(30'201'749), STAmount(USD, UINT64_C(29'90272233782839), -14)} - : Amounts{ - XRPAmount(30'201'749), - STAmount(USD, UINT64_C(29'90272233782840), -14)}; + BEAST_EXPECT(expectOffers(env, alice, 1, {{expectedAmounts}})); - BEAST_EXPECT(expectOffers(env, alice, 1, {{expectedAmounts}})); - } // Initial 30,000 + 100 BEAST_EXPECT(expectLine(env, carol, STAmount{USD, 30'100})); // Initial 1,000 - 30082730(AMM pool) - 70798251(offer) - 10(tx fee) @@ -3792,24 +3659,16 @@ private: sendmax(XRP(200)), txflags(tfPartialPayment)); env.close(); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammAlice.expectBalances( - XRP(10'100), USD(10'000), ammAlice.tokens())); - // Initial 30,000 + 200 - BEAST_EXPECT(expectLine(env, carol, USD(30'200))); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - XRP(10'100), - STAmount(USD, UINT64_C(10'000'00000000001), -11), - ammAlice.tokens())); - BEAST_EXPECT(expectLine( - env, - carol, - STAmount(USD, UINT64_C(30'199'99999999999), -11))); - } + + BEAST_EXPECT(ammAlice.expectBalances( + XRP(10'100), + STAmount(USD, UINT64_C(10'000'00000000001), -11), + ammAlice.tokens())); + BEAST_EXPECT(expectLine( + env, + carol, + STAmount(USD, UINT64_C(30'199'99999999999), -11))); + // Initial 30,000 - 10000(AMM pool LP) - 100(AMM offer) - // - 100(offer) - 10(tx fee) - one reserve BEAST_EXPECT(expectLedgerEntryRoot( @@ -3894,46 +3753,29 @@ private: env.close(); env(offer(carol, XRP(100), USD(55))); env.close(); - if (!features[fixAMMv1_1]) - { - // Pre-amendment the transfer fee is not taken into - // account when calculating the limit out based on - // limitQuality. Carol pays 0.1% on the takerGets, which - // lowers the overall quality. AMM offer is generated based - // on higher limit out, which generates a larger offer - // with lower quality. Consequently, the offer fails - // to cross. - BEAST_EXPECT( - amm.expectBalances(XRP(1'000), USD(500), amm.tokens())); - BEAST_EXPECT(expectOffers( - env, carol, 1, {{Amounts{XRP(100), USD(55)}}})); - } - else - { - // Post-amendment the transfer fee is taken into account - // when calculating the limit out based on limitQuality. - // This increases the limitQuality and decreases - // the limit out. Consequently, AMM offer size is decreased, - // and the quality is increased, matching the overall - // quality. - // AMM offer ~50USD/91XRP - BEAST_EXPECT(amm.expectBalances( - XRPAmount(909'090'909), - STAmount{USD, UINT64_C(550'000000055), -9}, - amm.tokens())); - // Offer ~91XRP/49.99USD - BEAST_EXPECT(expectOffers( - env, - carol, - 1, - {{Amounts{ - XRPAmount{9'090'909}, - STAmount{USD, 4'99999995, -8}}}})); - // Carol pays 0.1% fee on ~50USD =~ 0.05USD - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(29'949'94999999494), -11)); - } + // Post-amendment the transfer fee is taken into account + // when calculating the limit out based on limitQuality. + // This increases the limitQuality and decreases + // the limit out. Consequently, AMM offer size is decreased, + // and the quality is increased, matching the overall + // quality. + // AMM offer ~50USD/91XRP + BEAST_EXPECT(amm.expectBalances( + XRPAmount(909'090'909), + STAmount{USD, UINT64_C(550'000000055), -9}, + amm.tokens())); + // Offer ~91XRP/49.99USD + BEAST_EXPECT(expectOffers( + env, + carol, + 1, + {{Amounts{ + XRPAmount{9'090'909}, + STAmount{USD, 4'99999995, -8}}}})); + // Carol pays 0.1% fee on ~50USD =~ 0.05USD + BEAST_EXPECT( + env.balance(carol, USD) == + STAmount(USD, UINT64_C(29'949'94999999494), -11)); }, {{XRP(1'000), USD(500)}}, 0, @@ -3945,22 +3787,11 @@ private: env.close(); env(offer(carol, XRP(10), USD(5.5))); env.close(); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(amm.expectBalances( - XRP(990), - STAmount{USD, UINT64_C(505'050505050505), -12}, - amm.tokens())); - BEAST_EXPECT(expectOffers(env, carol, 0)); - } - else - { - BEAST_EXPECT(amm.expectBalances( - XRP(990), - STAmount{USD, UINT64_C(505'0505050505051), -13}, - amm.tokens())); - BEAST_EXPECT(expectOffers(env, carol, 0)); - } + BEAST_EXPECT(amm.expectBalances( + XRP(990), + STAmount{USD, UINT64_C(505'0505050505051), -13}, + amm.tokens())); + BEAST_EXPECT(expectOffers(env, carol, 0)); }, {{XRP(1'000), USD(500)}}, 0, @@ -3990,83 +3821,44 @@ private: env.close(); env(offer(carol, EUR(100), GBP(100))); env.close(); - if (!features[fixAMMv1_1]) - { - // After the auto-bridge offers are consumed, single path - // AMM offer is generated with the limit out not taking - // into consideration the transfer fee. This results - // in an overall lower quality offer than the limit quality - // and the single path AMM offer fails to consume. - // Total consumed ~37.06GBP/39.32EUR - BEAST_EXPECT(ammAlice.expectBalances( - STAmount{GBP, UINT64_C(1'037'06583722133), -11}, - STAmount{EUR, UINT64_C(1'060'684828792831), -12}, - ammAlice.tokens())); - // Consumed offer ~49.32EUR/49.32GBP - BEAST_EXPECT(expectOffers( - env, - carol, - 1, - {Amounts{ - STAmount{EUR, UINT64_C(50'684828792831), -12}, - STAmount{GBP, UINT64_C(50'684828792831), -12}}})); - BEAST_EXPECT(expectOffers(env, bob, 0)); - BEAST_EXPECT(expectOffers(env, ed, 0)); - // Initial 30,000 - ~47.06(offers = 37.06(AMM) + 10(LOB)) - // * 1.25 - // = 58.825 = ~29941.17 - // carol bought ~72.93EUR at the cost of ~70.68GBP - // the offer is partially consumed - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{GBP, UINT64_C(29'941'16770347333), -11})); - // Initial 30,000 + ~49.3(offers = 39.3(AMM) + 10(LOB)) - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{EUR, UINT64_C(30'049'31517120716), -11})); - } - else - { - // After the auto-bridge offers are consumed, single path - // AMM offer is generated with the limit out taking - // into consideration the transfer fee. This results - // in an overall quality offer matching the limit quality - // and the single path AMM offer is consumed. More - // liquidity is consumed overall in post-amendment. - // Total consumed ~60.68GBP/62.93EUR - BEAST_EXPECT(ammAlice.expectBalances( - STAmount{GBP, UINT64_C(1'060'684828792832), -12}, - STAmount{EUR, UINT64_C(1'037'06583722134), -11}, - ammAlice.tokens())); - // Consumed offer ~72.93EUR/72.93GBP - BEAST_EXPECT(expectOffers( - env, - carol, - 1, - {Amounts{ - STAmount{EUR, UINT64_C(27'06583722134028), -14}, - STAmount{GBP, UINT64_C(27'06583722134028), -14}}})); - BEAST_EXPECT(expectOffers(env, bob, 0)); - BEAST_EXPECT(expectOffers(env, ed, 0)); + // After the auto-bridge offers are consumed, single path + // AMM offer is generated with the limit out taking + // into consideration the transfer fee. This results + // in an overall quality offer matching the limit quality + // and the single path AMM offer is consumed. More + // liquidity is consumed overall in post-amendment. + // Total consumed ~60.68GBP/62.93EUR + BEAST_EXPECT(ammAlice.expectBalances( + STAmount{GBP, UINT64_C(1'060'684828792832), -12}, + STAmount{EUR, UINT64_C(1'037'06583722134), -11}, + ammAlice.tokens())); + // Consumed offer ~72.93EUR/72.93GBP + BEAST_EXPECT(expectOffers( + env, + carol, + 1, + {Amounts{ + STAmount{EUR, UINT64_C(27'06583722134028), -14}, + STAmount{GBP, UINT64_C(27'06583722134028), -14}}})); + BEAST_EXPECT(expectOffers(env, bob, 0)); + BEAST_EXPECT(expectOffers(env, ed, 0)); + + // Initial 30,000 - ~70.68(offers = 60.68(AMM) + 10(LOB)) + // * 1.25 + // = 88.35 = ~29911.64 + // carol bought ~72.93EUR at the cost of ~70.68GBP + // the offer is partially consumed + BEAST_EXPECT(expectLine( + env, + carol, + STAmount{GBP, UINT64_C(29'911'64396400896), -11})); + // Initial 30,000 + ~72.93(offers = 62.93(AMM) + 10(LOB)) + BEAST_EXPECT(expectLine( + env, + carol, + STAmount{EUR, UINT64_C(30'072'93416277865), -11})); - // Initial 30,000 - ~70.68(offers = 60.68(AMM) + 10(LOB)) - // * 1.25 - // = 88.35 = ~29911.64 - // carol bought ~72.93EUR at the cost of ~70.68GBP - // the offer is partially consumed - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{GBP, UINT64_C(29'911'64396400896), -11})); - // Initial 30,000 + ~72.93(offers = 62.93(AMM) + 10(LOB)) - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{EUR, UINT64_C(30'072'93416277865), -11})); - } // Initial 2000 + 10 = 2010 BEAST_EXPECT(expectLine(env, bob, GBP(2'010))); // Initial 2000 - 10 * 1.25 = 1987.5 @@ -4198,50 +3990,25 @@ private: path(~USD), path(~ETH, ~EUR, ~USD), sendmax(XRP(200))); - if (!features[fixAMMv1_1]) - { - // XRP-ETH-EUR-USD - // This path provides ~26.06USD/26.2XRP - BEAST_EXPECT(xrp_eth.expectBalances( - XRPAmount(10'026'208'900), - STAmount{ETH, UINT64_C(10'073'65779244494), -11}, - xrp_eth.tokens())); - BEAST_EXPECT(eth_eur.expectBalances( - STAmount{ETH, UINT64_C(10'926'34220755506), -11}, - STAmount{EUR, UINT64_C(10'973'54232078752), -11}, - eth_eur.tokens())); - BEAST_EXPECT(eur_usd.expectBalances( - STAmount{EUR, UINT64_C(10'126'45767921248), -11}, - STAmount{USD, UINT64_C(9'973'93151712086), -11}, - eur_usd.tokens())); - // XRP-USD path - // This path provides ~73.9USD/74.1XRP - BEAST_EXPECT(xrp_usd.expectBalances( - XRPAmount(10'224'106'246), - STAmount{USD, UINT64_C(10'126'06848287914), -11}, - xrp_usd.tokens())); - } - else - { - BEAST_EXPECT(xrp_eth.expectBalances( - XRPAmount(10'026'208'900), - STAmount{ETH, UINT64_C(10'073'65779244461), -11}, - xrp_eth.tokens())); - BEAST_EXPECT(eth_eur.expectBalances( - STAmount{ETH, UINT64_C(10'926'34220755539), -11}, - STAmount{EUR, UINT64_C(10'973'5423207872), -10}, - eth_eur.tokens())); - BEAST_EXPECT(eur_usd.expectBalances( - STAmount{EUR, UINT64_C(10'126'4576792128), -10}, - STAmount{USD, UINT64_C(9'973'93151712057), -11}, - eur_usd.tokens())); - // XRP-USD path - // This path provides ~73.9USD/74.1XRP - BEAST_EXPECT(xrp_usd.expectBalances( - XRPAmount(10'224'106'246), - STAmount{USD, UINT64_C(10'126'06848287943), -11}, - xrp_usd.tokens())); - } + + BEAST_EXPECT(xrp_eth.expectBalances( + XRPAmount(10'026'208'900), + STAmount{ETH, UINT64_C(10'073'65779244461), -11}, + xrp_eth.tokens())); + BEAST_EXPECT(eth_eur.expectBalances( + STAmount{ETH, UINT64_C(10'926'34220755539), -11}, + STAmount{EUR, UINT64_C(10'973'5423207872), -10}, + eth_eur.tokens())); + BEAST_EXPECT(eur_usd.expectBalances( + STAmount{EUR, UINT64_C(10'126'4576792128), -10}, + STAmount{USD, UINT64_C(9'973'93151712057), -11}, + eur_usd.tokens())); + // XRP-USD path + // This path provides ~73.9USD/74.1XRP + BEAST_EXPECT(xrp_usd.expectBalances( + XRPAmount(10'224'106'246), + STAmount{USD, UINT64_C(10'126'06848287943), -11}, + xrp_usd.tokens())); // XRP-EUR-BTC-USD // This path doesn't provide any liquidity due to how @@ -4279,54 +4046,27 @@ private: path(~EUR, ~BTC, ~USD), path(~ETH, ~EUR, ~BTC, ~USD), sendmax(XRP(200))); - if (!features[fixAMMv1_1]) - { - // XRP-EUR-BTC-USD path provides ~17.8USD/~18.7XRP - // XRP-ETH-EUR-BTC-USD path provides ~82.2USD/82.4XRP - BEAST_EXPECT(xrp_eur.expectBalances( - XRPAmount(10'118'738'472), - STAmount{EUR, UINT64_C(9'981'544436337968), -12}, - xrp_eur.tokens())); - BEAST_EXPECT(eur_btc.expectBalances( - STAmount{EUR, UINT64_C(10'101'16096785173), -11}, - STAmount{BTC, UINT64_C(10'097'91426968066), -11}, - eur_btc.tokens())); - BEAST_EXPECT(btc_usd.expectBalances( - STAmount{BTC, UINT64_C(10'202'08573031934), -11}, - USD(9'900), - btc_usd.tokens())); - BEAST_EXPECT(xrp_eth.expectBalances( - XRPAmount(10'082'446'397), - STAmount{ETH, UINT64_C(10'017'41072778012), -11}, - xrp_eth.tokens())); - BEAST_EXPECT(eth_eur.expectBalances( - STAmount{ETH, UINT64_C(10'982'58927221988), -11}, - STAmount{EUR, UINT64_C(10'917'2945958103), -10}, - eth_eur.tokens())); - } - else - { - BEAST_EXPECT(xrp_eur.expectBalances( - XRPAmount(10'118'738'472), - STAmount{EUR, UINT64_C(9'981'544436337923), -12}, - xrp_eur.tokens())); - BEAST_EXPECT(eur_btc.expectBalances( - STAmount{EUR, UINT64_C(10'101'16096785188), -11}, - STAmount{BTC, UINT64_C(10'097'91426968059), -11}, - eur_btc.tokens())); - BEAST_EXPECT(btc_usd.expectBalances( - STAmount{BTC, UINT64_C(10'202'08573031941), -11}, - USD(9'900), - btc_usd.tokens())); - BEAST_EXPECT(xrp_eth.expectBalances( - XRPAmount(10'082'446'397), - STAmount{ETH, UINT64_C(10'017'41072777996), -11}, - xrp_eth.tokens())); - BEAST_EXPECT(eth_eur.expectBalances( - STAmount{ETH, UINT64_C(10'982'58927222004), -11}, - STAmount{EUR, UINT64_C(10'917'2945958102), -10}, - eth_eur.tokens())); - } + + BEAST_EXPECT(xrp_eur.expectBalances( + XRPAmount(10'118'738'472), + STAmount{EUR, UINT64_C(9'981'544436337923), -12}, + xrp_eur.tokens())); + BEAST_EXPECT(eur_btc.expectBalances( + STAmount{EUR, UINT64_C(10'101'16096785188), -11}, + STAmount{BTC, UINT64_C(10'097'91426968059), -11}, + eur_btc.tokens())); + BEAST_EXPECT(btc_usd.expectBalances( + STAmount{BTC, UINT64_C(10'202'08573031941), -11}, + USD(9'900), + btc_usd.tokens())); + BEAST_EXPECT(xrp_eth.expectBalances( + XRPAmount(10'082'446'397), + STAmount{ETH, UINT64_C(10'017'41072777996), -11}, + xrp_eth.tokens())); + BEAST_EXPECT(eth_eur.expectBalances( + STAmount{ETH, UINT64_C(10'982'58927222004), -11}, + STAmount{EUR, UINT64_C(10'917'2945958102), -10}, + eth_eur.tokens())); BEAST_EXPECT(expectLine(env, carol, USD(300))); } @@ -4346,29 +4086,15 @@ private: path(~XRP, ~USD), sendmax(EUR(400)), txflags(tfPartialPayment | tfNoRippleDirect)); - if (!features[fixAMMv1_1]) - { - // Carol gets ~29.91USD because of the AMM offers limit - BEAST_EXPECT(ammAlice.expectBalances( - XRP(10'030), - STAmount{USD, UINT64_C(9'970'089730807577), -12}, - ammAlice.tokens())); - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{USD, UINT64_C(30'029'91026919241), -11})); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - XRP(10'030), - STAmount{USD, UINT64_C(9'970'089730807827), -12}, - ammAlice.tokens())); - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{USD, UINT64_C(30'029'91026919217), -11})); - } + + BEAST_EXPECT(ammAlice.expectBalances( + XRP(10'030), + STAmount{USD, UINT64_C(9'970'089730807827), -12}, + ammAlice.tokens())); + BEAST_EXPECT(expectLine( + env, + carol, + STAmount{USD, UINT64_C(30'029'91026919217), -11})); BEAST_EXPECT( expectOffers(env, alice, 1, {{{EUR(140), XRP(100)}}})); }, @@ -4393,18 +4119,7 @@ private: txflags(tfPartialPayment | tfNoRippleDirect)); BEAST_EXPECT(ammAlice.expectBalances( XRPAmount{10'101'010'102}, USD(9'900), ammAlice.tokens())); - if (!features[fixAMMv1_1]) - { - // Carol gets ~100USD - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{USD, UINT64_C(30'099'99999999999), -11})); - } - else - { - BEAST_EXPECT(expectLine(env, carol, USD(30'100))); - } + BEAST_EXPECT(expectLine(env, carol, USD(30'100))); BEAST_EXPECT(expectOffers( env, alice, @@ -4425,33 +4140,18 @@ private: env(offer(bob, XRP(100), USD(100.001))); AMM ammAlice(env, alice, XRP(10'000), USD(10'100)); env(offer(carol, USD(100), XRP(100))); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{10'049'825'373}, - STAmount{USD, UINT64_C(10'049'92586949302), -11}, - ammAlice.tokens())); - BEAST_EXPECT(expectOffers( - env, - bob, - 1, - {{{XRPAmount{50'074'629}, - STAmount{USD, UINT64_C(50'07513050698), -11}}}})); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - XRPAmount{10'049'825'372}, - STAmount{USD, UINT64_C(10'049'92587049303), -11}, - ammAlice.tokens())); - BEAST_EXPECT(expectOffers( - env, - bob, - 1, - {{{XRPAmount{50'074'628}, - STAmount{USD, UINT64_C(50'07512950697), -11}}}})); - BEAST_EXPECT(expectLine(env, carol, USD(30'100))); - } + + BEAST_EXPECT(ammAlice.expectBalances( + XRPAmount{10'049'825'372}, + STAmount{USD, UINT64_C(10'049'92587049303), -11}, + ammAlice.tokens())); + BEAST_EXPECT(expectOffers( + env, + bob, + 1, + {{{XRPAmount{50'074'628}, + STAmount{USD, UINT64_C(50'07512950697), -11}}}})); + BEAST_EXPECT(expectLine(env, carol, USD(30'100))); } // Individually frozen account @@ -4723,18 +4423,11 @@ private: // Execute with CLOB offer prep( [&](Env& env) { - if (!features[fixAMMv1_1]) - env(offer( - LP1, - XRPAmount{18'095'133}, - STAmount{TST, UINT64_C(1'68737984885388), -14}), - txflags(tfPassive)); - else - env(offer( - LP1, - XRPAmount{18'095'132}, - STAmount{TST, UINT64_C(1'68737976189735), -14}), - txflags(tfPassive)); + env(offer( + LP1, + XRPAmount{18'095'132}, + STAmount{TST, UINT64_C(1'68737976189735), -14}), + txflags(tfPassive)); }, [&](Env& env) { BEAST_EXPECT( @@ -4861,8 +4554,6 @@ private: carol, USD(100), std::nullopt, IOUAmount{520, 0}); // carol withdraws ~1,443.44USD auto const balanceAfterWithdraw = [&]() { - if (!features[fixAMMv1_1]) - return STAmount(USD, UINT64_C(30'443'43891402715), -11); return STAmount(USD, UINT64_C(30'443'43891402714), -11); }(); BEAST_EXPECT(env.balance(carol, USD) == balanceAfterWithdraw); @@ -4873,22 +4564,12 @@ private: ammAlice.vote(alice, 0); BEAST_EXPECT(ammAlice.expectTradingFee(0)); auto const tokensNoFee = ammAlice.withdraw(carol, deposit); - if (!features[fixAMMv1_1]) - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(30'443'43891402717), -11)); - else - BEAST_EXPECT( - env.balance(carol, USD) == - STAmount(USD, UINT64_C(30'443'43891402716), -11)); + BEAST_EXPECT( + env.balance(carol, USD) == + STAmount(USD, UINT64_C(30'443'43891402716), -11)); // carol pays ~4008 LPTokens in fees or ~0.5% of the no-fee // LPTokens - if (!features[fixAMMv1_1]) - BEAST_EXPECT( - tokensNoFee == IOUAmount(746'579'80779913, -8)); - else - BEAST_EXPECT( - tokensNoFee == IOUAmount(746'579'80779912, -8)); + BEAST_EXPECT(tokensNoFee == IOUAmount(746'579'80779912, -8)); BEAST_EXPECT(tokensFee == IOUAmount(750'588'23529411, -8)); }, std::nullopt, @@ -4978,20 +4659,10 @@ private: {{Amounts{ STAmount{EUR, UINT64_C(5'025125628140703), -15}, STAmount{USD, UINT64_C(5'025125628140703), -15}}}})); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(ammAlice.expectBalances( - STAmount{USD, UINT64_C(1'004'974874371859), -12}, - STAmount{EUR, UINT64_C(1'005'025125628141), -12}, - ammAlice.tokens())); - } - else - { - BEAST_EXPECT(ammAlice.expectBalances( - STAmount{USD, UINT64_C(1'004'97487437186), -11}, - STAmount{EUR, UINT64_C(1'005'025125628141), -12}, - ammAlice.tokens())); - } + BEAST_EXPECT(ammAlice.expectBalances( + STAmount{USD, UINT64_C(1'004'97487437186), -11}, + STAmount{EUR, UINT64_C(1'005'025125628141), -12}, + ammAlice.tokens())); }, {{USD(1'000), EUR(1'010)}}, 0, @@ -5018,21 +4689,12 @@ private: sendmax(EUR(15)), txflags(tfNoRippleDirect)); BEAST_EXPECT(expectLine(env, ed, USD(2'010))); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(expectLine(env, bob, EUR(1'990))); - BEAST_EXPECT(ammAlice.expectBalances( - USD(1'000), EUR(1'005), ammAlice.tokens())); - } - else - { - BEAST_EXPECT(expectLine( - env, bob, STAmount(EUR, UINT64_C(1989'999999999999), -12))); - BEAST_EXPECT(ammAlice.expectBalances( - USD(1'000), - STAmount(EUR, UINT64_C(1005'000000000001), -12), - ammAlice.tokens())); - } + BEAST_EXPECT(expectLine( + env, bob, STAmount(EUR, UINT64_C(1989'999999999999), -12))); + BEAST_EXPECT(ammAlice.expectBalances( + USD(1'000), + STAmount(EUR, UINT64_C(1005'000000000001), -12), + ammAlice.tokens())); BEAST_EXPECT(expectOffers(env, carol, 0)); } @@ -5055,28 +4717,12 @@ private: sendmax(EUR(15)), txflags(tfNoRippleDirect)); BEAST_EXPECT(expectLine(env, ed, USD(2'010))); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(expectLine( - env, - bob, - STAmount{EUR, UINT64_C(1'989'987453007618), -12})); - BEAST_EXPECT(ammAlice.expectBalances( - USD(1'000), - STAmount{EUR, UINT64_C(1'005'012546992382), -12}, - ammAlice.tokens())); - } - else - { - BEAST_EXPECT(expectLine( - env, - bob, - STAmount{EUR, UINT64_C(1'989'987453007628), -12})); - BEAST_EXPECT(ammAlice.expectBalances( - USD(1'000), - STAmount{EUR, UINT64_C(1'005'012546992372), -12}, - ammAlice.tokens())); - } + BEAST_EXPECT(expectLine( + env, bob, STAmount{EUR, UINT64_C(1'989'987453007628), -12})); + BEAST_EXPECT(ammAlice.expectBalances( + USD(1'000), + STAmount{EUR, UINT64_C(1'005'012546992372), -12}, + ammAlice.tokens())); BEAST_EXPECT(expectOffers(env, carol, 0)); } @@ -5185,46 +4831,22 @@ 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_1]) - BEAST_EXPECT(ammAlice.expectBalances( - XRP(10'000), - STAmount{USD, UINT64_C(10'000'0000000013), -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), USD(10'000), 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_1]) - BEAST_EXPECT(expectLine( - env, - carol, - STAmount{USD, UINT64_C(30'000'00000000001), -11})); - 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_1]) - BEAST_EXPECT(expectLine( - env, - nataly, - STAmount{USD, UINT64_C(1'500'000'000000002), -9})); - else - BEAST_EXPECT(expectLine( - env, - nataly, - STAmount{USD, UINT64_C(1'500'000'000000005), -9})); + BEAST_EXPECT(expectLine( + env, + nataly, + STAmount{USD, UINT64_C(1'500'000'000000005), -9})); ammAlice.withdrawAll(alice); BEAST_EXPECT(!ammAlice.ammExists()); - if (!features[fixAMMv1_1]) - BEAST_EXPECT(expectLine( - env, - alice, - STAmount{USD, UINT64_C(30'000'0000000013), -10})); - else - BEAST_EXPECT(expectLine(env, alice, USD(30'000))); + BEAST_EXPECT(expectLine(env, alice, USD(30'000))); // alice XRP balance is 30,000initial - 50 ammcreate fee - // 10drops fee BEAST_EXPECT(accountBalance(env, alice) == "29949999990"); @@ -5613,71 +5235,6 @@ private: BEAST_EXPECT(!amm->expectBalances( USD(1'000), ETH(1'000), amm->tokens())); } - if (i == 2 && !features[fixAMMv1_1]) - { - if (rates.first == 1.5) - { - if (!features[fixAMMv1_1]) - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, - UINT64_C(378'6327949540823), - -13}, - STAmount{ - USD, - UINT64_C(283'9745962155617), - -13}}}})); - else - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, - UINT64_C(378'6327949540813), - -13}, - STAmount{ - USD, - UINT64_C(283'974596215561), - -12}}}})); - } - else - { - if (!features[fixAMMv1_1]) - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, - UINT64_C(325'299461620749), - -12}, - STAmount{ - USD, - UINT64_C(243'9745962155617), - -13}}}})); - else - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, - UINT64_C(325'299461620748), - -12}, - STAmount{ - USD, - UINT64_C(243'974596215561), - -12}}}})); - } - } else if (i == 2) { if (rates.first == 1.5) @@ -5747,71 +5304,31 @@ private: { if (rates.first == 1.5) { - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(expectOffers( - env, ed, 1, {{Amounts{ETH(400), USD(250)}}})); - BEAST_EXPECT(expectOffers( - env, - alice, - 1, - {{Amounts{ - STAmount{ - USD, UINT64_C(40'5694150420947), -13}, - STAmount{ - ETH, UINT64_C(64'91106406735152), -14}, - }}})); - } - else - { - // Ed offer is partially crossed. - // The updated rounding makes limitQuality - // work if both amendments are enabled - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, UINT64_C(335'0889359326475), -13}, - STAmount{ - USD, UINT64_C(209'4305849579047), -13}, - }}})); - BEAST_EXPECT(expectOffers(env, alice, 0)); - } + // Ed offer is partially crossed. + // The updated rounding makes limitQuality + // work if both amendments are enabled + BEAST_EXPECT(expectOffers( + env, + ed, + 1, + {{Amounts{ + STAmount{ETH, UINT64_C(335'0889359326475), -13}, + STAmount{USD, UINT64_C(209'4305849579047), -13}, + }}})); + BEAST_EXPECT(expectOffers(env, alice, 0)); } else { - if (!features[fixAMMv1_1]) - { - // Ed offer is partially crossed. - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, UINT64_C(335'0889359326485), -13}, - STAmount{ - USD, UINT64_C(209'4305849579053), -13}, - }}})); - BEAST_EXPECT(expectOffers(env, alice, 0)); - } - else - { - // Ed offer is partially crossed. - BEAST_EXPECT(expectOffers( - env, - ed, - 1, - {{Amounts{ - STAmount{ - ETH, UINT64_C(335'0889359326475), -13}, - STAmount{ - USD, UINT64_C(209'4305849579047), -13}, - }}})); - BEAST_EXPECT(expectOffers(env, alice, 0)); - } + // Ed offer is partially crossed. + BEAST_EXPECT(expectOffers( + env, + ed, + 1, + {{Amounts{ + STAmount{ETH, UINT64_C(335'0889359326475), -13}, + STAmount{USD, UINT64_C(209'4305849579047), -13}, + }}})); + BEAST_EXPECT(expectOffers(env, alice, 0)); } } } @@ -5857,51 +5374,7 @@ private: env.close(); BEAST_EXPECT(expectLine(env, bob, USD(2'100))); - - if (i == 2 && !features[fixAMMv1_1]) - { - if (rates.first == 1.5) - { - // Liquidity is consumed from AMM strand only - BEAST_EXPECT(amm->expectBalances( - STAmount{ETH, UINT64_C(1'176'66038955758), -11}, - USD(850), - amm->tokens())); - } - else - { - BEAST_EXPECT(amm->expectBalances( - STAmount{ - ETH, UINT64_C(1'179'540094339627), -12}, - STAmount{USD, UINT64_C(847'7880529867501), -13}, - amm->tokens())); - BEAST_EXPECT(expectOffers( - env, - ed, - 2, - {{Amounts{ - STAmount{ - ETH, - UINT64_C(343'3179205198749), - -13}, - STAmount{ - CAN, - UINT64_C(343'3179205198749), - -13}, - }, - Amounts{ - STAmount{ - CAN, - UINT64_C(362'2119470132499), - -13}, - STAmount{ - USD, - UINT64_C(362'2119470132499), - -13}, - }}})); - } - } - else if (i == 2) + if (i == 2) { if (rates.first == 1.5) { @@ -5969,7 +5442,12 @@ private: std::uint16_t tfee, bool closeLedger, std::optional extra = std::nullopt) { - Env env(*this, features); + Env env( + *this, + envconfig(), + features, + nullptr, + beast::severities::kDisabled); fund(env, gw, {alice}, XRP(1'000), {USD(10)}); AMM amm( env, @@ -6142,7 +5620,12 @@ private: boost::smatch match; // tests that succeed should have the same amounts pre-fix and post-fix std::vector> successAmounts; - Env env(*this, features); + Env env( + *this, + envconfig(), + features, + nullptr, + beast::severities::kDisabled); auto rules = env.current()->rules(); CurrentTransactionRulesGuard rg(rules); for (auto const& t : tests) @@ -6174,34 +5657,19 @@ private: { if (status == SucceedShouldSucceedResize) { - if (!features[fixAMMv1_1]) - BEAST_EXPECT(Quality{*amounts} < quality); - else - BEAST_EXPECT(Quality{*amounts} >= quality); + BEAST_EXPECT(Quality{*amounts} >= quality); } else if (status == Succeed) { - if (!features[fixAMMv1_1]) - BEAST_EXPECT( - Quality{*amounts} >= quality || - withinRelativeDistance( - Quality{*amounts}, quality, Number{1, -7})); - else - BEAST_EXPECT(Quality{*amounts} >= quality); + BEAST_EXPECT(Quality{*amounts} >= quality); } else if (status == FailShouldSucceed) { - BEAST_EXPECT( - features[fixAMMv1_1] && - Quality{*amounts} >= quality); + BEAST_EXPECT(Quality{*amounts} >= quality); } else if (status == SucceedShouldFail) { - BEAST_EXPECT( - !features[fixAMMv1_1] && - Quality{*amounts} < quality && - withinRelativeDistance( - Quality{*amounts}, quality, Number{1, -7})); + BEAST_EXPECT(false); } } else @@ -6244,11 +5712,11 @@ private: } else if (status == FailShouldSucceed) { - BEAST_EXPECT(!features[fixAMMv1_1]); + BEAST_EXPECT(false); } else if (status == SucceedShouldFail) { - BEAST_EXPECT(features[fixAMMv1_1]); + BEAST_EXPECT(true); } } } @@ -6256,8 +5724,7 @@ private: { BEAST_EXPECT( !strcmp(e.what(), "changeSpotPriceQuality failed")); - BEAST_EXPECT( - !features[fixAMMv1_1] && status == FailShouldSucceed); + BEAST_EXPECT(false); } } @@ -6561,94 +6028,72 @@ private: }) { testcase(input.testCase); - for (auto const& features : - {all - fixAMMOverflowOffer, all | fixAMMOverflowOffer}) - { - Env env(*this, features); - env.fund(XRP(5'000), gatehub, bitstamp, trader); - env.close(); + Env env( + *this, envconfig(), all, nullptr, beast::severities::kDisabled); - if (input.rateGH != 0.0) - env(rate(gatehub, input.rateGH)); - if (input.rateBIT != 0.0) - env(rate(bitstamp, input.rateBIT)); + env.fund(XRP(5'000), gatehub, bitstamp, trader); + env.close(); - env(trust(trader, usdGH(10'000'000))); - env(trust(trader, usdBIT(10'000'000))); - env(trust(trader, btcGH(10'000'000))); - env.close(); + if (input.rateGH != 0.0) + env(rate(gatehub, input.rateGH)); + if (input.rateBIT != 0.0) + env(rate(bitstamp, input.rateBIT)); - env(pay(gatehub, trader, usdGH(100'000))); - env(pay(gatehub, trader, btcGH(100'000))); - env(pay(bitstamp, trader, usdBIT(100'000))); - env.close(); + env(trust(trader, usdGH(10'000'000))); + env(trust(trader, usdBIT(10'000'000))); + env(trust(trader, btcGH(10'000'000))); + env.close(); - AMM amm{ - env, - trader, - usdGH(input.poolUsdGH), - usdBIT(input.poolUsdBIT)}; - env.close(); + env(pay(gatehub, trader, usdGH(100'000))); + env(pay(gatehub, trader, btcGH(100'000))); + env(pay(bitstamp, trader, usdBIT(100'000))); + env.close(); - IOUAmount const preSwapLPTokenBalance = - amm.getLPTokensBalance(); + AMM amm{ + env, trader, usdGH(input.poolUsdGH), usdBIT(input.poolUsdBIT)}; + env.close(); - env(offer(trader, usdBIT(1), btcGH(input.offer1BtcGH))); - env(offer( - trader, - btcGH(input.offer2BtcGH), - usdGH(input.offer2UsdGH))); - env.close(); + IOUAmount const preSwapLPTokenBalance = amm.getLPTokensBalance(); - env(pay(trader, trader, input.sendUsdGH), - path(~usdGH), - path(~btcGH, ~usdGH), - sendmax(input.sendMaxUsdBIT), - txflags(tfPartialPayment)); - env.close(); + env(offer(trader, usdBIT(1), btcGH(input.offer1BtcGH))); + env(offer( + trader, btcGH(input.offer2BtcGH), usdGH(input.offer2UsdGH))); + env.close(); - auto const failUsdGH = - features[fixAMMv1_1] ? input.failUsdGHr : input.failUsdGH; - auto const failUsdBIT = - features[fixAMMv1_1] ? input.failUsdBITr : input.failUsdBIT; - auto const goodUsdGH = - features[fixAMMv1_1] ? input.goodUsdGHr : input.goodUsdGH; - auto const goodUsdBIT = - features[fixAMMv1_1] ? input.goodUsdBITr : input.goodUsdBIT; - if (!features[fixAMMOverflowOffer]) - { - BEAST_EXPECT(amm.expectBalances( - failUsdGH, failUsdBIT, input.lpTokenBalance)); - } - else - { - BEAST_EXPECT(amm.expectBalances( - goodUsdGH, goodUsdBIT, input.lpTokenBalance)); + env(pay(trader, trader, input.sendUsdGH), + path(~usdGH), + path(~btcGH, ~usdGH), + sendmax(input.sendMaxUsdBIT), + txflags(tfPartialPayment)); + env.close(); - // Invariant: LPToken balance must not change in a - // payment or a swap transaction - BEAST_EXPECT( - amm.getLPTokensBalance() == preSwapLPTokenBalance); + auto const failUsdGH = input.failUsdGHr; + auto const failUsdBIT = input.failUsdBITr; + auto const goodUsdGH = input.goodUsdGHr; + auto const goodUsdBIT = input.goodUsdBITr; - // Invariant: The square root of (product of the pool - // balances) must be at least the LPTokenBalance - Number const sqrtPoolProduct = - root2(goodUsdGH * goodUsdBIT); + BEAST_EXPECT(amm.expectBalances( + goodUsdGH, goodUsdBIT, input.lpTokenBalance)); - // Include a tiny tolerance for the test cases using - // .goodUsdGH{usdGH, uint64_t(35'44113971506987), - // -14}, .goodUsdBIT{usdBIT, - // uint64_t(2'821579689703915), -15}, - // These two values multiply - // to 99.99999999999994227040383754105 which gets - // internally rounded to 100, due to representation - // error. - BEAST_EXPECT( - (sqrtPoolProduct + Number{1, -14} >= - input.lpTokenBalance)); - } - } + // Invariant: LPToken balance must not change in a + // payment or a swap transaction + BEAST_EXPECT(amm.getLPTokensBalance() == preSwapLPTokenBalance); + + // Invariant: The square root of (product of the pool + // balances) must be at least the LPTokenBalance + Number const sqrtPoolProduct = root2(goodUsdGH * goodUsdBIT); + + // Include a tiny tolerance for the test cases using + // .goodUsdGH{usdGH, uint64_t(35'44113971506987), + // -14}, .goodUsdBIT{usdBIT, + // uint64_t(2'821579689703915), -15}, + // These two values multiply + // to 99.99999999999994227040383754105 which gets + // internally rounded to 100, due to representation + // error. + BEAST_EXPECT( + (sqrtPoolProduct + Number{1, -14} >= input.lpTokenBalance)); } } @@ -6686,7 +6131,7 @@ private: {{xrpPool, iouPool}}, 889, std::nullopt, - {jtx::supported_amendments() | fixAMMv1_1}); + {jtx::supported_amendments()}); } void @@ -6713,25 +6158,12 @@ private: env(offer(carol, USD(0.49), XRP(1))); env.close(); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT(amm.expectBalances( - XRP(200'000), USD(100'000), amm.tokens())); - BEAST_EXPECT(expectOffers( - env, alice, 1, {{Amounts{XRP(1), USD(0.01)}}})); - // Carol's offer is blocked by alice's offer - BEAST_EXPECT(expectOffers( - env, carol, 1, {{Amounts{USD(0.49), XRP(1)}}})); - } - else - { - BEAST_EXPECT(amm.expectBalances( - XRPAmount(200'000'980'005), USD(99'999.51), amm.tokens())); - BEAST_EXPECT(expectOffers( - env, alice, 1, {{Amounts{XRP(1), USD(0.01)}}})); - // Carol's offer crosses AMM - BEAST_EXPECT(expectOffers(env, carol, 0)); - } + BEAST_EXPECT(amm.expectBalances( + XRPAmount(200'000'980'005), USD(99'999.51), amm.tokens())); + BEAST_EXPECT( + expectOffers(env, alice, 1, {{Amounts{XRP(1), USD(0.01)}}})); + // Carol's offer crosses AMM + BEAST_EXPECT(expectOffers(env, carol, 0)); } // There is no blocking offer, the same AMM liquidity is consumed @@ -6768,31 +6200,18 @@ private: AMM amm(env, alice, XRP(1'000), USD(500)); env(offer(carol, XRP(100), USD(55))); env.close(); - if (!features[fixAMMv1_1]) - { - BEAST_EXPECT( - amm.expectBalances(XRP(1'000), USD(500), amm.tokens())); - BEAST_EXPECT(expectOffers( - env, bob, 1, {{Amounts{USD(1), XRPAmount(500)}}})); - BEAST_EXPECT(expectOffers( - env, carol, 1, {{Amounts{XRP(100), USD(55)}}})); - } - else - { - BEAST_EXPECT(amm.expectBalances( - XRPAmount(909'090'909), - STAmount{USD, UINT64_C(550'000000055), -9}, - amm.tokens())); - BEAST_EXPECT(expectOffers( - env, - carol, - 1, - {{Amounts{ - XRPAmount{9'090'909}, - STAmount{USD, 4'99999995, -8}}}})); - BEAST_EXPECT(expectOffers( - env, bob, 1, {{Amounts{USD(1), XRPAmount(500)}}})); - } + BEAST_EXPECT(amm.expectBalances( + XRPAmount(909'090'909), + STAmount{USD, UINT64_C(550'000000055), -9}, + amm.tokens())); + BEAST_EXPECT(expectOffers( + env, + carol, + 1, + {{Amounts{ + XRPAmount{9'090'909}, STAmount{USD, 4'99999995, -8}}}})); + BEAST_EXPECT( + expectOffers(env, bob, 1, {{Amounts{USD(1), XRPAmount(500)}}})); } // There is no blocking offer, the same AMM liquidity is consumed @@ -6843,16 +6262,8 @@ private: BEAST_EXPECT( lpToken == "1414.213562373095" && lpTokenBalance == "1414.213562373"); - if (!features[fixAMMv1_1]) - { - amm.withdrawAll(gw, std::nullopt, ter(tecAMM_BALANCE)); - BEAST_EXPECT(amm.ammExists()); - } - else - { - amm.withdrawAll(gw); - BEAST_EXPECT(!amm.ammExists()); - } + amm.withdrawAll(gw); + BEAST_EXPECT(!amm.ammExists()); } // Last Liquidity Provider is the issuer of two tokens, or not @@ -6879,16 +6290,8 @@ private: BEAST_EXPECT( lpToken == "1414.213562373095" && lpTokenBalance == "1414.213562373"); - if (!features[fixAMMv1_1]) - { - amm.withdrawAll(lp, std::nullopt, ter(tecAMM_BALANCE)); - BEAST_EXPECT(amm.ammExists()); - } - else - { - amm.withdrawAll(lp); - BEAST_EXPECT(!amm.ammExists()); - } + amm.withdrawAll(lp); + BEAST_EXPECT(!amm.ammExists()); } // More than one Liquidity Provider @@ -7070,8 +6473,7 @@ private: testcase("Fix Reserve Check On Withdrawal"); using namespace jtx; - auto const err = features[fixAMMv1_2] ? ter(tecINSUFFICIENT_RESERVE) - : ter(tesSUCCESS); + auto const err = ter(tecINSUFFICIENT_RESERVE); auto test = [&](auto&& cb) { Env env(*this, features); @@ -7128,46 +6530,32 @@ private: testFeeVote(); testInvalidBid(); testBid(all); - testBid(all - fixAMMv1_1); testInvalidAMMPayment(); testBasicPaymentEngine(all); - testBasicPaymentEngine(all - fixAMMv1_1); testBasicPaymentEngine(all - fixReducedOffersV2); - testBasicPaymentEngine(all - fixAMMv1_1 - fixReducedOffersV2); testAMMTokens(); testAmendment(); testFlags(); testRippling(); testAMMAndCLOB(all); - testAMMAndCLOB(all - fixAMMv1_1); testTradingFee(all); - testTradingFee(all - fixAMMv1_1); testAdjustedTokens(all); - testAdjustedTokens(all - fixAMMv1_1); testAutoDelete(); testClawback(); testAMMID(); testSelection(all); - testSelection(all - fixAMMv1_1); testFixDefaultInnerObj(); testMalformed(); testFixOverflowOffer(all); - testFixOverflowOffer(all - fixAMMv1_1); testSwapRounding(); testFixChangeSpotPriceQuality(all); - testFixChangeSpotPriceQuality(all - fixAMMv1_1); testFixAMMOfferBlockedByLOB(all); - testFixAMMOfferBlockedByLOB(all - fixAMMv1_1); testLPTokenBalance(all); - testLPTokenBalance(all - fixAMMv1_1); testAMMClawback(all); testAMMClawback(all - featureAMMClawback); - testAMMClawback(all - fixAMMv1_1 - featureAMMClawback); testAMMDepositWithFrozenAssets(all); testAMMDepositWithFrozenAssets(all - featureAMMClawback); - testAMMDepositWithFrozenAssets(all - fixAMMv1_1 - featureAMMClawback); testFixReserveCheckOnWithdrawal(all); - testFixReserveCheckOnWithdrawal(all - fixAMMv1_2); } }; diff --git a/src/test/app/LPTokenTransfer_test.cpp b/src/test/app/LPTokenTransfer_test.cpp index 96e621dcc..5fd505b5f 100644 --- a/src/test/app/LPTokenTransfer_test.cpp +++ b/src/test/app/LPTokenTransfer_test.cpp @@ -61,8 +61,7 @@ class LPTokenTransfer_test : public jtx::AMMTest env.close(); // bob can still send lptoken to carol even tho carol's USD is - // frozen, regardless of whether fixFrozenLPTokenTransfer is enabled or - // not + // frozen // Note: Deep freeze is not considered for LPToken transfer env(pay(bob, carol, STAmount{lpIssue, 5})); env.close(); @@ -72,16 +71,8 @@ class LPTokenTransfer_test : public jtx::AMMTest ter(tecNO_PERMISSION)); env.close(); - if (features[fixFrozenLPTokenTransfer]) - { - // carol is frozen on USD and therefore can't send lptoken to bob - env(pay(carol, bob, STAmount{lpIssue, 5}), ter(tecPATH_DRY)); - } - else - { - // carol can still send lptoken with frozen USD - env(pay(carol, bob, STAmount{lpIssue, 5})); - } + // carol is frozen on USD and therefore can't send lptoken to bob + env(pay(carol, bob, STAmount{lpIssue, 5}), ter(tecPATH_DRY)); } void @@ -119,40 +110,26 @@ class LPTokenTransfer_test : public jtx::AMMTest env.close(); // exercises alice's ability to consume carol's offer to sell lptoken - // when carol's USD is frozen pre/post fixFrozenLPTokenTransfer - // amendment - if (features[fixFrozenLPTokenTransfer]) - { - // with fixFrozenLPTokenTransfer, alice fails to consume carol's - // offer since carol's USD is frozen - env(pay(alice, bob, STAmount{lpIssue, 10}), - txflags(tfPartialPayment), - sendmax(XRP(10)), - ter(tecPATH_DRY)); - env.close(); - BEAST_EXPECT(expectOffers(env, carol, 1)); + // when carol's USD is frozen - // gateway unfreezes carol's USD - env(trust(gw, carol["USD"](1'000'000'000), tfClearFreeze)); - env.close(); + // alice fails to consume carol's offer since carol's USD is frozen + env(pay(alice, bob, STAmount{lpIssue, 10}), + txflags(tfPartialPayment), + sendmax(XRP(10)), + ter(tecPATH_DRY)); + env.close(); + BEAST_EXPECT(expectOffers(env, carol, 1)); - // alice successfully consumes carol's offer - env(pay(alice, bob, STAmount{lpIssue, 10}), - txflags(tfPartialPayment), - sendmax(XRP(10))); - env.close(); - BEAST_EXPECT(expectOffers(env, carol, 0)); - } - else - { - // without fixFrozenLPTokenTransfer, alice can consume carol's offer - // even when carol's USD is frozen - env(pay(alice, bob, STAmount{lpIssue, 10}), - txflags(tfPartialPayment), - sendmax(XRP(10))); - env.close(); - BEAST_EXPECT(expectOffers(env, carol, 0)); - } + // gateway unfreezes carol's USD + env(trust(gw, carol["USD"](1'000'000'000), tfClearFreeze)); + env.close(); + + // alice successfully consumes carol's offer + env(pay(alice, bob, STAmount{lpIssue, 10}), + txflags(tfPartialPayment), + sendmax(XRP(10))); + env.close(); + BEAST_EXPECT(expectOffers(env, carol, 0)); // make sure carol's USD is not frozen env(trust(gw, carol["USD"](1'000'000'000), tfClearFreeze)); @@ -205,37 +182,26 @@ class LPTokenTransfer_test : public jtx::AMMTest env.close(); // exercises carol's ability to create a new offer to sell lptoken with - // frozen USD, before and after fixFrozenLPTokenTransfer - if (features[fixFrozenLPTokenTransfer]) - { - // with fixFrozenLPTokenTransfer, carol can't create an offer to - // sell lptoken when one of the assets is frozen + // frozen USD - // carol can't create an offer to sell lptoken - env(offer(carol, XRP(10), STAmount{lpIssue, 10}), - txflags(tfPassive), - ter(tecUNFUNDED_OFFER)); - env.close(); - BEAST_EXPECT(expectOffers(env, carol, 0)); + // carol can't create an offer to sell lptoken when one of the assets is + // frozen - // gateway unfreezes carol's USD - env(trust(gw, carol["USD"](1'000'000'000), tfClearFreeze)); - env.close(); + // carol can't create an offer to sell lptoken + env(offer(carol, XRP(10), STAmount{lpIssue, 10}), + txflags(tfPassive), + ter(tecUNFUNDED_OFFER)); + env.close(); + BEAST_EXPECT(expectOffers(env, carol, 0)); - // carol can create an offer to sell lptoken after USD is unfrozen - env(offer(carol, XRP(10), STAmount{lpIssue, 10}), - txflags(tfPassive)); - env.close(); - BEAST_EXPECT(expectOffers(env, carol, 1)); - } - else - { - // without fixFrozenLPTokenTransfer, carol can create an offer - env(offer(carol, XRP(10), STAmount{lpIssue, 10}), - txflags(tfPassive)); - env.close(); - BEAST_EXPECT(expectOffers(env, carol, 1)); - } + // gateway unfreezes carol's USD + env(trust(gw, carol["USD"](1'000'000'000), tfClearFreeze)); + env.close(); + + // carol can create an offer to sell lptoken after USD is unfrozen + env(offer(carol, XRP(10), STAmount{lpIssue, 10}), txflags(tfPassive)); + env.close(); + BEAST_EXPECT(expectOffers(env, carol, 1)); // gateway freezes carol's USD env(trust(gw, carol["USD"](0), tfSetFreeze)); @@ -276,38 +242,22 @@ class LPTokenTransfer_test : public jtx::AMMTest env.close(); // alice creates an offer which exhibits different behavior on offer - // crossing depending on if fixFrozenLPTokenTransfer is enabled + // crossing depending on env(offer(alice, STAmount{token1, 100}, STAmount{token2, 100})); env.close(); // exercises carol's offer's ability to cross with alice's offer when - // carol's USD is frozen, before and after fixFrozenLPTokenTransfer - if (features[fixFrozenLPTokenTransfer]) - { - // with fixFrozenLPTokenTransfer enabled, alice's offer can no - // longer cross with carol's offer - BEAST_EXPECT( - expectLine(env, alice, STAmount{token1, 10'000'000}) && - expectLine(env, alice, STAmount{token2, 10'000'000})); - BEAST_EXPECT( - expectLine(env, carol, STAmount{token2, 10'000'000}) && - expectLine(env, carol, STAmount{token1, 10'000'000})); - BEAST_EXPECT( - expectOffers(env, alice, 1) && expectOffers(env, carol, 0)); - } - else - { - // alice's offer still crosses with carol's offer despite carol's - // token1 is frozen - BEAST_EXPECT( - expectLine(env, alice, STAmount{token1, 10'000'100}) && - expectLine(env, alice, STAmount{token2, 9'999'900})); - BEAST_EXPECT( - expectLine(env, carol, STAmount{token2, 10'000'100}) && - expectLine(env, carol, STAmount{token1, 9'999'900})); - BEAST_EXPECT( - expectOffers(env, alice, 0) && expectOffers(env, carol, 0)); - } + // carol's USD is frozen + + // alice's offer can no longer cross with carol's offer + BEAST_EXPECT( + expectLine(env, alice, STAmount{token1, 10'000'000}) && + expectLine(env, alice, STAmount{token2, 10'000'000})); + BEAST_EXPECT( + expectLine(env, carol, STAmount{token2, 10'000'000}) && + expectLine(env, carol, STAmount{token1, 10'000'000})); + BEAST_EXPECT( + expectOffers(env, alice, 1) && expectOffers(env, carol, 0)); } void @@ -340,12 +290,9 @@ class LPTokenTransfer_test : public jtx::AMMTest env(check::create(carol, bob, STAmount{lpIssue, 10})); env.close(); - // with fixFrozenLPTokenTransfer enabled, bob fails to cash the check - if (features[fixFrozenLPTokenTransfer]) - env(check::cash(bob, carolChkId, STAmount{lpIssue, 10}), - ter(tecPATH_PARTIAL)); - else - env(check::cash(bob, carolChkId, STAmount{lpIssue, 10})); + // bob fails to cash the check + env(check::cash(bob, carolChkId, STAmount{lpIssue, 10}), + ter(tecPATH_PARTIAL)); env.close(); @@ -398,69 +345,43 @@ class LPTokenTransfer_test : public jtx::AMMTest // exercises one's ability to transfer NFT using lptoken when one of the // assets is frozen - if (features[fixFrozenLPTokenTransfer]) - { - // with fixFrozenLPTokenTransfer, freezing USD will prevent buy/sell - // offers with lptokens from being created/accepted - // carol fails to accept bob's offer with lptoken because carol's - // USD is frozen - env(token::acceptSellOffer(carol, sellOfferIndex), - ter(tecINSUFFICIENT_FUNDS)); - env.close(); + // Freezing USD will prevent buy/sell + // offers with lptokens from being created/accepted - // gateway unfreezes carol's USD - env(trust(gw, carol["USD"](1'000'000), tfClearFreeze)); - env.close(); + // carol fails to accept bob's offer with lptoken because carol's + // USD is frozen + env(token::acceptSellOffer(carol, sellOfferIndex), + ter(tecINSUFFICIENT_FUNDS)); + env.close(); - // carol can now accept the offer and own the nft - env(token::acceptSellOffer(carol, sellOfferIndex)); - env.close(); + // gateway unfreezes carol's USD + env(trust(gw, carol["USD"](1'000'000), tfClearFreeze)); + env.close(); - // gateway freezes bobs's USD - env(trust(gw, bob["USD"](0), tfSetFreeze)); - env.close(); + // carol can now accept the offer and own the nft + env(token::acceptSellOffer(carol, sellOfferIndex)); + env.close(); - // bob fails to create a buy offer with lptoken for carol's nft - // since bob's USD is frozen - env(token::createOffer(bob, nftID, STAmount{lpIssue, 10}), - token::owner(carol), - ter(tecUNFUNDED_OFFER)); - env.close(); + // gateway freezes bobs's USD + env(trust(gw, bob["USD"](0), tfSetFreeze)); + env.close(); - // gateway unfreezes bob's USD - env(trust(gw, bob["USD"](1'000'000), tfClearFreeze)); - env.close(); + // bob fails to create a buy offer with lptoken for carol's nft + // since bob's USD is frozen + env(token::createOffer(bob, nftID, STAmount{lpIssue, 10}), + token::owner(carol), + ter(tecUNFUNDED_OFFER)); + env.close(); - // bob can now create a buy offer - env(token::createOffer(bob, nftID, STAmount{lpIssue, 10}), - token::owner(carol)); - env.close(); - } - else - { - // without fixFrozenLPTokenTransfer, freezing USD will still allow - // buy/sell offers to be created/accepted with lptoken + // gateway unfreezes bob's USD + env(trust(gw, bob["USD"](1'000'000), tfClearFreeze)); + env.close(); - // carol can still accept bob's offer despite carol's USD is frozen - env(token::acceptSellOffer(carol, sellOfferIndex)); - env.close(); - - // gateway freezes bob's USD - env(trust(gw, bob["USD"](0), tfSetFreeze)); - env.close(); - - // bob creates a buy offer with lptoken despite bob's USD is frozen - uint256 const buyOfferIndex = - keylet::nftoffer(bob, env.seq(bob)).key; - env(token::createOffer(bob, nftID, STAmount{lpIssue, 10}), - token::owner(carol)); - env.close(); - - // carol accepts bob's offer - env(token::acceptBuyOffer(carol, buyOfferIndex)); - env.close(); - } + // bob can now create a buy offer + env(token::createOffer(bob, nftID, STAmount{lpIssue, 10}), + token::owner(carol)); + env.close(); } public: @@ -469,15 +390,12 @@ public: { FeatureBitset const all{jtx::supported_amendments()}; - for (auto const features : {all, all - fixFrozenLPTokenTransfer}) - { - testDirectStep(features); - testBookStep(features); - testOfferCreation(features); - testOfferCrossing(features); - testCheck(features); - testNFTOffers(features); - } + testDirectStep(all); + testBookStep(all); + testOfferCreation(all); + testOfferCrossing(all); + testCheck(all); + testNFTOffers(all); } }; diff --git a/src/xrpld/app/misc/AMMHelpers.h b/src/xrpld/app/misc/AMMHelpers.h index c6c0c808b..be75abce0 100644 --- a/src/xrpld/app/misc/AMMHelpers.h +++ b/src/xrpld/app/misc/AMMHelpers.h @@ -336,76 +336,6 @@ changeSpotPriceQuality( Rules const& rules, beast::Journal j) { - if (!rules.enabled(fixAMMv1_1)) - { - // Finds takerPays (i) and takerGets (o) such that given pool - // composition poolGets(I) and poolPays(O): (O - o) / (I + i) = quality. - // Where takerGets is calculated as the swapAssetIn (see below). - // The above equation produces the quadratic equation: - // i^2*(1-fee) + i*I*(2-fee) + I^2 - I*O/quality, - // which is solved for i, and o is found with swapAssetIn(). - auto const f = feeMult(tfee); // 1 - fee - auto const& a = f; - auto const b = pool.in * (1 + f); - Number const c = - pool.in * pool.in - pool.in * pool.out * quality.rate(); - if (auto const res = b * b - 4 * a * c; res < 0) - return std::nullopt; // LCOV_EXCL_LINE - else if (auto const nTakerPaysPropose = (-b + root2(res)) / (2 * a); - nTakerPaysPropose > 0) - { - auto const nTakerPays = [&]() { - // The fee might make the AMM offer quality less than CLOB - // quality. Therefore, AMM offer has to satisfy this constraint: - // o / i >= q. Substituting o with swapAssetIn() gives: i <= O / - // q - I / (1 - fee). - auto const nTakerPaysConstraint = - pool.out * quality.rate() - pool.in / f; - if (nTakerPaysPropose > nTakerPaysConstraint) - return nTakerPaysConstraint; - return nTakerPaysPropose; - }(); - if (nTakerPays <= 0) - { - JLOG(j.trace()) - << "changeSpotPriceQuality calc failed: " - << to_string(pool.in) << " " << to_string(pool.out) << " " - << quality << " " << tfee; - return std::nullopt; - } - auto const takerPays = - toAmount(getIssue(pool.in), nTakerPays, Number::upward); - // should not fail - if (auto const amounts = - TAmounts{ - takerPays, swapAssetIn(pool, takerPays, tfee)}; - Quality{amounts} < quality && - !withinRelativeDistance( - Quality{amounts}, quality, Number(1, -7))) - { - JLOG(j.error()) - << "changeSpotPriceQuality failed: " << to_string(pool.in) - << " " << to_string(pool.out) << " " << " " << quality - << " " << tfee << " " << to_string(amounts.in) << " " - << to_string(amounts.out); - Throw("changeSpotPriceQuality failed"); - } - else - { - JLOG(j.trace()) - << "changeSpotPriceQuality succeeded: " - << to_string(pool.in) << " " << to_string(pool.out) << " " - << " " << quality << " " << tfee << " " - << to_string(amounts.in) << " " << to_string(amounts.out); - return amounts; - } - } - JLOG(j.trace()) << "changeSpotPriceQuality calc failed: " - << to_string(pool.in) << " " << to_string(pool.out) - << " " << quality << " " << tfee; - return std::nullopt; - } - // Generate the offer starting with XRP side. Return seated offer amounts // if the offer can be generated, otherwise nullopt. auto const amounts = [&]() { @@ -467,61 +397,49 @@ swapAssetIn( TIn const& assetIn, std::uint16_t tfee) { - if (auto const& rules = getCurrentTransactionRules(); - rules && rules->enabled(fixAMMv1_1)) - { - // set rounding to always favor the amm. Clip to zero. - // calculate: - // pool.out - - // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), - // and explicitly set the rounding modes - // Favoring the amm means we should: - // minimize: - // pool.out - - // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), - // maximize: - // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), - // (pool.in * pool.out) - // minimize: - // (pool.in + assetIn * feeMult(tfee)), - // minimize: - // assetIn * feeMult(tfee) - // feeMult is: (1-fee), fee is tfee/100000 - // minimize: - // 1-fee - // maximize: - // fee - saveNumberRoundMode _{Number::getround()}; + // set rounding to always favor the amm. Clip to zero. + // calculate: + // pool.out - + // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), + // and explicitly set the rounding modes + // Favoring the amm means we should: + // minimize: + // pool.out - + // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), + // maximize: + // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), + // (pool.in * pool.out) + // minimize: + // (pool.in + assetIn * feeMult(tfee)), + // minimize: + // assetIn * feeMult(tfee) + // feeMult is: (1-fee), fee is tfee/100000 + // minimize: + // 1-fee + // maximize: + // fee + saveNumberRoundMode _{Number::getround()}; - Number::setround(Number::upward); - auto const numerator = pool.in * pool.out; - auto const fee = getFee(tfee); + Number::setround(Number::upward); + auto const numerator = pool.in * pool.out; + auto const fee = getFee(tfee); - Number::setround(Number::downward); - auto const denom = pool.in + assetIn * (1 - fee); + Number::setround(Number::downward); + auto const denom = pool.in + assetIn * (1 - fee); - if (denom.signum() <= 0) - return toAmount(getIssue(pool.out), 0); + if (denom.signum() <= 0) + return toAmount(getIssue(pool.out), 0); - Number::setround(Number::upward); - auto const ratio = numerator / denom; + Number::setround(Number::upward); + auto const ratio = numerator / denom; - Number::setround(Number::downward); - auto const swapOut = pool.out - ratio; + Number::setround(Number::downward); + auto const swapOut = pool.out - ratio; - if (swapOut.signum() < 0) - return toAmount(getIssue(pool.out), 0); + if (swapOut.signum() < 0) + return toAmount(getIssue(pool.out), 0); - return toAmount(getIssue(pool.out), swapOut, Number::downward); - } - else - { - return toAmount( - getIssue(pool.out), - pool.out - - (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)), - Number::downward); - } + return toAmount(getIssue(pool.out), swapOut, Number::downward); } /** Swap assetOut out of the pool and swap in a proportional amount @@ -540,61 +458,49 @@ swapAssetOut( TOut const& assetOut, std::uint16_t tfee) { - if (auto const& rules = getCurrentTransactionRules(); - rules && rules->enabled(fixAMMv1_1)) + // set rounding to always favor the amm. Clip to zero. + // calculate: + // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) / + // (1-tfee/100000) + // maximize: + // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) + // maximize: + // (pool.in * pool.out) / (pool.out - assetOut) + // maximize: + // (pool.in * pool.out) + // minimize + // (pool.out - assetOut) + // minimize: + // (1-tfee/100000) + // maximize: + // tfee/100000 + + saveNumberRoundMode _{Number::getround()}; + + Number::setround(Number::upward); + auto const numerator = pool.in * pool.out; + + Number::setround(Number::downward); + auto const denom = pool.out - assetOut; + if (denom.signum() <= 0) { - // set rounding to always favor the amm. Clip to zero. - // calculate: - // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) / - // (1-tfee/100000) - // maximize: - // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) - // maximize: - // (pool.in * pool.out) / (pool.out - assetOut) - // maximize: - // (pool.in * pool.out) - // minimize - // (pool.out - assetOut) - // minimize: - // (1-tfee/100000) - // maximize: - // tfee/100000 - - saveNumberRoundMode _{Number::getround()}; - - Number::setround(Number::upward); - auto const numerator = pool.in * pool.out; - - Number::setround(Number::downward); - auto const denom = pool.out - assetOut; - if (denom.signum() <= 0) - { - return toMaxAmount(getIssue(pool.in)); - } - - Number::setround(Number::upward); - auto const ratio = numerator / denom; - auto const numerator2 = ratio - pool.in; - auto const fee = getFee(tfee); - - Number::setround(Number::downward); - auto const feeMult = 1 - fee; - - Number::setround(Number::upward); - auto const swapIn = numerator2 / feeMult; - if (swapIn.signum() < 0) - return toAmount(getIssue(pool.in), 0); - - return toAmount(getIssue(pool.in), swapIn, Number::upward); - } - else - { - return toAmount( - getIssue(pool.in), - ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) / - feeMult(tfee), - Number::upward); + return toMaxAmount(getIssue(pool.in)); } + + Number::setround(Number::upward); + auto const ratio = numerator / denom; + auto const numerator2 = ratio - pool.in; + auto const fee = getFee(tfee); + + Number::setround(Number::downward); + auto const feeMult = 1 - fee; + + Number::setround(Number::upward); + auto const swapIn = numerator2 / feeMult; + if (swapIn.signum() < 0) + return toAmount(getIssue(pool.in), 0); + + return toAmount(getIssue(pool.in), swapIn, Number::upward); } /** Return square of n. diff --git a/src/xrpld/app/misc/detail/AMMHelpers.cpp b/src/xrpld/app/misc/detail/AMMHelpers.cpp index 8724c413a..76b977e9a 100644 --- a/src/xrpld/app/misc/detail/AMMHelpers.cpp +++ b/src/xrpld/app/misc/detail/AMMHelpers.cpp @@ -165,13 +165,6 @@ adjustAmountsByLPTokens( if (lpTokensActual < lpTokens) { - bool const ammRoundingEnabled = [&]() { - if (auto const& rules = getCurrentTransactionRules(); - rules && rules->enabled(fixAMMv1_1)) - return true; - return false; - }(); - // Equal trade if (amount2) { @@ -179,14 +172,7 @@ adjustAmountsByLPTokens( auto const amountActual = toSTAmount(amount.issue(), fr * amount); auto const amount2Actual = toSTAmount(amount2->issue(), fr * *amount2); - if (!ammRoundingEnabled) - return std::make_tuple( - amountActual < amount ? amountActual : amount, - amount2Actual < amount2 ? amount2Actual : amount2, - lpTokensActual); - else - return std::make_tuple( - amountActual, amount2Actual, lpTokensActual); + return std::make_tuple(amountActual, amount2Actual, lpTokensActual); } // Single trade @@ -194,19 +180,11 @@ adjustAmountsByLPTokens( if (isDeposit) return ammAssetIn( amountBalance, lptAMMBalance, lpTokensActual, tfee); - else if (!ammRoundingEnabled) - return withdrawByTokens( - amountBalance, lptAMMBalance, lpTokens, tfee); - else - return withdrawByTokens( - amountBalance, lptAMMBalance, lpTokensActual, tfee); + return withdrawByTokens( + amountBalance, lptAMMBalance, lpTokensActual, tfee); }(); - if (!ammRoundingEnabled) - return amountActual < amount - ? std::make_tuple(amountActual, std::nullopt, lpTokensActual) - : std::make_tuple(amount, std::nullopt, lpTokensActual); - else - return std::make_tuple(amountActual, std::nullopt, lpTokensActual); + + return std::make_tuple(amountActual, std::nullopt, lpTokensActual); } XRPL_ASSERT( diff --git a/src/xrpld/app/misc/detail/AMMUtils.cpp b/src/xrpld/app/misc/detail/AMMUtils.cpp index 0b83afc6d..10a918098 100644 --- a/src/xrpld/app/misc/detail/AMMUtils.cpp +++ b/src/xrpld/app/misc/detail/AMMUtils.cpp @@ -118,8 +118,7 @@ ammLPHolds( { // This function looks similar to `accountHolds`. However, it only checks if // a LPToken holder has enough balance. On the other hand, `accountHolds` - // checks if the underlying assets of LPToken are frozen with the - // fixFrozenLPTokenTransfer amendment + // checks if the underlying assets of LPToken are frozen auto const currency = ammLPTCurrency(cur1, cur2); STAmount amount; diff --git a/src/xrpld/app/paths/AMMLiquidity.h b/src/xrpld/app/paths/AMMLiquidity.h index fe60d3926..e4e03a87b 100644 --- a/src/xrpld/app/paths/AMMLiquidity.h +++ b/src/xrpld/app/paths/AMMLiquidity.h @@ -138,13 +138,9 @@ private: generateFibSeqOffer(TAmounts const& balances) const; /** Generate max offer. - * If `fixAMMOverflowOffer` is active, the offer is generated as: + * The offer is generated as: * takerGets = 99% * balances.out takerPays = swapOut(takerGets). * Return nullopt if takerGets is 0 or takerGets == balances.out. - * - * If `fixAMMOverflowOffer` is not active, the offer is generated as: - * takerPays = max input amount; - * takerGets = swapIn(takerPays). */ std::optional> maxOffer(TAmounts const& balances, Rules const& rules) const; diff --git a/src/xrpld/app/paths/detail/AMMLiquidity.cpp b/src/xrpld/app/paths/detail/AMMLiquidity.cpp index 813554ba7..984374546 100644 --- a/src/xrpld/app/paths/detail/AMMLiquidity.cpp +++ b/src/xrpld/app/paths/detail/AMMLiquidity.cpp @@ -123,26 +123,14 @@ AMMLiquidity::maxOffer( TAmounts const& balances, Rules const& rules) const { - if (!rules.enabled(fixAMMOverflowOffer)) - { - return AMMOffer( - *this, - {maxAmount(), - swapAssetIn(balances, maxAmount(), tradingFee_)}, - balances, - Quality{balances}); - } - else - { - auto const out = maxOut(balances.out, issueOut()); - if (out <= TOut{0} || out >= balances.out) - return std::nullopt; - return AMMOffer( - *this, - {swapAssetOut(balances, out, tradingFee_), out}, - balances, - Quality{balances}); - } + auto const out = maxOut(balances.out, issueOut()); + if (out <= TOut{0} || out >= balances.out) + return std::nullopt; + return AMMOffer( + *this, + {swapAssetOut(balances, out, tradingFee_), out}, + balances, + Quality{balances}); } template @@ -213,22 +201,13 @@ AMMLiquidity::getOffer( return AMMOffer( *this, *amounts, balances, Quality{*amounts}); } - else if (view.rules().enabled(fixAMMv1_2)) + else if (auto const maxAMMOffer = maxOffer(balances, view.rules()); + maxAMMOffer && + Quality{maxAMMOffer->amount()} > *clobQuality) { - if (auto const maxAMMOffer = maxOffer(balances, view.rules()); - maxAMMOffer && - Quality{maxAMMOffer->amount()} > *clobQuality) - return maxAMMOffer; + return maxAMMOffer; } } - catch (std::overflow_error const& e) - { - JLOG(j_.error()) << "AMMLiquidity::getOffer overflow " << e.what(); - if (!view.rules().enabled(fixAMMOverflowOffer)) - return maxOffer(balances, view.rules()); - else - return std::nullopt; - } catch (std::exception const& e) { JLOG(j_.error()) << "AMMLiquidity::getOffer exception " << e.what(); diff --git a/src/xrpld/app/paths/detail/BookStep.cpp b/src/xrpld/app/paths/detail/BookStep.cpp index e38b9ae16..4f01ef121 100644 --- a/src/xrpld/app/paths/detail/BookStep.cpp +++ b/src/xrpld/app/paths/detail/BookStep.cpp @@ -533,10 +533,7 @@ public: // Single path AMM offer has to factor in the transfer in rate // when calculating the upper bound quality and the quality function // because single path AMM's offer quality is not constant. - if (!rules.enabled(fixAMMv1_1)) - return ofrQ; - else if ( - offerType == OfferType::CLOB || + if (offerType == OfferType::CLOB || (this->ammLiquidity_ && this->ammLiquidity_->multiPath())) return ofrQ; @@ -838,7 +835,7 @@ BookStep::forEachOffer( // If offer crossing then use either LOB quality or nullopt // to prevent AMM being blocked by a lower quality LOB. auto const qualityThreshold = [&]() -> std::optional { - if (sb.rules().enabled(fixAMMv1_1) && lobQuality) + if (lobQuality) return static_cast(this)->qualityThreshold( *lobQuality); return lobQuality; @@ -881,11 +878,8 @@ BookStep::consumeOffer( { // purposely written as separate if statements so we get logging even // when the amendment isn't active. - if (sb.rules().enabled(fixAMMOverflowOffer)) - { - Throw( - tecINVARIANT_FAILED, "AMM pool product invariant failed."); - } + Throw( + tecINVARIANT_FAILED, "AMM pool product invariant failed."); } // The offer owner gets the ofrAmt. The difference between ofrAmt and @@ -955,7 +949,7 @@ BookStep::tip(ReadView const& view) const // as the result a LOB offer is partially crossed, and it might take a few // iterations to fully cross the offer. auto const qualityThreshold = [&]() -> std::optional { - if (view.rules().enabled(fixAMMv1_1) && lobQuality) + if (lobQuality) return static_cast(this)->qualityThreshold( *lobQuality); return std::nullopt; diff --git a/src/xrpld/app/paths/detail/StepChecks.h b/src/xrpld/app/paths/detail/StepChecks.h index d4fda2bfe..6affeccff 100644 --- a/src/xrpld/app/paths/detail/StepChecks.h +++ b/src/xrpld/app/paths/detail/StepChecks.h @@ -61,23 +61,20 @@ checkFreeze( } } - if (view.rules().enabled(fixFrozenLPTokenTransfer)) + if (auto const sleDst = view.read(keylet::account(dst)); + sleDst && sleDst->isFieldPresent(sfAMMID)) { - if (auto const sleDst = view.read(keylet::account(dst)); - sleDst && sleDst->isFieldPresent(sfAMMID)) - { - auto const sleAmm = view.read(keylet::amm((*sleDst)[sfAMMID])); - if (!sleAmm) - return tecINTERNAL; // LCOV_EXCL_LINE + auto const sleAmm = view.read(keylet::amm((*sleDst)[sfAMMID])); + if (!sleAmm) + return tecINTERNAL; // LCOV_EXCL_LINE - if (isLPTokenFrozen( - view, - src, - (*sleAmm)[sfAsset].get(), - (*sleAmm)[sfAsset2].get())) - { - return terNO_LINE; - } + if (isLPTokenFrozen( + view, + src, + (*sleAmm)[sfAsset].get(), + (*sleAmm)[sfAsset2].get())) + { + return terNO_LINE; } } diff --git a/src/xrpld/app/tx/detail/AMMWithdraw.cpp b/src/xrpld/app/tx/detail/AMMWithdraw.cpp index 23e8529cf..4fccec937 100644 --- a/src/xrpld/app/tx/detail/AMMWithdraw.cpp +++ b/src/xrpld/app/tx/detail/AMMWithdraw.cpp @@ -311,26 +311,24 @@ AMMWithdraw::applyGuts(Sandbox& sb) // Due to rounding, the LPTokenBalance of the last LP // might not match the LP's trustline balance - if (sb.rules().enabled(fixAMMv1_1)) + + if (auto const res = + isOnlyLiquidityProvider(sb, lpTokens.issue(), account_); + !res) + return {res.error(), false}; + else if (res.value()) { - if (auto const res = - isOnlyLiquidityProvider(sb, lpTokens.issue(), account_); - !res) - return {res.error(), false}; - else if (res.value()) + if (withinRelativeDistance( + lpTokens, + ammSle->getFieldAmount(sfLPTokenBalance), + Number{1, -3})) { - if (withinRelativeDistance( - lpTokens, - ammSle->getFieldAmount(sfLPTokenBalance), - Number{1, -3})) - { - ammSle->setFieldAmount(sfLPTokenBalance, lpTokens); - sb.update(ammSle); - } - else - { - return {tecAMM_INVALID_TOKENS, false}; - } + ammSle->setFieldAmount(sfLPTokenBalance, lpTokens); + sb.update(ammSle); + } + else + { + return {tecAMM_INVALID_TOKENS, false}; } } @@ -542,8 +540,7 @@ AMMWithdraw::withdraw( // Should not happen since the only LP on last withdraw // has the balance set to the lp token trustline balance. - if (view.rules().enabled(fixAMMv1_1) && - lpTokensWithdrawActual > lpTokensAMMBalance) + if (lpTokensWithdrawActual > lpTokensAMMBalance) { // LCOV_EXCL_START JLOG(journal.debug()) @@ -597,9 +594,8 @@ AMMWithdraw::withdraw( } // Check the reserve in case a trustline has to be created - bool const enabledFixAMMv1_2 = view.rules().enabled(fixAMMv1_2); auto sufficientReserve = [&](Issue const& issue) -> TER { - if (!enabledFixAMMv1_2 || isXRP(issue)) + if (isXRP(issue)) return tesSUCCESS; if (!view.exists(keylet::line(account, issue))) { diff --git a/src/xrpld/ledger/detail/View.cpp b/src/xrpld/ledger/detail/View.cpp index 30d6a7927..33034cc24 100644 --- a/src/xrpld/ledger/detail/View.cpp +++ b/src/xrpld/ledger/detail/View.cpp @@ -335,29 +335,26 @@ accountHolds( return false; } - // when fixFrozenLPTokenTransfer is enabled, if currency is lptoken, - // we need to check if the associated assets have been frozen - if (view.rules().enabled(fixFrozenLPTokenTransfer)) + // If currency is lptoken, we need to check if the associated assets + // have been frozen + auto const sleIssuer = view.read(keylet::account(issuer)); + if (!sleIssuer) { - auto const sleIssuer = view.read(keylet::account(issuer)); - if (!sleIssuer) - { - return false; // LCOV_EXCL_LINE - } - else if (sleIssuer->isFieldPresent(sfAMMID)) - { - auto const sleAmm = - view.read(keylet::amm((*sleIssuer)[sfAMMID])); + return false; // LCOV_EXCL_LINE + } + else if (sleIssuer->isFieldPresent(sfAMMID)) + { + auto const sleAmm = + view.read(keylet::amm((*sleIssuer)[sfAMMID])); - if (!sleAmm || - isLPTokenFrozen( - view, - account, - (*sleAmm)[sfAsset].get(), - (*sleAmm)[sfAsset2].get())) - { - return false; - } + if (!sleAmm || + isLPTokenFrozen( + view, + account, + (*sleAmm)[sfAsset].get(), + (*sleAmm)[sfAsset2].get())) + { + return false; } } } @@ -1443,18 +1440,9 @@ accountSendIOU( WaiveTransferFee waiveFee, bool const senderPaysXferFees) { - if (view.rules().enabled(fixAMMv1_1)) + if (saAmount < beast::zero || saAmount.holds()) { - if (saAmount < beast::zero || saAmount.holds()) - { - return tecINTERNAL; - } - } - else - { - XRPL_ASSERT( - saAmount >= beast::zero && !saAmount.holds(), - "ripple::accountSendIOU : minimum amount and not MPT"); + return tecINTERNAL; } /* If we aren't sending anything or if the sender is the same as the