xrpld
Loading...
Searching...
No Matches
TxFlags.h
1#pragma once
2
3// NOLINTBEGIN(readability-identifier-naming)
4
5#include <xrpl/protocol/LedgerFormats.h>
6
7#include <cstdint>
8#include <map>
9#include <string>
10#include <utility>
11#include <vector>
12
13namespace xrpl {
14
39
41
42// Universal Transaction flags:
43inline constexpr FlagValue tfFullyCanonicalSig = 0x80000000;
44inline constexpr FlagValue tfInnerBatchTxn = 0x40000000;
47
48#pragma push_macro("XMACRO")
49#pragma push_macro("TO_VALUE")
50#pragma push_macro("VALUE_TO_MAP")
51#pragma push_macro("NULL_NAME")
52#pragma push_macro("NULL_OUTPUT")
53#pragma push_macro("TO_MAP")
54#pragma push_macro("TO_MASK")
55#pragma push_macro("VALUE_TO_MASK")
56#pragma push_macro("ALL_TX_FLAGS")
57#pragma push_macro("NULL_MASK_ADJ")
58#pragma push_macro("MASK_ADJ_TO_MASK")
59
60#undef XMACRO
61#undef TO_VALUE
62#undef VALUE_TO_MAP
63#undef NULL_NAME
64#undef NULL_OUTPUT
65#undef TO_MAP
66#undef TO_MASK
67#undef VALUE_TO_MASK
68#undef NULL_MASK_ADJ
69#undef MASK_ADJ_TO_MASK
70
71// clang-format off
72#undef ALL_TX_FLAGS
73
74// XMACRO parameters:
75// - TRANSACTION: handles the transaction name, its flags, and mask adjustment
76// - TF_FLAG: defines a new flag constant
77// - TF_FLAG2: references an existing flag constant (no new definition)
78// - MASK_ADJ: specifies flags to add back to the mask (making them invalid for this tx type)
79//
80// Note: MASK_ADJ is used when a universal flag should be invalid for a specific transaction.
81// For example, Batch uses MASK_ADJ(tfInnerBatchTxn) because the outer Batch transaction
82// must not have tfInnerBatchTxn set (only inner transactions should have it).
83//
84// TODO: Consider rewriting this using reflection in C++26 or later. Alternatively this could be a DSL processed by a script at build time.
85#define XMACRO(TRANSACTION, TF_FLAG, TF_FLAG2, MASK_ADJ) \
86 TRANSACTION(AccountSet, \
87 TF_FLAG(tfRequireDestTag, 0x00010000) \
88 TF_FLAG(tfOptionalDestTag, 0x00020000) \
89 TF_FLAG(tfRequireAuth, 0x00040000) \
90 TF_FLAG(tfOptionalAuth, 0x00080000) \
91 TF_FLAG(tfDisallowXRP, 0x00100000) \
92 TF_FLAG(tfAllowXRP, 0x00200000), \
93 MASK_ADJ(0)) \
94 \
95 TRANSACTION(OfferCreate, \
96 TF_FLAG(tfPassive, 0x00010000) \
97 TF_FLAG(tfImmediateOrCancel, 0x00020000) \
98 TF_FLAG(tfFillOrKill, 0x00040000) \
99 TF_FLAG(tfSell, 0x00080000) \
100 TF_FLAG(tfHybrid, 0x00100000), \
101 MASK_ADJ(0)) \
102 \
103 TRANSACTION(Payment, \
104 TF_FLAG(tfNoRippleDirect, 0x00010000) \
105 TF_FLAG(tfPartialPayment, 0x00020000) \
106 TF_FLAG(tfLimitQuality, 0x00040000) \
107 TF_FLAG(tfSponsorCreatedAccount, 0x00080000), \
108 MASK_ADJ(0)) \
109 \
110 TRANSACTION(TrustSet, \
111 TF_FLAG(tfSetfAuth, 0x00010000) \
112 TF_FLAG(tfSetNoRipple, 0x00020000) \
113 TF_FLAG(tfClearNoRipple, 0x00040000) \
114 TF_FLAG(tfSetFreeze, 0x00100000) \
115 TF_FLAG(tfClearFreeze, 0x00200000) \
116 TF_FLAG(tfSetDeepFreeze, 0x00400000) \
117 TF_FLAG(tfClearDeepFreeze, 0x00800000), \
118 MASK_ADJ(0)) \
119 \
120 TRANSACTION(EnableAmendment, \
121 TF_FLAG(tfGotMajority, 0x00010000) \
122 TF_FLAG(tfLostMajority, 0x00020000), \
123 MASK_ADJ(0)) \
124 \
125 TRANSACTION(PaymentChannelClaim, \
126 TF_FLAG(tfRenew, 0x00010000) \
127 TF_FLAG(tfClose, 0x00020000), \
128 MASK_ADJ(0)) \
129 \
130 TRANSACTION(NFTokenMint, \
131 TF_FLAG(tfBurnable, 0x00000001) \
132 TF_FLAG(tfOnlyXRP, 0x00000002) \
133 /* deprecated TF_FLAG(tfTrustLine, 0x00000004) */ \
134 TF_FLAG(tfTransferable, 0x00000008) \
135 TF_FLAG(tfMutable, 0x00000010), \
136 MASK_ADJ(0)) \
137 \
138 TRANSACTION(MPTokenIssuanceCreate, \
139 /* Note: tf/lsfMPTLocked is intentionally omitted since this transaction is not allowed to modify it. */ \
140 TF_FLAG(tfMPTCanLock, lsfMPTCanLock) \
141 TF_FLAG(tfMPTRequireAuth, lsfMPTRequireAuth) \
142 TF_FLAG(tfMPTCanEscrow, lsfMPTCanEscrow) \
143 TF_FLAG(tfMPTCanTrade, lsfMPTCanTrade) \
144 TF_FLAG(tfMPTCanTransfer, lsfMPTCanTransfer) \
145 TF_FLAG(tfMPTCanClawback, lsfMPTCanClawback) \
146 TF_FLAG(tfMPTCanHoldConfidentialBalance, lsfMPTCanHoldConfidentialBalance), \
147 MASK_ADJ(0)) \
148 \
149 TRANSACTION(MPTokenAuthorize, \
150 TF_FLAG(tfMPTUnauthorize, 0x00000001), \
151 MASK_ADJ(0)) \
152 \
153 TRANSACTION(MPTokenIssuanceSet, \
154 TF_FLAG(tfMPTLock, 0x00000001) \
155 TF_FLAG(tfMPTUnlock, 0x00000002) \
156 TF_FLAG(tfMPTSetCanLock, 0x00000004) \
157 TF_FLAG(tfMPTSetRequireAuth, 0x00000008) \
158 TF_FLAG(tfMPTSetCanEscrow, 0x00000010) \
159 TF_FLAG(tfMPTSetCanTrade, 0x00000020) \
160 TF_FLAG(tfMPTSetCanTransfer, 0x00000040) \
161 TF_FLAG(tfMPTSetCanClawback, 0x00000080) \
162 TF_FLAG(tfMPTSetCanHoldConfidentialBalance, 0x00000100), \
163 MASK_ADJ(0)) \
164 \
165 TRANSACTION(NFTokenCreateOffer, \
166 TF_FLAG(tfSellNFToken, 0x00000001), \
167 MASK_ADJ(0)) \
168 \
169 TRANSACTION(AMMDeposit, \
170 TF_FLAG(tfLPToken, 0x00010000) \
171 TF_FLAG(tfSingleAsset, 0x00080000) \
172 TF_FLAG(tfTwoAsset, 0x00100000) \
173 TF_FLAG(tfOneAssetLPToken, 0x00200000) \
174 TF_FLAG(tfLimitLPToken, 0x00400000) \
175 TF_FLAG(tfTwoAssetIfEmpty, 0x00800000), \
176 MASK_ADJ(0)) \
177 \
178 TRANSACTION(AMMWithdraw, \
179 TF_FLAG2(tfLPToken, 0x00010000) \
180 TF_FLAG(tfWithdrawAll, 0x00020000) \
181 TF_FLAG(tfOneAssetWithdrawAll, 0x00040000) \
182 TF_FLAG2(tfSingleAsset, 0x00080000) \
183 TF_FLAG2(tfTwoAsset, 0x00100000) \
184 TF_FLAG2(tfOneAssetLPToken, 0x00200000) \
185 TF_FLAG2(tfLimitLPToken, 0x00400000), \
186 MASK_ADJ(0)) \
187 \
188 TRANSACTION(AMMClawback, \
189 TF_FLAG(tfClawTwoAssets, 0x00000001), \
190 MASK_ADJ(0)) \
191 \
192 TRANSACTION(XChainModifyBridge, \
193 TF_FLAG(tfClearAccountCreateAmount, 0x00010000), \
194 MASK_ADJ(0)) \
195 \
196 TRANSACTION(VaultCreate, \
197 TF_FLAG(tfVaultPrivate, lsfVaultPrivate) \
198 TF_FLAG(tfVaultShareNonTransferable, 0x00020000), \
199 MASK_ADJ(0)) \
200 \
201 TRANSACTION(Batch, \
202 TF_FLAG(tfAllOrNothing, 0x00010000) \
203 TF_FLAG(tfOnlyOne, 0x00020000) \
204 TF_FLAG(tfUntilFailure, 0x00040000) \
205 TF_FLAG(tfIndependent, 0x00080000), \
206 MASK_ADJ(tfInnerBatchTxn)) /* Batch must reject tfInnerBatchTxn - only inner transactions should have this flag */ \
207 \
208 TRANSACTION(LoanSet, /* True indicates the loan supports overpayments */ \
209 TF_FLAG(tfLoanOverpayment, 0x00010000), \
210 MASK_ADJ(0)) \
211 \
212 TRANSACTION(LoanPay, /* True indicates any excess in this payment can be used as an overpayment. */ \
213 /* False: no overpayments will be taken. */ \
214 TF_FLAG2(tfLoanOverpayment, 0x00010000) \
215 TF_FLAG(tfLoanFullPayment, 0x00020000) /* True indicates that the payment is an early full payment. */ \
216 /* It must pay the entire loan including close interest and fees, or it will fail. */ \
217 /* False: Not a full payment. */ \
218 TF_FLAG(tfLoanLatePayment, 0x00040000), /* True indicates that the payment is late, and includes late interest and fees. */ \
219 /* If the loan is not late, it will fail. */ \
220 /* False: not a late payment. If the current payment is overdue, the transaction will fail.*/ \
221 MASK_ADJ(0)) \
222 \
223 TRANSACTION(LoanManage, \
224 TF_FLAG(tfLoanDefault, 0x00010000) \
225 TF_FLAG(tfLoanImpair, 0x00020000) \
226 TF_FLAG(tfLoanUnimpair, 0x00040000), \
227 MASK_ADJ(0)) \
228 \
229 TRANSACTION(SponsorshipSet, \
230 TF_FLAG(tfSponsorshipSetRequireSignForFee, 0x00010000) \
231 TF_FLAG(tfSponsorshipClearRequireSignForFee, 0x00020000) \
232 TF_FLAG(tfSponsorshipSetRequireSignForReserve, 0x00040000) \
233 TF_FLAG(tfSponsorshipClearRequireSignForReserve, 0x00080000) \
234 TF_FLAG(tfDeleteObject, 0x00100000), \
235 MASK_ADJ(0)) \
236 \
237 TRANSACTION(SponsorshipTransfer, \
238 TF_FLAG(tfSponsorshipEnd, 0x00010000) \
239 TF_FLAG(tfSponsorshipCreate, 0x00020000) \
240 TF_FLAG(tfSponsorshipReassign, 0x00040000), \
241 MASK_ADJ(0))
242
243// clang-format on
244
245// Create all the flag values.
246//
247// example:
248// inline constexpr FlagValue tfAccountSetRequireDestTag = 0x00010000;
249#define TO_VALUE(name, value) inline constexpr FlagValue name = value;
250#define NULL_NAME(name, values, maskAdj) values
251#define NULL_OUTPUT(name, value)
252#define NULL_MASK_ADJ(value)
253XMACRO(NULL_NAME, TO_VALUE, NULL_OUTPUT, NULL_MASK_ADJ)
254
255// Create masks for each transaction type that has flags.
256//
257// example:
258// inline constexpr FlagValue tfAccountSetMask = ~(tfUniversal | tfRequireDestTag |
259// tfOptionalDestTag | tfRequireAuth | tfOptionalAuth | tfDisallowXRP | tfAllowXRP);
260//
261// The mask adjustment (maskAdj) allows adding flags back to the mask, making them invalid.
262// For example, Batch uses MASK_ADJ(tfInnerBatchTxn) to reject tfInnerBatchTxn on outer Batch.
263#define TO_MASK(name, values, maskAdj) \
264 inline constexpr FlagValue tf##name##Mask = ~(tfUniversal values) | (maskAdj);
265#define VALUE_TO_MASK(name, value) | name
266#define MASK_ADJ_TO_MASK(value) value
267XMACRO(TO_MASK, VALUE_TO_MASK, VALUE_TO_MASK, MASK_ADJ_TO_MASK)
268
269// Verify that tfBatchMask correctly rejects tfInnerBatchTxn.
270// The outer Batch transaction must NOT have tfInnerBatchTxn set; only inner transactions should
271// have it.
272static_assert(
273 (tfBatchMask & tfInnerBatchTxn) == tfInnerBatchTxn,
274 "tfBatchMask must include tfInnerBatchTxn to reject it on outer Batch");
275
276// Verify that other transaction masks correctly allow tfInnerBatchTxn.
277// Inner transactions need tfInnerBatchTxn to be valid, so these masks must not reject it.
278static_assert(
279 (tfPaymentMask & tfInnerBatchTxn) == 0,
280 "tfPaymentMask must not reject tfInnerBatchTxn");
281static_assert(
282 (tfAccountSetMask & tfInnerBatchTxn) == 0,
283 "tfAccountSetMask must not reject tfInnerBatchTxn");
284
285// Create getter functions for each set of flags using Meyer's singleton pattern.
286// This avoids static initialization order fiasco while still providing efficient access.
287// This is used below in `getAllTxFlags()` to generate the server_definitions RPC
288// output.
289//
290// example:
291// inline FlagMap const& getAccountSetFlags() {
292// static FlagMap const flags = {
293// {"tfRequireDestTag", 0x00010000},
294// {"tfOptionalDestTag", 0x00020000},
295// ...};
296// return flags;
297// }
299#define VALUE_TO_MAP(name, value) {#name, value},
300#define TO_MAP(name, values, maskAdj) \
301 inline FlagMap const& get##name##Flags() \
302 { \
303 static FlagMap const flags = {values}; \
304 return flags; \
305 }
306XMACRO(TO_MAP, VALUE_TO_MAP, VALUE_TO_MAP, NULL_MASK_ADJ)
307
308inline FlagMap const&
310{
311 static FlagMap const flags = {
312 {"tfFullyCanonicalSig", tfFullyCanonicalSig}, {"tfInnerBatchTxn", tfInnerBatchTxn}};
313 return flags;
314}
315
316// Create a getter function for all transaction flag maps using Meyer's singleton pattern.
317// This is used to generate the server_definitions RPC output.
318//
319// example:
320// inline FlagMapPairList const& getAllTxFlags() {
321// static FlagMapPairList const flags = {
322// {"AccountSet", getAccountSetFlags()},
323// ...};
324// return flags;
325// }
327#define ALL_TX_FLAGS(name, values, maskAdj) {#name, get##name##Flags()},
328inline FlagMapPairList const&
330{
331 static FlagMapPairList const flags = {
332 {"universal", getUniversalFlags()},
333 XMACRO(ALL_TX_FLAGS, NULL_OUTPUT, NULL_OUTPUT, NULL_MASK_ADJ)};
334 return flags;
335}
336
337#undef XMACRO
338#undef TO_VALUE
339#undef VALUE_TO_MAP
340#undef NULL_NAME
341#undef NULL_OUTPUT
342#undef TO_MAP
343#undef TO_MASK
344#undef VALUE_TO_MASK
345#undef ALL_TX_FLAGS
346#undef NULL_MASK_ADJ
347#undef MASK_ADJ_TO_MASK
348
349#pragma pop_macro("XMACRO")
350#pragma pop_macro("TO_VALUE")
351#pragma pop_macro("VALUE_TO_MAP")
352#pragma pop_macro("NULL_NAME")
353#pragma pop_macro("NULL_OUTPUT")
354#pragma pop_macro("TO_MAP")
355#pragma pop_macro("TO_MASK")
356#pragma pop_macro("VALUE_TO_MASK")
357#pragma pop_macro("ALL_TX_FLAGS")
358#pragma pop_macro("NULL_MASK_ADJ")
359#pragma pop_macro("MASK_ADJ_TO_MASK")
360
361// Additional transaction masks and combos
362inline constexpr FlagValue tfMPTPaymentMask = ~(tfUniversal | tfPartialPayment);
364 ~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
365
366// MPTokenIssuanceCreate / MPTokenIssuanceSet ImmutableFlags:
367// Defines the immutable fields and flags specific to MPTokenIssuance.
380
381// MPTokenIssuanceSet set of flags that is used to enable capabilities on an MPTokenIssuance.
382// Used as `txFlags & tfMPTokenIssuanceSetEnableFlagMask` to extract the capability-enabling bits.
383inline constexpr FlagValue tfMPTokenIssuanceSetEnableFlagMask = tfMPTSetCanLock |
384 tfMPTSetRequireAuth | tfMPTSetCanEscrow | tfMPTSetCanTrade | tfMPTSetCanTransfer |
385 tfMPTSetCanClawback | tfMPTSetCanHoldConfidentialBalance;
386
387// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
388// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
389// This was enabled by minting the NFToken with the tfTrustLine flag set.
390//
391// That capability could be used to attack the NFToken issuer.
392// It would be possible for two accounts to trade the NFToken back and forth building up any number
393// of TrustLines on the issuer, increasing the issuer's reserve without bound.
394//
395// The fixRemoveNFTokenAutoTrustLine amendment disables minting with the tfTrustLine flag as a way
396// to prevent the attack. But until the amendment passes we still need to keep the old behavior
397// available.
398inline constexpr FlagValue tfTrustLine = 0x00000004; // needed for backwards compatibility
400 ~(tfUniversal | tfBurnable | tfOnlyXRP | tfTransferable);
401
403
404// if featureDynamicNFT enabled then new flag allowing mutable URI available.
406
407inline constexpr FlagValue tfWithdrawSubTx = tfLPToken | tfSingleAsset | tfTwoAsset |
408 tfOneAssetLPToken | tfLimitLPToken | tfWithdrawAll | tfOneAssetWithdrawAll;
409inline constexpr FlagValue tfDepositSubTx =
410 tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken | tfLimitLPToken | tfTwoAssetIfEmpty;
411
412#pragma push_macro("ACCOUNTSET_FLAGS")
413#pragma push_macro("ACCOUNTSET_FLAG_TO_VALUE")
414#pragma push_macro("ACCOUNTSET_FLAG_TO_MAP")
415
416// AccountSet SetFlag/ClearFlag values
417#define ACCOUNTSET_FLAGS(ASF_FLAG) \
418 ASF_FLAG(asfRequireDest, 1) \
419 ASF_FLAG(asfRequireAuth, 2) \
420 ASF_FLAG(asfDisallowXRP, 3) \
421 ASF_FLAG(asfDisableMaster, 4) \
422 ASF_FLAG(asfAccountTxnID, 5) \
423 ASF_FLAG(asfNoFreeze, 6) \
424 ASF_FLAG(asfGlobalFreeze, 7) \
425 ASF_FLAG(asfDefaultRipple, 8) \
426 ASF_FLAG(asfDepositAuth, 9) \
427 ASF_FLAG(asfAuthorizedNFTokenMinter, 10) \
428 /* 11 is unused */ \
429 ASF_FLAG(asfDisallowIncomingNFTokenOffer, 12) \
430 ASF_FLAG(asfDisallowIncomingCheck, 13) \
431 ASF_FLAG(asfDisallowIncomingPayChan, 14) \
432 ASF_FLAG(asfDisallowIncomingTrustline, 15) \
433 ASF_FLAG(asfAllowTrustLineClawback, 16) \
434 ASF_FLAG(asfAllowTrustLineLocking, 17)
435
436#define ACCOUNTSET_FLAG_TO_VALUE(name, value) inline constexpr FlagValue name = value;
437#define ACCOUNTSET_FLAG_TO_MAP(name, value) {#name, value},
438
439ACCOUNTSET_FLAGS(ACCOUNTSET_FLAG_TO_VALUE)
440
443{
444 static std::map<std::string, FlagValue> const flags = {
445 ACCOUNTSET_FLAGS(ACCOUNTSET_FLAG_TO_MAP)};
446 return flags;
447}
448
449#undef ACCOUNTSET_FLAG_TO_VALUE
450#undef ACCOUNTSET_FLAG_TO_MAP
451#undef ACCOUNTSET_FLAGS
452
453#pragma pop_macro("ACCOUNTSET_FLAG_TO_VALUE")
454#pragma pop_macro("ACCOUNTSET_FLAG_TO_MAP")
455#pragma pop_macro("ACCOUNTSET_FLAGS")
456
457// Sponsor flags (spf)
458
459inline constexpr FlagValue spfSponsorFee = 1;
460inline constexpr FlagValue spfSponsorReserve = 2;
462
463} // namespace xrpl
464
465// NOLINTEND(readability-identifier-naming)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
constexpr FlagValue tifMPTMetadata
Definition TxFlags.h:374
constexpr FlagValue spfSponsorFee
Definition TxFlags.h:459
constexpr std::uint32_t lsifMPTCanClawback
constexpr FlagValue tfInnerBatchTxn
Definition TxFlags.h:44
std::uint32_t FlagValue
Transaction flags.
Definition TxFlags.h:40
constexpr std::uint32_t lsifMPTCanHoldConfidentialBalance
constexpr std::uint32_t lsifMPTRequireAuth
constexpr FlagValue tfDepositSubTx
Definition TxFlags.h:409
constexpr FlagValue tfTrustLine
Definition TxFlags.h:398
constexpr FlagValue tfNFTokenMintMaskWithoutMutable
Definition TxFlags.h:399
constexpr FlagValue tfNFTokenMintOldMaskWithMutable
Definition TxFlags.h:405
constexpr FlagValue tifMPTTransferFee
Definition TxFlags.h:375
constexpr FlagValue tfTrustSetPermissionMask
Definition TxFlags.h:363
constexpr std::uint32_t lsifMPTCanEscrow
constexpr FlagValue tifMPTCanEscrow
Definition TxFlags.h:370
std::vector< std::pair< std::string, FlagMap > > FlagMapPairList
Definition TxFlags.h:326
constexpr FlagValue tfUniversal
Definition TxFlags.h:45
constexpr FlagValue tifMPTCanTransfer
Definition TxFlags.h:372
constexpr FlagValue tfMPTokenIssuanceSetEnableFlagMask
Definition TxFlags.h:383
constexpr FlagValue tfMPTPaymentMask
Definition TxFlags.h:362
FlagMap const & getUniversalFlags()
Definition TxFlags.h:309
FlagMapPairList const & getAllTxFlags()
Definition TxFlags.h:329
constexpr FlagValue tifMPTokenIssuanceImmutableMask
Definition TxFlags.h:377
constexpr FlagValue tfNFTokenMintOldMask
Definition TxFlags.h:402
constexpr std::uint32_t lsifMPTCanTrade
std::map< std::string, FlagValue > FlagMap
Definition TxFlags.h:298
constexpr FlagValue tifMPTCanHoldConfidentialBalance
Definition TxFlags.h:376
constexpr std::uint32_t lsifMPTMetadata
constexpr FlagValue spfSponsorFlagMask
Definition TxFlags.h:461
constexpr FlagValue tifMPTCanClawback
Definition TxFlags.h:373
std::map< std::string, FlagValue > const & getAsfFlagMap()
Definition TxFlags.h:442
constexpr FlagValue tifMPTCanLock
Definition TxFlags.h:368
constexpr std::uint32_t lsifMPTCanLock
constexpr FlagValue tifMPTCanTrade
Definition TxFlags.h:371
constexpr FlagValue tfWithdrawSubTx
Definition TxFlags.h:407
constexpr FlagValue tfUniversalMask
Definition TxFlags.h:46
constexpr FlagValue tifMPTRequireAuth
Definition TxFlags.h:369
constexpr FlagValue spfSponsorReserve
Definition TxFlags.h:460
constexpr FlagValue tfFullyCanonicalSig
Definition TxFlags.h:43
constexpr std::uint32_t lsifMPTTransferFee
constexpr std::uint32_t lsifMPTCanTransfer