Skip to content

Commit 8a862c7

Browse files
committed
Simplify checkMPTDEX() and checkMPTTx(). (#59)
* Simplify checkMPTDEX() and checkMPTTx(). Enforce CanTrade enabled for all MPT supporting transactions. * Update CanTrade/CanTransfer rules. * Extend the unit-tests.
1 parent 9df5cbc commit 8a862c7

File tree

23 files changed

+1311
-361
lines changed

23 files changed

+1311
-361
lines changed

include/xrpl/ledger/View.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,12 @@ enforceMPTokenAuthorization(
11011101
XRPAmount const& priorBalance,
11021102
beast::Journal j);
11031103

1104+
/** Check if Asset can be traded on DEX. return tecNO_PERMISSION
1105+
* if it doesn't and tesSUCCESS otherwise.
1106+
*/
1107+
[[nodiscard]] TER
1108+
canTrade(ReadView const& view, Asset const& asset);
1109+
11041110
/** Check if the destination account is allowed
11051111
* to receive MPT. Return tecNO_AUTH if it doesn't
11061112
* and tesSUCCESS otherwise.

include/xrpl/protocol/TER.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ enum TERcodes : TERUnderlyingType {
210210
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
211211
// create a pseudo-account
212212
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
213+
terLOCKED, // MPT is locked
213214
};
214215

215216
//------------------------------------------------------------------------------

src/libxrpl/ledger/View.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3441,6 +3441,22 @@ enforceMPTokenAuthorization(
34413441
// LCOV_EXCL_STOP
34423442
}
34433443

3444+
TER
3445+
canTrade(ReadView const& view, Asset const& asset)
3446+
{
3447+
return asset.visit(
3448+
[&](Issue const&) -> TER { return tesSUCCESS; },
3449+
[&](MPTIssue const& mptIssue) -> TER {
3450+
auto const sleIssuance =
3451+
view.read(keylet::mptIssuance(mptIssue.getMptID()));
3452+
if (!sleIssuance)
3453+
return tecOBJECT_NOT_FOUND;
3454+
if (!sleIssuance->isFlag(lsfMPTCanTrade))
3455+
return tecNO_PERMISSION;
3456+
return tesSUCCESS;
3457+
});
3458+
}
3459+
34443460
TER
34453461
canTransfer(
34463462
ReadView const& view,

src/test/app/AMMClawbackMPT_test.cpp

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
3434
.issuer = gw,
3535
.holders = {alice},
3636
.pay = 40'000,
37-
.flags = tfMPTCanClawback});
37+
.flags = tfMPTCanClawback | MPTDEXFlags});
3838

3939
auto const USD = gw["USD"];
4040
env.trust(USD(10000), alice);
@@ -174,7 +174,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
174174
.issuer = gw2,
175175
.holders = {alice},
176176
.pay = 40'000,
177-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
177+
.flags = tfMPTCanClawback | MPTDEXFlags});
178178

179179
AMM amm(env, alice, BTC(100), USD(100));
180180
env.close();
@@ -204,7 +204,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
204204
.issuer = gw,
205205
.holders = {alice},
206206
.pay = 40'000,
207-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
207+
.flags = tfMPTCanClawback | MPTDEXFlags});
208208

209209
AMM amm(env, alice, BTC(100), XRP(100));
210210
env.close();
@@ -232,7 +232,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
232232
.issuer = gw,
233233
.holders = {alice},
234234
.pay = 10'000,
235-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
235+
.flags = tfMPTCanClawback | MPTDEXFlags});
236236

237237
AMM amm(env, alice, XRP(1'000), BTC(1'000));
238238

@@ -280,7 +280,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
280280
.issuer = gw2,
281281
.holders = {alice},
282282
.pay = 40'000'000000,
283-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
283+
.flags = tfMPTCanClawback | MPTDEXFlags});
284284

285285
AMM amm(env, alice, BTC(1000000000), USD(2000));
286286
env.close();
@@ -346,7 +346,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
346346
.issuer = gw,
347347
.holders = {alice, bob},
348348
.pay = 40'000'000000,
349-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
349+
.flags = tfMPTCanClawback | MPTDEXFlags});
350350

351351
AMM amm(env, alice, BTC(1000000000), XRP(2000));
352352
env.close();
@@ -456,14 +456,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
456456
.issuer = gw,
457457
.holders = {alice, bob},
458458
.pay = 40'000'000000,
459-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
459+
.flags = tfMPTCanClawback | MPTDEXFlags});
460460

461461
MPT ETH = MPTTester(
462462
{.env = env,
463463
.issuer = gw2,
464464
.holders = {alice, bob},
465465
.pay = 30'000'000000,
466-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
466+
.flags = tfMPTCanClawback | MPTDEXFlags});
467467

468468
AMM amm(env, alice, BTC(2'000'000000), ETH(3'000'000000));
469469
env.close();
@@ -574,7 +574,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
574574
.issuer = gw2,
575575
.holders = {alice, bob},
576576
.pay = 40'000'000000,
577-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
577+
.flags = tfMPTCanClawback | MPTDEXFlags});
578578

579579
AMM amm(env, alice, BTC(2000000000), USD(2000));
580580
env.close();
@@ -631,7 +631,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
631631
.issuer = gw,
632632
.holders = {alice, bob},
633633
.pay = 40'000'000000,
634-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
634+
.flags = tfMPTCanClawback | MPTDEXFlags});
635635

636636
AMM amm(env, alice, BTC(5000), XRP(10'000));
637637
env.close();
@@ -688,14 +688,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
688688
.issuer = gw,
689689
.holders = {alice, bob},
690690
.pay = 40'000'000000,
691-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
691+
.flags = tfMPTCanClawback | MPTDEXFlags});
692692

693693
MPT ETH = MPTTester(
694694
{.env = env,
695695
.issuer = gw2,
696696
.holders = {alice, bob},
697697
.pay = 30'000'000000,
698-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
698+
.flags = tfMPTCanClawback | MPTDEXFlags});
699699

700700
AMM amm(env, alice, BTC(20'000), ETH(50'000));
701701
env.close();
@@ -765,7 +765,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
765765
.issuer = gw,
766766
.holders = {alice, bob},
767767
.pay = 40'000'000000,
768-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
768+
.flags = tfMPTCanClawback | MPTDEXFlags});
769769

770770
AMM amm(env, alice, BTC(1'000'000000), USD(2000));
771771
env.close();
@@ -863,14 +863,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
863863
.issuer = gw,
864864
.holders = {alice, bob},
865865
.pay = 40'000'000000,
866-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
866+
.flags = tfMPTCanClawback | MPTDEXFlags});
867867

868868
MPT ETH = MPTTester(
869869
{.env = env,
870870
.issuer = gw,
871871
.holders = {alice, bob},
872872
.pay = 30'000'000000,
873-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
873+
.flags = tfMPTCanClawback | MPTDEXFlags});
874874

875875
AMM amm(env, alice, BTC(2'000'000000), ETH(3'000'000000));
876876
env.close();
@@ -983,7 +983,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
983983
.issuer = gw,
984984
.holders = {alice, bob},
985985
.pay = 40'000'000000,
986-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
986+
.flags = tfMPTCanClawback | MPTDEXFlags});
987987

988988
AMM amm(env, alice, BTC(2'000'000000), USD(8'000));
989989
env.close();
@@ -1042,14 +1042,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
10421042
.issuer = gw,
10431043
.holders = {alice, bob},
10441044
.pay = 40'000'000000,
1045-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1045+
.flags = tfMPTCanClawback | MPTDEXFlags});
10461046

10471047
MPT ETH = MPTTester(
10481048
{.env = env,
10491049
.issuer = gw,
10501050
.holders = {alice, bob},
10511051
.pay = 30'000'000000,
1052-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1052+
.flags = tfMPTCanClawback | MPTDEXFlags});
10531053

10541054
AMM amm(env, alice, BTC(20'000), ETH(10'000));
10551055
env.close();
@@ -1123,7 +1123,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
11231123
.issuer = gw2,
11241124
.holders = {alice, gw},
11251125
.pay = 40'000'000000,
1126-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1126+
.flags = tfMPTCanClawback | MPTDEXFlags});
11271127

11281128
AMM amm(env, gw, USD(1000), BTC(2000));
11291129
env.close();
@@ -1224,14 +1224,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
12241224
.issuer = gw,
12251225
.holders = {gw2, alice},
12261226
.pay = 40'000'000000,
1227-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1227+
.flags = tfMPTCanClawback | MPTDEXFlags});
12281228

12291229
MPT ETH = MPTTester(
12301230
{.env = env,
12311231
.issuer = gw2,
12321232
.holders = {gw, alice},
12331233
.pay = 30'000'000000,
1234-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1234+
.flags = tfMPTCanClawback | MPTDEXFlags});
12351235

12361236
AMM amm(env, gw, BTC(10'000), ETH(50'000));
12371237
env.close();
@@ -1454,7 +1454,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
14541454
.issuer = gw,
14551455
.holders = {alice},
14561456
.pay = 40'000'000000,
1457-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1457+
.flags = tfMPTCanClawback | MPTDEXFlags});
14581458

14591459
// gw creates AMM pool of BTC/XRP.
14601460
AMM amm(env, gw, XRP(100), BTC(400), ter(tesSUCCESS));
@@ -1504,7 +1504,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
15041504
.issuer = gw,
15051505
.holders = {alice},
15061506
.pay = 40'000'000000,
1507-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1507+
.flags = tfMPTCanClawback | MPTDEXFlags});
15081508

15091509
// gw creates AMM pool of BTC/USD.
15101510
AMM amm(env, gw, USD(100), BTC(400), ter(tesSUCCESS));
@@ -1557,14 +1557,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
15571557
.issuer = gw,
15581558
.holders = {alice},
15591559
.pay = 40'000'000000,
1560-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1560+
.flags = tfMPTCanClawback | MPTDEXFlags});
15611561

15621562
MPT BTC = MPTTester(
15631563
{.env = env,
15641564
.issuer = gw,
15651565
.holders = {alice},
15661566
.pay = 40'000'000000,
1567-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1567+
.flags = tfMPTCanClawback | MPTDEXFlags});
15681568

15691569
// gw creates AMM pool of BTC/USD.
15701570
AMM amm(env, gw, USD(100), BTC(400), ter(tesSUCCESS));
@@ -1630,7 +1630,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
16301630
.issuer = gw,
16311631
.holders = {alice, bob},
16321632
.pay = 40'000'000000,
1633-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1633+
.flags = tfMPTCanClawback | MPTDEXFlags});
16341634

16351635
AMM amm(env, alice, USD(2), EUR(1));
16361636
amm.deposit(alice, IOUAmount{1'576123487565916, -15});
@@ -1706,14 +1706,14 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
17061706
.issuer = gw,
17071707
.holders = {alice, bob},
17081708
.pay = 40'000'000000,
1709-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1709+
.flags = tfMPTCanClawback | MPTDEXFlags});
17101710

17111711
MPT EUR = MPTTester(
17121712
{.env = env,
17131713
.issuer = gw,
17141714
.holders = {alice, bob},
17151715
.pay = 40'000'000000,
1716-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1716+
.flags = tfMPTCanClawback | MPTDEXFlags});
17171717

17181718
AMM amm(env, alice, USD(2), EUR(1));
17191719
amm.deposit(alice, IOUAmount{1'576123487565916, -15});
@@ -1837,15 +1837,15 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
18371837
.issuer = gw,
18381838
.holders = {alice},
18391839
.pay = 40'000,
1840-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1840+
.flags = tfMPTCanClawback | MPTDEXFlags});
18411841

18421842
// Asset USD is not clawable without asfAllowTrustLineClawback.
18431843
AMM amm(env, alice, USD(200), BTC(100));
18441844
env(amm::ammClawback(gw, alice, USD, BTC, std::nullopt),
18451845
ter(tecNO_PERMISSION));
18461846

18471847
// Although BTC is clawable with tfMPTCanClawback.
1848-
// When tfClawTwoAssets is set, we will claw Asser2 as well.
1848+
// When tfClawTwoAssets is set, we will claw Asset2 as well.
18491849
// But Asset2 is not clawable. asfAllowTrustLineClawback was not set
18501850
// by the issuer.
18511851
env(amm::ammClawback(gw, alice, BTC, USD, std::nullopt),
@@ -1878,7 +1878,7 @@ class AMMClawbackMPT_test : public beast::unit_test::suite
18781878
.issuer = gw2,
18791879
.holders = {alice},
18801880
.pay = 40'000,
1881-
.flags = tfMPTCanClawback | tfMPTCanTransfer});
1881+
.flags = tfMPTCanClawback | MPTDEXFlags});
18821882

18831883
AMM amm(env, alice, USD(200), BTC(100));
18841884

src/test/app/AMMExtendedMPT_test.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,25 +3360,24 @@ struct AMMExtendedMPT_test : public jtx::AMMTest
33603360
BTC.set({.holder = bob, .flags = tfMPTLock});
33613361

33623362
{
3363-
// different from IOU.
3364-
// with MPT locked,
3365-
// can not buy more assets
3366-
env(offer(bob, BTC(5), XRP(25)), ter(tecLOCKED));
3363+
// different from IOU. The offer is created but not crossed.
3364+
env(offer(bob, BTC(5), XRP(25)));
33673365
env.close();
3366+
BEAST_EXPECT(expectOffers(env, bob, 1, {{{BTC(5), XRP(25)}}}));
33683367
BEAST_EXPECT(
33693368
ammAlice.expectBalances(XRP(500), BTC(105), ammAlice.tokens()));
33703369
}
33713370

33723371
{
33733372
// can not sell assets
3374-
env(offer(bob, XRP(1), BTC(5)), ter(tecLOCKED));
3373+
env(offer(bob, XRP(1), BTC(5)), ter(tecUNFUNDED_OFFER));
33753374

33763375
// different from IOU
33773376
// can not receive Payment when locked
3378-
env(pay(alice, bob, BTC(1)), ter(tecLOCKED));
3377+
env(pay(alice, bob, BTC(1)), ter(tecPATH_DRY));
33793378

33803379
// can not make Payment when locked
3381-
env(pay(bob, alice, BTC(1)), ter(tecLOCKED));
3380+
env(pay(bob, alice, BTC(1)), ter(tecPATH_DRY));
33823381

33833382
env.require(balance(bob, BTC(10)));
33843383
}
@@ -3474,8 +3473,8 @@ struct AMMExtendedMPT_test : public jtx::AMMTest
34743473
env(pay(G1, A2, BTC(1)));
34753474
env(pay(A2, G1, BTC(1)));
34763475
// locked
3477-
env(pay(A2, A1, BTC(1)), ter(tecLOCKED));
3478-
env(pay(A1, A2, BTC(1)), ter(tecLOCKED));
3476+
env(pay(A2, A1, BTC(1)), ter(tecPATH_DRY));
3477+
env(pay(A1, A2, BTC(1)), ter(tecPATH_DRY));
34793478
}
34803479

34813480
{

0 commit comments

Comments
 (0)