Skip to main content

spl_token_2022_interface/extension/confidential_mint_burn/
mod.rs

1use {
2    crate::{
3        error::TokenError,
4        extension::{Extension, ExtensionType},
5    },
6    bytemuck::{Pod, Zeroable},
7    solana_program_error::ProgramResult,
8    solana_zk_sdk_pod::encryption::{
9        auth_encryption::PodAeCiphertext,
10        elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
11    },
12};
13
14/// Confidential Mint-Burn Extension instructions
15pub mod instruction;
16
17/// Confidential mint-burn mint configuration
18#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
19#[repr(C)]
20pub struct ConfidentialMintBurn {
21    /// The confidential supply of the mint (encrypted by `encryption_pubkey`)
22    pub confidential_supply: PodElGamalCiphertext,
23    /// The decryptable confidential supply of the mint
24    pub decryptable_supply: PodAeCiphertext,
25    /// The ElGamal pubkey used to encrypt the confidential supply
26    pub supply_elgamal_pubkey: PodElGamalPubkey,
27    /// The amount of burn amounts not yet aggregated into the confidential supply
28    pub pending_burn: PodElGamalCiphertext,
29}
30
31impl Extension for ConfidentialMintBurn {
32    const TYPE: ExtensionType = ExtensionType::ConfidentialMintBurn;
33}
34
35impl ConfidentialMintBurn {
36    /// Checks if the mint can be closed based on confidential supply state
37    ///
38    /// The check verifies that the encrypted supply is an identically zero
39    /// ElGamal ciphertext. In case the encrypted supply is zero, but not
40    /// an identically zero ciphertext, one must use the
41    /// `RotateSupplyElGamalPubkey` to update the supply ciphertext to an
42    /// identically zero ciphertext.
43    pub fn closable(&self) -> ProgramResult {
44        if self.confidential_supply == PodElGamalCiphertext::default() {
45            Ok(())
46        } else {
47            Err(TokenError::MintHasSupply.into())
48        }
49    }
50}