Skip to main content

spl_token_2022_interface/extension/confidential_transfer_fee/
mod.rs

1use {
2    crate::{
3        error::TokenError,
4        extension::{Extension, ExtensionType},
5    },
6    bytemuck::{Pod, Zeroable},
7    solana_address::Address,
8    solana_nullable::MaybeNull,
9    solana_program_error::ProgramResult,
10    solana_zero_copy::unaligned::Bool,
11    solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
12    spl_token_confidential_transfer_proof_extraction::encryption::PodFeeCiphertext,
13};
14
15/// Confidential transfer fee extension instructions
16pub mod instruction;
17
18/// ElGamal ciphertext containing a transfer fee
19pub type EncryptedFee = PodFeeCiphertext;
20/// ElGamal ciphertext containing a withheld fee in an account
21pub type EncryptedWithheldAmount = PodElGamalCiphertext;
22
23/// Confidential transfer fee extension data for mints
24#[repr(C)]
25#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
26pub struct ConfidentialTransferFeeConfig {
27    /// Optional authority to set the withdraw withheld authority ElGamal key
28    pub authority: MaybeNull<Address>,
29
30    /// Withheld fees from accounts must be encrypted with this ElGamal key.
31    ///
32    /// Note that whoever holds the ElGamal private key for this ElGamal public
33    /// key has the ability to decode any withheld fee amount that are
34    /// associated with accounts. When combined with the fee parameters, the
35    /// withheld fee amounts can reveal information about transfer amounts.
36    pub withdraw_withheld_authority_elgamal_pubkey: PodElGamalPubkey,
37
38    /// If `false`, the harvest of withheld tokens to mint is rejected.
39    pub harvest_to_mint_enabled: Bool,
40
41    /// Withheld confidential transfer fee tokens that have been moved to the
42    /// mint for withdrawal.
43    pub withheld_amount: EncryptedWithheldAmount,
44}
45
46impl Extension for ConfidentialTransferFeeConfig {
47    const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeConfig;
48}
49
50/// Confidential transfer fee
51#[repr(C)]
52#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
53pub struct ConfidentialTransferFeeAmount {
54    /// Amount withheld during confidential transfers, to be harvest to the mint
55    pub withheld_amount: EncryptedWithheldAmount,
56}
57
58impl Extension for ConfidentialTransferFeeAmount {
59    const TYPE: ExtensionType = ExtensionType::ConfidentialTransferFeeAmount;
60}
61
62impl ConfidentialTransferFeeAmount {
63    /// Check if a confidential transfer fee account is in a closable state.
64    pub fn closable(&self) -> ProgramResult {
65        if self.withheld_amount == EncryptedWithheldAmount::zeroed() {
66            Ok(())
67        } else {
68            Err(TokenError::ConfidentialTransferFeeAccountHasWithheldFee.into())
69        }
70    }
71}