Skip to content

Conversation

@samkim-crypto
Copy link
Contributor

@samkim-crypto samkim-crypto commented Jan 2, 2026

Problem

When the ConfidentialMintBurn extension is enabled, the mint account maintains both a public supply and a confidential_supply encrypted under ElGamal. However, the SPL Token program does not verify that the confidential_supply equals zero before allowing the mint account to be closed.

As a result, a mint with a non-zero confidential supply can be prematurely closed, removing the only on-chain record needed to authorize confidential operations. Once the mint account is closed, users can no longer perform confidential transfer or burn operations. This results in an inconsistent state where confidential tokens may still exist on-chain but can no longer be utilized.

The core issue arises from an inconsistency in the design between public and confidential tokens. For standard SPL tokens without the confidential extension, the mint account cannot be closed unless the total supply is zero, which provides clear guarantees to users about the conditions under which the close authority may act. In contrast, when the ConfidentialMintBurn extension is enabled, the SPL Token program does not enforce that the confidential supply be zero prior to closing the mint. This disparity can mislead users and mint authorities into assuming that the same safety property holds in both cases, leaving them unaware that the close authority can legitimately close a mint even while confidential tokens still effectively exist. As a result, users may form incorrect expectations about the lifecycle and safety conditions of confidential token mints. Also, the inconsistent design may result with unintentional loss of fund.

Summary of Changes

Updated the program logic to require that confidential balance is zero before a mint can be closed.

@samkim-crypto samkim-crypto marked this pull request as ready for review January 7, 2026 01:51
impl ConfidentialMintBurn {
/// Checks if the mint can be closed based on confidential supply state
pub fn closable(&self) -> ProgramResult {
if self.confidential_supply == PodElGamalCiphertext::default() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies if this is a silly question, but does this work if someone has minted and then burned tokens?

For example, if I mint 10 tokens, and then burn those 10 tokens, there are 0 tokens, but confidential_supply won't be PodElGamalCiphertext::default(), correct? Is it even possible to reset the confidential_supply to PodElGamalCiphertext::default()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is a totally valid question. If we mint and then burn, then the ciphertext will most likely not be identically zero.

There is a RotateSupplyElGamalPubkey instruction that allows the authority to provide a new ciphertext for encrypted supply. The main purpose is to actually rotate the supply ElGamal public key, but it can be used to update the ciphertext as well. In the instruction, one has to provide:

  • a new ElGamal public key
  • a new ciphertext that encrypts the same supply under the new ElGamal public key
  • a ciphertext-ciphertext equality proof certifying the above

To close the mint, one can provide the same ElGamal public key and an identically zero ciphertext (assuming that the supply is zero already).

I can write a clarifying comment on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah very smart! I didn't realize that was possible with RotateSupplyElGamalPubkey. This is all good then

joncinque
joncinque previously approved these changes Jan 8, 2026
Copy link
Contributor

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, feel free to add the comment here or elsewhere

@samkim-crypto samkim-crypto merged commit abc3769 into solana-program:main Jan 8, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants