remove tmfMPTClearCanConfidentialAmount flag

This commit is contained in:
Peter Chen
2026-06-23 10:41:06 -07:00
parent d6e5aff363
commit 113c92f27e
4 changed files with 12 additions and 126 deletions

View File

@@ -368,11 +368,9 @@ inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000008;
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000010;
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000020;
inline constexpr FlagValue tmfMPTSetCanConfidentialAmount = 0x00000040;
inline constexpr FlagValue tmfMPTClearCanConfidentialAmount = 0x00000080;
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask =
~(tmfMPTSetCanLock | tmfMPTSetRequireAuth | tmfMPTSetCanEscrow | tmfMPTSetCanTrade |
tmfMPTSetCanTransfer | tmfMPTSetCanClawback | tmfMPTSetCanConfidentialAmount |
tmfMPTClearCanConfidentialAmount);
tmfMPTSetCanTransfer | tmfMPTSetCanClawback | tmfMPTSetCanConfidentialAmount);
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
// TrustLine to be added to the issuer of that token without explicit permission from that issuer.

View File

@@ -79,10 +79,8 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
auto const hasAuditorElGamalKey = ctx.tx.isFieldPresent(sfAuditorEncryptionKey);
auto const txFlags = ctx.tx.getFlags();
auto const mutablePrivacyFlags = mutableFlags
? (*mutableFlags & (tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount))
: 0u;
auto const mutatePrivacy = mutablePrivacyFlags != 0u;
bool const enablePrivacy =
mutableFlags && (*mutableFlags & tmfMPTSetCanConfidentialAmount) != 0u;
auto const hasDomain = ctx.tx.isFieldPresent(sfDomainID);
auto const hasHolder = ctx.tx.isFieldPresent(sfHolder);
@@ -90,14 +88,14 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
if (isMutate && !ctx.rules.enabled(featureDynamicMPT))
return temDISABLED;
if ((hasIssuerElGamalKey || hasAuditorElGamalKey || mutatePrivacy) &&
if ((hasIssuerElGamalKey || hasAuditorElGamalKey || enablePrivacy) &&
!ctx.rules.enabled(featureConfidentialTransfer))
return temDISABLED;
if (hasDomain && hasHolder)
return temMALFORMED;
if (mutatePrivacy && hasHolder)
if (enablePrivacy && hasHolder)
return temMALFORMED;
// fails if both flags are set
@@ -131,8 +129,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
if (transferFee && *transferFee > kMaxTransferFee)
return temBAD_TRANSFER_FEE;
if (transferFee && *transferFee > 0u &&
(mutablePrivacyFlags & tmfMPTSetCanConfidentialAmount) != 0u)
if (transferFee && *transferFee > 0u && enablePrivacy)
return temBAD_TRANSFER_FEE;
if (metadata && metadata->length() > kMaxMpTokenMetadataLength)
@@ -142,10 +139,6 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
{
if ((*mutableFlags == 0u) || ((*mutableFlags & tmfMPTokenIssuanceSetMutableMask) != 0u))
return temINVALID_FLAG;
if (mutablePrivacyFlags ==
(tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount))
return temINVALID_FLAG;
}
}
@@ -155,11 +148,6 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
if (hasAuditorElGamalKey && !hasIssuerElGamalKey)
return temMALFORMED;
// Cannot set keys while clearing confidential amount
if ((hasIssuerElGamalKey || hasAuditorElGamalKey) && mutableFlags &&
((*mutableFlags & tmfMPTClearCanConfidentialAmount) != 0u))
return temINVALID_FLAG;
if (hasIssuerElGamalKey && !isValidCompressedECPoint(ctx.tx[sfIssuerEncryptionKey]))
return temMALFORMED;
@@ -228,9 +216,9 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx)
};
auto const mutableFlags = ctx.tx[~sfMutableFlags];
auto const mutablePrivacyFlags = mutableFlags
? (*mutableFlags & (tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount))
: 0u;
// Whether the transaction is enabling confidential amounts.
bool const enablesConfidentialAmount =
mutableFlags && (*mutableFlags & tmfMPTSetCanConfidentialAmount) != 0u;
if (mutableFlags)
{
if (std::ranges::any_of(kMptMutabilityFlags, [mutableFlags, &isMutableFlag](auto const& f) {
@@ -238,7 +226,7 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx)
}))
return tecNO_PERMISSION;
if (mutablePrivacyFlags != 0u && isMutableFlag(lsmfMPTCannotMutateCanConfidentialAmount))
if (enablesConfidentialAmount && isMutableFlag(lsmfMPTCannotMutateCanConfidentialAmount))
return tecNO_PERMISSION;
}
@@ -277,10 +265,6 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx)
return tecNO_PERMISSION; // LCOV_EXCL_LINE
}
// Check if the transaction is enabling confidential amounts
bool const enablesConfidentialAmount =
(mutablePrivacyFlags & tmfMPTSetCanConfidentialAmount) != 0u;
if (enablesConfidentialAmount && sleMptIssuance->isFieldPresent(sfTransferFee) &&
(*sleMptIssuance)[sfTransferFee] > 0u)
return tecNO_PERMISSION;
@@ -301,7 +285,7 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx)
// cannot upload key if there's circulating supply of COA
if ((ctx.tx.isFieldPresent(sfIssuerEncryptionKey) ||
ctx.tx.isFieldPresent(sfAuditorEncryptionKey) || mutablePrivacyFlags != 0u) &&
ctx.tx.isFieldPresent(sfAuditorEncryptionKey) || enablesConfidentialAmount) &&
(*sleMptIssuance)[~sfConfidentialOutstandingAmount].value_or(0) > 0)
{
return tecNO_PERMISSION; // LCOV_EXCL_LINE
@@ -353,13 +337,7 @@ MPTokenIssuanceSet::doApply()
}
if ((mutableFlags & tmfMPTSetCanConfidentialAmount) != 0u)
{
flagsOut |= lsfMPTCanConfidentialAmount;
}
else if ((mutableFlags & tmfMPTClearCanConfidentialAmount) != 0u)
{
flagsOut &= ~lsfMPTCanConfidentialAmount;
}
}
if (flagsIn != flagsOut)

View File

@@ -751,14 +751,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
.err = temMALFORMED,
});
// Cannot set keys while clearing confidential amount
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
.issuerPubKey = mptAlice.getPubKey(alice),
.err = temINVALID_FLAG,
});
// Cannot set Holder and auditor Keys in the same transaction
mptAlice.set({
.account = alice,
@@ -4911,10 +4903,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
ct.mpt.pay(alice, carol, 50);
ct.mpt.convertBack({.account = bob, .amt = 50});
ct.mpt.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
});
runPublicPayments(ct.mpt);
drainAndDeleteBobMPToken(env, ct.mpt);
@@ -4951,10 +4939,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
});
mptAlice.mergeInbox({.account = bob});
mptAlice.convertBack({.account = bob, .amt = 50});
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
});
runPublicPayments(mptAlice);
drainAndDeleteBobMPToken(env, mptAlice);
@@ -4975,10 +4959,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
ct.mpt.pay(alice, carol, 50);
ct.mpt.confidentialClaw({.account = alice, .holder = bob, .amt = 50});
ct.mpt.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
});
runPublicPayments(ct.mpt);
drainAndDeleteBobMPToken(env, ct.mpt);
@@ -5040,12 +5020,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
.mutableFlags = tmfMPTSetCanConfidentialAmount,
.err = tecNO_PERMISSION,
});
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
.err = tecNO_PERMISSION,
});
}
// Toggle lsfMPTCanConfidentialAmount
@@ -5114,21 +5088,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
});
verifyToggle(tesSUCCESS, 10);
// clear lsfMPTCanConfidentialAmount
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
});
verifyToggle(tecNO_PERMISSION, 10);
// can clear lsfMPTCanConfidentialAmount again but has no effect
// for privacy settings
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount | tmfMPTSetCanLock,
});
verifyToggle(tecNO_PERMISSION, 20);
// set lsfMPTCanConfidentialAmount again
mptAlice.set({
.account = alice,
@@ -5164,56 +5123,13 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
// bob convert 50 to confidential
mptAlice.convert({.account = bob, .amt = 50, .holderPubKey = mptAlice.getPubKey(bob)});
// set or clear lsfMPTCanConfidentialAmount should fail because of
// set lsfMPTCanConfidentialAmount should fail because of
// confidential outstanding balance
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTSetCanConfidentialAmount,
.err = tecNO_PERMISSION,
});
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
.err = tecNO_PERMISSION,
});
// bob merge inbox
mptAlice.mergeInbox({
.account = bob,
});
// bob convert back all confidential balance
mptAlice.convertBack({
.account = bob,
.amt = 50,
});
// now clear lsfMPTCanConfidentialAmount should succeed,
// because there's no confidential outstanding balance
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTClearCanConfidentialAmount,
});
// bob can not convert because lsfMPTCanConfidentialAmount was cleared
// successfully
mptAlice.convert({
.account = bob,
.amt = 10,
.holderPubKey = mptAlice.getPubKey(bob),
.err = tecNO_PERMISSION,
});
// can set lsfMPTCanConfidentialAmount again when there's no confidential
// outstanding balance
mptAlice.set({
.account = alice,
.mutableFlags = tmfMPTSetCanConfidentialAmount,
});
mptAlice.convert({
.account = bob,
.amt = 10,
});
}
}

View File

@@ -522,13 +522,7 @@ MPTTester::set(MPTSet const& arg)
}
if (*arg.mutableFlags & tmfMPTSetCanConfidentialAmount)
{
flags |= lsfMPTCanConfidentialAmount;
}
else if (*arg.mutableFlags & tmfMPTClearCanConfidentialAmount)
{
flags &= ~lsfMPTCanConfidentialAmount;
}
}
}
env_.require(MptFlags(*this, flags, holder));