[confidential-extension] Use `OptionalNonZeroPubkey` and `OptionalNonZeroEncryptionPubkey` for confidential extension (#3943)
* use OptionalNonZeroPubkey for the confidential mint authority pubkey * add OptionalNonZeroEncryptionPubkey * update tests * Update token/program-2022/src/pod.rs Co-authored-by: Jon Cinque <jon.cinque@gmail.com> * remove unnecessary COption convertion for OptionalNonZeroEncryptionPubkey Co-authored-by: Jon Cinque <jon.cinque@gmail.com>
This commit is contained in:
parent
19b8fae56c
commit
b9aba3fb8d
|
@ -20,11 +20,12 @@ use {
|
||||||
},
|
},
|
||||||
spl_token_2022::{
|
spl_token_2022::{
|
||||||
extension::{
|
extension::{
|
||||||
confidential_transfer, confidential_transfer::EncryptionPubkey, cpi_guard,
|
confidential_transfer, cpi_guard, default_account_state, interest_bearing_mint,
|
||||||
default_account_state, interest_bearing_mint, memo_transfer, transfer_fee,
|
memo_transfer, transfer_fee, BaseStateWithExtensions, ExtensionType,
|
||||||
BaseStateWithExtensions, ExtensionType, StateWithExtensionsOwned,
|
StateWithExtensionsOwned,
|
||||||
},
|
},
|
||||||
instruction,
|
instruction,
|
||||||
|
pod::EncryptionPubkey,
|
||||||
solana_zk_token_sdk::{
|
solana_zk_token_sdk::{
|
||||||
encryption::{auth_encryption::*, elgamal::*},
|
encryption::{auth_encryption::*, elgamal::*},
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
|
@ -106,8 +107,8 @@ pub enum ExtensionInitializationParams {
|
||||||
ConfidentialTransferMint {
|
ConfidentialTransferMint {
|
||||||
authority: Option<Pubkey>,
|
authority: Option<Pubkey>,
|
||||||
auto_approve_new_accounts: bool,
|
auto_approve_new_accounts: bool,
|
||||||
auditor_encryption_pubkey: EncryptionPubkey,
|
auditor_encryption_pubkey: Option<EncryptionPubkey>,
|
||||||
withdraw_withheld_authority_encryption_pubkey: EncryptionPubkey,
|
withdraw_withheld_authority_encryption_pubkey: Option<EncryptionPubkey>,
|
||||||
},
|
},
|
||||||
DefaultAccountState {
|
DefaultAccountState {
|
||||||
state: AccountState,
|
state: AccountState,
|
||||||
|
@ -158,10 +159,10 @@ impl ExtensionInitializationParams {
|
||||||
} => confidential_transfer::instruction::initialize_mint(
|
} => confidential_transfer::instruction::initialize_mint(
|
||||||
token_program_id,
|
token_program_id,
|
||||||
mint,
|
mint,
|
||||||
authority.as_ref(),
|
authority,
|
||||||
auto_approve_new_accounts,
|
auto_approve_new_accounts,
|
||||||
&auditor_encryption_pubkey,
|
auditor_encryption_pubkey,
|
||||||
&withdraw_withheld_authority_encryption_pubkey,
|
withdraw_withheld_authority_encryption_pubkey,
|
||||||
),
|
),
|
||||||
Self::DefaultAccountState { state } => {
|
Self::DefaultAccountState { state } => {
|
||||||
default_account_state::instruction::initialize_default_account_state(
|
default_account_state::instruction::initialize_default_account_state(
|
||||||
|
@ -1492,7 +1493,7 @@ where
|
||||||
authority: &S,
|
authority: &S,
|
||||||
new_authority: Option<&S>,
|
new_authority: Option<&S>,
|
||||||
auto_approve_new_account: bool,
|
auto_approve_new_account: bool,
|
||||||
auditor_encryption_pubkey: &EncryptionPubkey,
|
auditor_encryption_pubkey: Option<EncryptionPubkey>,
|
||||||
) -> TokenResult<T::Output> {
|
) -> TokenResult<T::Output> {
|
||||||
let mut signers = vec![authority];
|
let mut signers = vec![authority];
|
||||||
let new_authority_pubkey = if let Some(new_authority) = new_authority {
|
let new_authority_pubkey = if let Some(new_authority) = new_authority {
|
||||||
|
@ -1789,16 +1790,20 @@ where
|
||||||
/// Fetch the ElGamal pubkey key of the auditor associated with a confidential token mint
|
/// Fetch the ElGamal pubkey key of the auditor associated with a confidential token mint
|
||||||
pub async fn confidential_transfer_get_auditor_encryption_pubkey<S: Signer>(
|
pub async fn confidential_transfer_get_auditor_encryption_pubkey<S: Signer>(
|
||||||
&self,
|
&self,
|
||||||
) -> TokenResult<ElGamalPubkey> {
|
) -> TokenResult<Option<ElGamalPubkey>> {
|
||||||
let mint_state = self.get_mint_info().await.unwrap();
|
let mint_state = self.get_mint_info().await.unwrap();
|
||||||
let ct_mint =
|
let ct_mint =
|
||||||
mint_state.get_extension::<confidential_transfer::ConfidentialTransferMint>()?;
|
mint_state.get_extension::<confidential_transfer::ConfidentialTransferMint>()?;
|
||||||
let auditor_pubkey = ct_mint
|
let auditor_encryption_pubkey: Option<EncryptionPubkey> =
|
||||||
.auditor_encryption_pubkey
|
ct_mint.auditor_encryption_pubkey.into();
|
||||||
.try_into()
|
|
||||||
.map_err(TokenError::Proof)?;
|
|
||||||
|
|
||||||
Ok(auditor_pubkey)
|
if let Some(encryption_pubkey) = auditor_encryption_pubkey {
|
||||||
|
let encryption_pubkey: ElGamalPubkey =
|
||||||
|
encryption_pubkey.try_into().map_err(TokenError::Proof)?;
|
||||||
|
Ok(Some(encryption_pubkey))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the ElGamal pubkey key of the withdraw withheld authority associated with a
|
/// Fetch the ElGamal pubkey key of the withdraw withheld authority associated with a
|
||||||
|
@ -1807,16 +1812,20 @@ where
|
||||||
S: Signer,
|
S: Signer,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
) -> TokenResult<ElGamalPubkey> {
|
) -> TokenResult<Option<ElGamalPubkey>> {
|
||||||
let mint_state = self.get_mint_info().await.unwrap();
|
let mint_state = self.get_mint_info().await.unwrap();
|
||||||
let ct_mint =
|
let ct_mint =
|
||||||
mint_state.get_extension::<confidential_transfer::ConfidentialTransferMint>()?;
|
mint_state.get_extension::<confidential_transfer::ConfidentialTransferMint>()?;
|
||||||
let auditor_pubkey = ct_mint
|
let withdraw_withheld_authority_encryption_pubkey: Option<EncryptionPubkey> =
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
ct_mint.withdraw_withheld_authority_encryption_pubkey.into();
|
||||||
.try_into()
|
|
||||||
.map_err(TokenError::Proof)?;
|
|
||||||
|
|
||||||
Ok(auditor_pubkey)
|
if let Some(encryption_pubkey) = withdraw_withheld_authority_encryption_pubkey {
|
||||||
|
let encryption_pubkey: ElGamalPubkey =
|
||||||
|
encryption_pubkey.try_into().map_err(TokenError::Proof)?;
|
||||||
|
Ok(Some(encryption_pubkey))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deposit SPL Tokens into the pending balance of a confidential token account
|
/// Deposit SPL Tokens into the pending balance of a confidential token account
|
||||||
|
@ -1932,7 +1941,7 @@ where
|
||||||
source_available_balance: u64,
|
source_available_balance: u64,
|
||||||
source_available_balance_ciphertext: &ElGamalCiphertext,
|
source_available_balance_ciphertext: &ElGamalCiphertext,
|
||||||
destination_elgamal_pubkey: &ElGamalPubkey,
|
destination_elgamal_pubkey: &ElGamalPubkey,
|
||||||
auditor_elgamal_pubkey: &ElGamalPubkey,
|
auditor_elgamal_pubkey: Option<ElGamalPubkey>,
|
||||||
) -> TokenResult<T::Output> {
|
) -> TokenResult<T::Output> {
|
||||||
let source_elgamal_keypair =
|
let source_elgamal_keypair =
|
||||||
ElGamalKeypair::new(source_token_authority, source_token_account)
|
ElGamalKeypair::new(source_token_authority, source_token_account)
|
||||||
|
@ -1966,7 +1975,7 @@ where
|
||||||
source_available_balance: u64,
|
source_available_balance: u64,
|
||||||
source_available_balance_ciphertext: &ElGamalCiphertext,
|
source_available_balance_ciphertext: &ElGamalCiphertext,
|
||||||
destination_elgamal_pubkey: &ElGamalPubkey,
|
destination_elgamal_pubkey: &ElGamalPubkey,
|
||||||
auditor_elgamal_pubkey: &ElGamalPubkey,
|
auditor_elgamal_pubkey: Option<ElGamalPubkey>,
|
||||||
source_elgamal_keypair: &ElGamalKeypair,
|
source_elgamal_keypair: &ElGamalKeypair,
|
||||||
source_authenticated_encryption_key: &AeKey,
|
source_authenticated_encryption_key: &AeKey,
|
||||||
) -> TokenResult<T::Output> {
|
) -> TokenResult<T::Output> {
|
||||||
|
@ -1974,6 +1983,8 @@ where
|
||||||
return Err(TokenError::MaximumDepositTransferAmountExceeded);
|
return Err(TokenError::MaximumDepositTransferAmountExceeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let auditor_elgamal_pubkey = auditor_elgamal_pubkey.unwrap_or_default();
|
||||||
|
|
||||||
let proof_data = confidential_transfer::instruction::TransferData::new(
|
let proof_data = confidential_transfer::instruction::TransferData::new(
|
||||||
amount,
|
amount,
|
||||||
(
|
(
|
||||||
|
@ -1981,7 +1992,7 @@ where
|
||||||
source_available_balance_ciphertext,
|
source_available_balance_ciphertext,
|
||||||
),
|
),
|
||||||
source_elgamal_keypair,
|
source_elgamal_keypair,
|
||||||
(destination_elgamal_pubkey, auditor_elgamal_pubkey),
|
(destination_elgamal_pubkey, &auditor_elgamal_pubkey),
|
||||||
)
|
)
|
||||||
.map_err(TokenError::Proof)?;
|
.map_err(TokenError::Proof)?;
|
||||||
|
|
||||||
|
@ -2019,7 +2030,7 @@ where
|
||||||
source_available_balance: u64,
|
source_available_balance: u64,
|
||||||
source_available_balance_ciphertext: &ElGamalCiphertext,
|
source_available_balance_ciphertext: &ElGamalCiphertext,
|
||||||
destination_elgamal_pubkey: &ElGamalPubkey,
|
destination_elgamal_pubkey: &ElGamalPubkey,
|
||||||
auditor_elgamal_pubkey: &ElGamalPubkey,
|
auditor_elgamal_pubkey: Option<ElGamalPubkey>,
|
||||||
withdraw_withheld_authority_elgamal_pubkey: &ElGamalPubkey,
|
withdraw_withheld_authority_elgamal_pubkey: &ElGamalPubkey,
|
||||||
epoch_info: &EpochInfo,
|
epoch_info: &EpochInfo,
|
||||||
) -> TokenResult<T::Output> {
|
) -> TokenResult<T::Output> {
|
||||||
|
@ -2057,7 +2068,7 @@ where
|
||||||
source_available_balance: u64,
|
source_available_balance: u64,
|
||||||
source_available_balance_ciphertext: &ElGamalCiphertext,
|
source_available_balance_ciphertext: &ElGamalCiphertext,
|
||||||
destination_elgamal_pubkey: &ElGamalPubkey,
|
destination_elgamal_pubkey: &ElGamalPubkey,
|
||||||
auditor_elgamal_pubkey: &ElGamalPubkey,
|
auditor_elgamal_pubkey: Option<ElGamalPubkey>,
|
||||||
withdraw_withheld_authority_elgamal_pubkey: &ElGamalPubkey,
|
withdraw_withheld_authority_elgamal_pubkey: &ElGamalPubkey,
|
||||||
source_elgamal_keypair: &ElGamalKeypair,
|
source_elgamal_keypair: &ElGamalKeypair,
|
||||||
source_authenticated_encryption_key: &AeKey,
|
source_authenticated_encryption_key: &AeKey,
|
||||||
|
@ -2067,7 +2078,8 @@ where
|
||||||
return Err(TokenError::MaximumDepositTransferAmountExceeded);
|
return Err(TokenError::MaximumDepositTransferAmountExceeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: take transfer fee params as input
|
let auditor_elgamal_pubkey = auditor_elgamal_pubkey.unwrap_or_default();
|
||||||
|
|
||||||
let mint_state = self.get_mint_info().await.unwrap();
|
let mint_state = self.get_mint_info().await.unwrap();
|
||||||
let transfer_fee_config = mint_state
|
let transfer_fee_config = mint_state
|
||||||
.get_extension::<transfer_fee::TransferFeeConfig>()
|
.get_extension::<transfer_fee::TransferFeeConfig>()
|
||||||
|
@ -2081,7 +2093,7 @@ where
|
||||||
source_available_balance_ciphertext,
|
source_available_balance_ciphertext,
|
||||||
),
|
),
|
||||||
source_elgamal_keypair,
|
source_elgamal_keypair,
|
||||||
(destination_elgamal_pubkey, auditor_elgamal_pubkey),
|
(destination_elgamal_pubkey, &auditor_elgamal_pubkey),
|
||||||
FeeParameters {
|
FeeParameters {
|
||||||
fee_rate_basis_points: u16::from(fee_parameters.transfer_fee_basis_points),
|
fee_rate_basis_points: u16::from(fee_parameters.transfer_fee_basis_points),
|
||||||
maximum_fee: u64::from(fee_parameters.maximum_fee),
|
maximum_fee: u64::from(fee_parameters.maximum_fee),
|
||||||
|
|
|
@ -17,6 +17,7 @@ use {
|
||||||
},
|
},
|
||||||
BaseStateWithExtensions, ExtensionType,
|
BaseStateWithExtensions, ExtensionType,
|
||||||
},
|
},
|
||||||
|
pod::EncryptionPubkey,
|
||||||
solana_zk_token_sdk::{
|
solana_zk_token_sdk::{
|
||||||
encryption::{auth_encryption::*, elgamal::*},
|
encryption::{auth_encryption::*, elgamal::*},
|
||||||
zk_token_elgamal::pod::Zeroable,
|
zk_token_elgamal::pod::Zeroable,
|
||||||
|
@ -53,9 +54,7 @@ fn test_epoch_info() -> EpochInfo {
|
||||||
struct ConfidentialTransferMintWithKeypairs {
|
struct ConfidentialTransferMintWithKeypairs {
|
||||||
ct_mint: ConfidentialTransferMint,
|
ct_mint: ConfidentialTransferMint,
|
||||||
ct_mint_authority: Keypair,
|
ct_mint_authority: Keypair,
|
||||||
#[allow(dead_code)]
|
|
||||||
ct_mint_transfer_auditor_encryption_keypair: ElGamalKeypair,
|
ct_mint_transfer_auditor_encryption_keypair: ElGamalKeypair,
|
||||||
#[allow(dead_code)]
|
|
||||||
ct_mint_withdraw_withheld_authority_encryption_keypair: ElGamalKeypair,
|
ct_mint_withdraw_withheld_authority_encryption_keypair: ElGamalKeypair,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,15 +62,28 @@ impl ConfidentialTransferMintWithKeypairs {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let ct_mint_authority = Keypair::new();
|
let ct_mint_authority = Keypair::new();
|
||||||
let ct_mint_transfer_auditor_encryption_keypair = ElGamalKeypair::new_rand();
|
let ct_mint_transfer_auditor_encryption_keypair = ElGamalKeypair::new_rand();
|
||||||
|
let ct_mint_transfer_auditor_encryption_pubkey: EncryptionPubkey =
|
||||||
|
ct_mint_transfer_auditor_encryption_keypair
|
||||||
|
.public
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
let ct_mint_withdraw_withheld_authority_encryption_keypair = ElGamalKeypair::new_rand();
|
let ct_mint_withdraw_withheld_authority_encryption_keypair = ElGamalKeypair::new_rand();
|
||||||
|
let ct_mint_withdraw_withheld_authority_encryption_pubkey: EncryptionPubkey =
|
||||||
|
ct_mint_withdraw_withheld_authority_encryption_keypair
|
||||||
|
.public
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
let ct_mint = ConfidentialTransferMint {
|
let ct_mint = ConfidentialTransferMint {
|
||||||
authority: ct_mint_authority.pubkey(),
|
authority: Some(ct_mint_authority.pubkey()).try_into().unwrap(),
|
||||||
auto_approve_new_accounts: true.into(),
|
auto_approve_new_accounts: true.into(),
|
||||||
auditor_encryption_pubkey: ct_mint_transfer_auditor_encryption_keypair.public.into(),
|
auditor_encryption_pubkey: Some(ct_mint_transfer_auditor_encryption_pubkey)
|
||||||
withdraw_withheld_authority_encryption_pubkey:
|
.try_into()
|
||||||
ct_mint_withdraw_withheld_authority_encryption_keypair
|
.unwrap(),
|
||||||
.public
|
withdraw_withheld_authority_encryption_pubkey: Some(
|
||||||
.into(),
|
ct_mint_withdraw_withheld_authority_encryption_pubkey,
|
||||||
|
)
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
withheld_amount: EncryptedWithheldAmount::zeroed(),
|
withheld_amount: EncryptedWithheldAmount::zeroed(),
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
|
@ -286,11 +298,12 @@ async fn ct_initialize_and_update_mint() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -305,7 +318,7 @@ async fn ct_initialize_and_update_mint() {
|
||||||
// Change the authority
|
// Change the authority
|
||||||
let new_ct_mint_authority = Keypair::new();
|
let new_ct_mint_authority = Keypair::new();
|
||||||
let new_ct_mint = ConfidentialTransferMint {
|
let new_ct_mint = ConfidentialTransferMint {
|
||||||
authority: new_ct_mint_authority.pubkey(),
|
authority: Some(new_ct_mint_authority.pubkey()).try_into().unwrap(),
|
||||||
..ConfidentialTransferMint::default()
|
..ConfidentialTransferMint::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,10 +327,9 @@ async fn ct_initialize_and_update_mint() {
|
||||||
&wrong_keypair,
|
&wrong_keypair,
|
||||||
Some(&new_ct_mint_authority),
|
Some(&new_ct_mint_authority),
|
||||||
new_ct_mint.auto_approve_new_accounts.into(),
|
new_ct_mint.auto_approve_new_accounts.into(),
|
||||||
&new_ct_mint
|
new_ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
.try_into()
|
.into(),
|
||||||
.unwrap(),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
@ -332,10 +344,9 @@ async fn ct_initialize_and_update_mint() {
|
||||||
&ct_mint_authority,
|
&ct_mint_authority,
|
||||||
Some(&new_ct_mint_authority),
|
Some(&new_ct_mint_authority),
|
||||||
new_ct_mint.auto_approve_new_accounts.into(),
|
new_ct_mint.auto_approve_new_accounts.into(),
|
||||||
&new_ct_mint
|
new_ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
.try_into()
|
.into(),
|
||||||
.unwrap(),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -364,10 +375,9 @@ async fn ct_initialize_and_update_mint() {
|
||||||
&new_ct_mint_authority,
|
&new_ct_mint_authority,
|
||||||
None,
|
None,
|
||||||
new_ct_mint.auto_approve_new_accounts.into(),
|
new_ct_mint.auto_approve_new_accounts.into(),
|
||||||
&new_ct_mint
|
new_ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
.try_into()
|
.into(),
|
||||||
.unwrap(),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -402,11 +412,12 @@ async fn ct_configure_token_account() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -479,11 +490,12 @@ async fn ct_enable_disable_confidential_credits() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -527,11 +539,12 @@ async fn ct_enable_disable_non_confidential_credits() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -624,11 +637,12 @@ async fn ct_new_account_is_empty() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -652,11 +666,12 @@ async fn ct_deposit() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -782,11 +797,12 @@ async fn ct_withdraw() {
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -885,17 +901,21 @@ async fn ct_withdraw() {
|
||||||
#[cfg(feature = "zk-ops")]
|
#[cfg(feature = "zk-ops")]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ct_transfer() {
|
async fn ct_transfer() {
|
||||||
let ConfidentialTransferMintWithKeypairs { ct_mint, .. } =
|
let ConfidentialTransferMintWithKeypairs {
|
||||||
ConfidentialTransferMintWithKeypairs::new();
|
ct_mint,
|
||||||
|
ct_mint_transfer_auditor_encryption_keypair,
|
||||||
|
..
|
||||||
|
} = ConfidentialTransferMintWithKeypairs::new();
|
||||||
let mut context = TestContext::new().await;
|
let mut context = TestContext::new().await;
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -932,7 +952,7 @@ async fn ct_transfer() {
|
||||||
42,
|
42,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&alice_meta.elgamal_keypair.public,
|
&alice_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -967,7 +987,7 @@ async fn ct_transfer() {
|
||||||
42,
|
42,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&alice_meta.elgamal_keypair.public,
|
&alice_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1001,7 +1021,7 @@ async fn ct_transfer() {
|
||||||
0,
|
0,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&alice_meta.elgamal_keypair.public,
|
&alice_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
@ -1052,7 +1072,7 @@ async fn ct_transfer() {
|
||||||
42,
|
42,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1122,8 +1142,12 @@ async fn ct_transfer() {
|
||||||
#[cfg(feature = "zk-ops")]
|
#[cfg(feature = "zk-ops")]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ct_transfer_with_fee() {
|
async fn ct_transfer_with_fee() {
|
||||||
let ConfidentialTransferMintWithKeypairs { ct_mint, .. } =
|
let ConfidentialTransferMintWithKeypairs {
|
||||||
ConfidentialTransferMintWithKeypairs::new();
|
ct_mint,
|
||||||
|
ct_mint_transfer_auditor_encryption_keypair,
|
||||||
|
ct_mint_withdraw_withheld_authority_encryption_keypair,
|
||||||
|
..
|
||||||
|
} = ConfidentialTransferMintWithKeypairs::new();
|
||||||
|
|
||||||
let mut context = TestContext::new().await;
|
let mut context = TestContext::new().await;
|
||||||
context
|
context
|
||||||
|
@ -1135,11 +1159,12 @@ async fn ct_transfer_with_fee() {
|
||||||
maximum_fee: TEST_MAXIMUM_FEE,
|
maximum_fee: TEST_MAXIMUM_FEE,
|
||||||
},
|
},
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -1179,7 +1204,7 @@ async fn ct_transfer_with_fee() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&alice_meta.elgamal_keypair.public,
|
&alice_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1214,7 +1239,7 @@ async fn ct_transfer_with_fee() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&alice_meta.elgamal_keypair.public,
|
&alice_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1265,11 +1290,8 @@ async fn ct_transfer_with_fee() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
&ct_mint
|
&ct_mint_withdraw_withheld_authority_encryption_keypair.public,
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
&epoch_info,
|
&epoch_info,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -1343,6 +1365,7 @@ async fn ct_transfer_with_fee() {
|
||||||
async fn ct_withdraw_withheld_tokens_from_mint() {
|
async fn ct_withdraw_withheld_tokens_from_mint() {
|
||||||
let ConfidentialTransferMintWithKeypairs {
|
let ConfidentialTransferMintWithKeypairs {
|
||||||
ct_mint,
|
ct_mint,
|
||||||
|
ct_mint_transfer_auditor_encryption_keypair,
|
||||||
ct_mint_withdraw_withheld_authority_encryption_keypair,
|
ct_mint_withdraw_withheld_authority_encryption_keypair,
|
||||||
..
|
..
|
||||||
} = ConfidentialTransferMintWithKeypairs::new();
|
} = ConfidentialTransferMintWithKeypairs::new();
|
||||||
|
@ -1359,11 +1382,12 @@ async fn ct_withdraw_withheld_tokens_from_mint() {
|
||||||
maximum_fee: TEST_MAXIMUM_FEE,
|
maximum_fee: TEST_MAXIMUM_FEE,
|
||||||
},
|
},
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -1434,11 +1458,8 @@ async fn ct_withdraw_withheld_tokens_from_mint() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
&ct_mint
|
&ct_mint_withdraw_withheld_authority_encryption_keypair.public,
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
&epoch_info,
|
&epoch_info,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -1521,11 +1542,12 @@ async fn ct_withdraw_withheld_tokens_from_accounts() {
|
||||||
maximum_fee: TEST_MAXIMUM_FEE,
|
maximum_fee: TEST_MAXIMUM_FEE,
|
||||||
},
|
},
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -1565,7 +1587,7 @@ async fn ct_withdraw_withheld_tokens_from_accounts() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint_transfer_auditor_encryption_keypair.public,
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
&ct_mint_withdraw_withheld_authority_encryption_keypair.public,
|
&ct_mint_withdraw_withheld_authority_encryption_keypair.public,
|
||||||
&epoch_info,
|
&epoch_info,
|
||||||
)
|
)
|
||||||
|
@ -1628,17 +1650,21 @@ async fn ct_withdraw_withheld_tokens_from_accounts() {
|
||||||
#[cfg(feature = "zk-ops")]
|
#[cfg(feature = "zk-ops")]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ct_transfer_memo() {
|
async fn ct_transfer_memo() {
|
||||||
let ConfidentialTransferMintWithKeypairs { ct_mint, .. } =
|
let ConfidentialTransferMintWithKeypairs {
|
||||||
ConfidentialTransferMintWithKeypairs::new();
|
ct_mint,
|
||||||
|
ct_mint_transfer_auditor_encryption_keypair,
|
||||||
|
..
|
||||||
|
} = ConfidentialTransferMintWithKeypairs::new();
|
||||||
let mut context = TestContext::new().await;
|
let mut context = TestContext::new().await;
|
||||||
context
|
context
|
||||||
.init_token_with_mint(vec![
|
.init_token_with_mint(vec![
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -1676,7 +1702,7 @@ async fn ct_transfer_memo() {
|
||||||
42,
|
42,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
@ -1702,7 +1728,7 @@ async fn ct_transfer_memo() {
|
||||||
42,
|
42,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1735,8 +1761,12 @@ async fn ct_transfer_memo() {
|
||||||
#[cfg(feature = "zk-ops")]
|
#[cfg(feature = "zk-ops")]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ct_transfer_with_fee_memo() {
|
async fn ct_transfer_with_fee_memo() {
|
||||||
let ConfidentialTransferMintWithKeypairs { ct_mint, .. } =
|
let ConfidentialTransferMintWithKeypairs {
|
||||||
ConfidentialTransferMintWithKeypairs::new();
|
ct_mint,
|
||||||
|
ct_mint_transfer_auditor_encryption_keypair,
|
||||||
|
ct_mint_withdraw_withheld_authority_encryption_keypair,
|
||||||
|
..
|
||||||
|
} = ConfidentialTransferMintWithKeypairs::new();
|
||||||
|
|
||||||
let mut context = TestContext::new().await;
|
let mut context = TestContext::new().await;
|
||||||
context
|
context
|
||||||
|
@ -1748,11 +1778,12 @@ async fn ct_transfer_with_fee_memo() {
|
||||||
maximum_fee: TEST_MAXIMUM_FEE,
|
maximum_fee: TEST_MAXIMUM_FEE,
|
||||||
},
|
},
|
||||||
ExtensionInitializationParams::ConfidentialTransferMint {
|
ExtensionInitializationParams::ConfidentialTransferMint {
|
||||||
authority: Some(ct_mint.authority),
|
authority: ct_mint.authority.into(),
|
||||||
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
|
||||||
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
|
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey.into(),
|
||||||
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
withdraw_withheld_authority_encryption_pubkey: ct_mint
|
||||||
.withdraw_withheld_authority_encryption_pubkey,
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.await
|
.await
|
||||||
|
@ -1792,11 +1823,8 @@ async fn ct_transfer_with_fee_memo() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
&ct_mint
|
&ct_mint_withdraw_withheld_authority_encryption_keypair.public,
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
&epoch_info,
|
&epoch_info,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -1822,11 +1850,8 @@ async fn ct_transfer_with_fee_memo() {
|
||||||
100,
|
100,
|
||||||
&extension.available_balance.try_into().unwrap(),
|
&extension.available_balance.try_into().unwrap(),
|
||||||
&bob_meta.elgamal_keypair.public,
|
&bob_meta.elgamal_keypair.public,
|
||||||
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
|
Some(ct_mint_transfer_auditor_encryption_keypair.public),
|
||||||
&ct_mint
|
&ct_mint_withdraw_withheld_authority_encryption_keypair.public,
|
||||||
.withdraw_withheld_authority_encryption_pubkey
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
&epoch_info,
|
&epoch_info,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -431,14 +431,14 @@ pub enum ConfidentialTransferInstruction {
|
||||||
pub struct InitializeMintData {
|
pub struct InitializeMintData {
|
||||||
/// Authority to modify the `ConfidentialTransferMint` configuration and to approve new
|
/// Authority to modify the `ConfidentialTransferMint` configuration and to approve new
|
||||||
/// accounts.
|
/// accounts.
|
||||||
pub authority: Pubkey,
|
pub authority: OptionalNonZeroPubkey,
|
||||||
/// Determines if newly configured accounts must be approved by the `authority` before they may
|
/// Determines if newly configured accounts must be approved by the `authority` before they may
|
||||||
/// be used by the user.
|
/// be used by the user.
|
||||||
pub auto_approve_new_accounts: PodBool,
|
pub auto_approve_new_accounts: PodBool,
|
||||||
/// New authority to decode any transfer amount in a confidential transfer.
|
/// New authority to decode any transfer amount in a confidential transfer.
|
||||||
pub auditor_encryption_pubkey: EncryptionPubkey,
|
pub auditor_encryption_pubkey: OptionalNonZeroEncryptionPubkey,
|
||||||
/// Authority to withdraw withheld fees that are associated with accounts.
|
/// Authority to withdraw withheld fees that are associated with accounts.
|
||||||
pub withdraw_withheld_authority_encryption_pubkey: EncryptionPubkey,
|
pub withdraw_withheld_authority_encryption_pubkey: OptionalNonZeroEncryptionPubkey,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data expected by `ConfidentialTransferInstruction::UpdateMint`
|
/// Data expected by `ConfidentialTransferInstruction::UpdateMint`
|
||||||
|
@ -449,7 +449,7 @@ pub struct UpdateMintData {
|
||||||
/// be used by the user.
|
/// be used by the user.
|
||||||
pub auto_approve_new_accounts: PodBool,
|
pub auto_approve_new_accounts: PodBool,
|
||||||
/// New authority to decode any transfer amount in a confidential transfer.
|
/// New authority to decode any transfer amount in a confidential transfer.
|
||||||
pub auditor_encryption_pubkey: EncryptionPubkey,
|
pub auditor_encryption_pubkey: OptionalNonZeroEncryptionPubkey,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data expected by `ConfidentialTransferInstruction::ConfigureAccount`
|
/// Data expected by `ConfidentialTransferInstruction::ConfigureAccount`
|
||||||
|
@ -547,32 +547,25 @@ pub struct WithdrawWithheldTokensFromAccountsData {
|
||||||
pub fn initialize_mint(
|
pub fn initialize_mint(
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
mint: &Pubkey,
|
mint: &Pubkey,
|
||||||
authority: Option<&Pubkey>,
|
authority: Option<Pubkey>,
|
||||||
auto_approve_new_accounts: bool,
|
auto_approve_new_accounts: bool,
|
||||||
auditor_encryption_pubkey: &EncryptionPubkey,
|
auditor_encryption_pubkey: Option<EncryptionPubkey>,
|
||||||
withdraw_withheld_authority_encryption_pubkey: &EncryptionPubkey,
|
withdraw_withheld_authority_encryption_pubkey: Option<EncryptionPubkey>,
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
check_program_account(token_program_id)?;
|
check_program_account(token_program_id)?;
|
||||||
let accounts = vec![AccountMeta::new(*mint, false)];
|
let accounts = vec![AccountMeta::new(*mint, false)];
|
||||||
|
|
||||||
// TODO: use `OptionalNonZeroPubkey`
|
|
||||||
let authority = if let Some(authority) = authority {
|
|
||||||
*authority
|
|
||||||
} else {
|
|
||||||
Pubkey::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(encode_instruction(
|
Ok(encode_instruction(
|
||||||
token_program_id,
|
token_program_id,
|
||||||
accounts,
|
accounts,
|
||||||
TokenInstruction::ConfidentialTransferExtension,
|
TokenInstruction::ConfidentialTransferExtension,
|
||||||
ConfidentialTransferInstruction::InitializeMint,
|
ConfidentialTransferInstruction::InitializeMint,
|
||||||
&InitializeMintData {
|
&InitializeMintData {
|
||||||
authority,
|
authority: authority.try_into()?,
|
||||||
auto_approve_new_accounts: auto_approve_new_accounts.into(),
|
auto_approve_new_accounts: auto_approve_new_accounts.into(),
|
||||||
auditor_encryption_pubkey: *auditor_encryption_pubkey,
|
auditor_encryption_pubkey: auditor_encryption_pubkey.try_into()?,
|
||||||
withdraw_withheld_authority_encryption_pubkey:
|
withdraw_withheld_authority_encryption_pubkey:
|
||||||
*withdraw_withheld_authority_encryption_pubkey,
|
withdraw_withheld_authority_encryption_pubkey.try_into()?,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -585,7 +578,7 @@ pub fn update_mint(
|
||||||
authority: &Pubkey,
|
authority: &Pubkey,
|
||||||
new_authority: Option<&Pubkey>,
|
new_authority: Option<&Pubkey>,
|
||||||
auto_approve_new_accounts: bool,
|
auto_approve_new_accounts: bool,
|
||||||
auditor_encryption_pubkey: &EncryptionPubkey,
|
auditor_encryption_pubkey: Option<EncryptionPubkey>,
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
check_program_account(token_program_id)?;
|
check_program_account(token_program_id)?;
|
||||||
|
|
||||||
|
@ -606,7 +599,7 @@ pub fn update_mint(
|
||||||
ConfidentialTransferInstruction::UpdateMint,
|
ConfidentialTransferInstruction::UpdateMint,
|
||||||
&UpdateMintData {
|
&UpdateMintData {
|
||||||
auto_approve_new_accounts: auto_approve_new_accounts.into(),
|
auto_approve_new_accounts: auto_approve_new_accounts.into(),
|
||||||
auditor_encryption_pubkey: *auditor_encryption_pubkey,
|
auditor_encryption_pubkey: auditor_encryption_pubkey.try_into()?,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use {
|
||||||
pod::*,
|
pod::*,
|
||||||
},
|
},
|
||||||
bytemuck::{Pod, Zeroable},
|
bytemuck::{Pod, Zeroable},
|
||||||
solana_program::{entrypoint::ProgramResult, pubkey::Pubkey},
|
solana_program::entrypoint::ProgramResult,
|
||||||
solana_zk_token_sdk::zk_token_elgamal::pod,
|
solana_zk_token_sdk::zk_token_elgamal::pod,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ pub mod instruction;
|
||||||
/// Confidential Transfer Extension processor
|
/// Confidential Transfer Extension processor
|
||||||
pub mod processor;
|
pub mod processor;
|
||||||
|
|
||||||
/// ElGamal public key used for encryption
|
|
||||||
pub type EncryptionPubkey = pod::ElGamalPubkey;
|
|
||||||
/// ElGamal ciphertext containing an account balance
|
/// ElGamal ciphertext containing an account balance
|
||||||
pub type EncryptedBalance = pod::ElGamalCiphertext;
|
pub type EncryptedBalance = pod::ElGamalCiphertext;
|
||||||
/// Authenticated encryption containing an account balance
|
/// Authenticated encryption containing an account balance
|
||||||
|
@ -43,11 +41,8 @@ pub struct ConfidentialTransferMint {
|
||||||
/// Authority to modify the `ConfidentialTransferMint` configuration and to approve new
|
/// Authority to modify the `ConfidentialTransferMint` configuration and to approve new
|
||||||
/// accounts (if `auto_approve_new_accounts` is true)
|
/// accounts (if `auto_approve_new_accounts` is true)
|
||||||
///
|
///
|
||||||
/// Note that setting an authority of `Pubkey::default()` is the idiomatic way to disable
|
|
||||||
/// future changes to the configuration.
|
|
||||||
///
|
|
||||||
/// The legacy Token Multisig account is not supported as the authority
|
/// The legacy Token Multisig account is not supported as the authority
|
||||||
pub authority: Pubkey,
|
pub authority: OptionalNonZeroPubkey,
|
||||||
|
|
||||||
/// Indicate if newly configured accounts must be approved by the `authority` before they may be
|
/// Indicate if newly configured accounts must be approved by the `authority` before they may be
|
||||||
/// used by the user.
|
/// used by the user.
|
||||||
|
@ -58,25 +53,21 @@ pub struct ConfidentialTransferMint {
|
||||||
pub auto_approve_new_accounts: PodBool,
|
pub auto_approve_new_accounts: PodBool,
|
||||||
|
|
||||||
/// Authority to decode any transfer amount in a confidential transafer.
|
/// Authority to decode any transfer amount in a confidential transafer.
|
||||||
///
|
pub auditor_encryption_pubkey: OptionalNonZeroEncryptionPubkey,
|
||||||
/// * If non-zero, transfers must include ElGamal cyphertext with this public key permitting the
|
|
||||||
/// auditor to decode the transfer amount.
|
|
||||||
/// * If all zero, auditing is currently disabled.
|
|
||||||
pub auditor_encryption_pubkey: EncryptionPubkey,
|
|
||||||
|
|
||||||
/// Authority to withraw withheld fees that are associated with accounts. It must be set to an
|
/// Authority to withraw withheld fees that are associated with accounts. It must be set to
|
||||||
/// all zero pubkey if the mint is not extended for fees.
|
/// `None` if the mint is not extended for fees.
|
||||||
///
|
///
|
||||||
/// Note that the withdraw withheld authority has the ability to decode any withheld fee
|
/// Note that the withdraw withheld authority has the ability to decode any withheld fee
|
||||||
/// amount that are associated with accounts. When combined with the fee parameters, the
|
/// amount that are associated with accounts. When combined with the fee parameters, the
|
||||||
/// withheld fee amounts can reveal information about transfer amounts.
|
/// withheld fee amounts can reveal information about transfer amounts.
|
||||||
///
|
///
|
||||||
/// * If non-zero, transfers must include ElGamal cyphertext of the transfer fee with this
|
/// * If not `None`, transfers must include ElGamal cyphertext of the transfer fee with this
|
||||||
/// public key. If this is the case, but the base mint is not extended for fees, then any
|
/// public key. If this is the case, but the base mint is not extended for fees, then any
|
||||||
/// transfer will fail.
|
/// transfer will fail.
|
||||||
/// * If all zero, transfer fee is disabled. If this is the case, but the base mint is extended
|
/// * If `None`, transfer fee is disabled. If this is the case, but the base mint is extended
|
||||||
/// for fees, then any transfer will fail.
|
/// for fees, then any transfer will fail.
|
||||||
pub withdraw_withheld_authority_encryption_pubkey: EncryptionPubkey,
|
pub withdraw_withheld_authority_encryption_pubkey: OptionalNonZeroEncryptionPubkey,
|
||||||
|
|
||||||
/// Withheld transfer fee confidential tokens that have been moved to the mint for withdrawal.
|
/// Withheld transfer fee confidential tokens that have been moved to the mint for withdrawal.
|
||||||
/// This will always be zero if fees are never enabled.
|
/// This will always be zero if fees are never enabled.
|
||||||
|
|
|
@ -55,10 +55,10 @@ fn decode_proof_instruction<T: Pod>(
|
||||||
/// Processes an [InitializeMint] instruction.
|
/// Processes an [InitializeMint] instruction.
|
||||||
fn process_initialize_mint(
|
fn process_initialize_mint(
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
authority: &Pubkey,
|
authority: &OptionalNonZeroPubkey,
|
||||||
auto_approve_new_account: PodBool,
|
auto_approve_new_account: PodBool,
|
||||||
auditor_encryption_pubkey: &EncryptionPubkey,
|
auditor_encryption_pubkey: &OptionalNonZeroEncryptionPubkey,
|
||||||
withdraw_withheld_authority_encryption_pubkey: &EncryptionPubkey,
|
withdraw_withheld_authority_encryption_pubkey: &OptionalNonZeroEncryptionPubkey,
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
let mint_info = next_account_info(account_info_iter)?;
|
let mint_info = next_account_info(account_info_iter)?;
|
||||||
|
@ -82,7 +82,7 @@ fn process_initialize_mint(
|
||||||
fn process_update_mint(
|
fn process_update_mint(
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
auto_approve_new_account: PodBool,
|
auto_approve_new_account: PodBool,
|
||||||
auditor_encryption_pubkey: &EncryptionPubkey,
|
auditor_encryption_pubkey: &OptionalNonZeroEncryptionPubkey,
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
let mint_info = next_account_info(account_info_iter)?;
|
let mint_info = next_account_info(account_info_iter)?;
|
||||||
|
@ -93,18 +93,26 @@ fn process_update_mint(
|
||||||
let mint_data = &mut mint_info.data.borrow_mut();
|
let mint_data = &mut mint_info.data.borrow_mut();
|
||||||
let mut mint = StateWithExtensionsMut::<Mint>::unpack(mint_data)?;
|
let mut mint = StateWithExtensionsMut::<Mint>::unpack(mint_data)?;
|
||||||
let confidential_transfer_mint = mint.get_extension_mut::<ConfidentialTransferMint>()?;
|
let confidential_transfer_mint = mint.get_extension_mut::<ConfidentialTransferMint>()?;
|
||||||
|
let maybe_confidential_transfer_mint_authority: Option<Pubkey> =
|
||||||
|
confidential_transfer_mint.authority.into();
|
||||||
|
let confidential_transfer_mint_authority =
|
||||||
|
maybe_confidential_transfer_mint_authority.ok_or(TokenError::NoAuthorityExists)?;
|
||||||
|
|
||||||
if authority_info.is_signer
|
if !authority_info.is_signer
|
||||||
&& confidential_transfer_mint.authority == *authority_info.key
|
|| confidential_transfer_mint_authority != *authority_info.key
|
||||||
&& (new_authority_info.is_signer || *new_authority_info.key == Pubkey::default())
|
|| (!new_authority_info.is_signer && *new_authority_info.key != Pubkey::default())
|
||||||
{
|
{
|
||||||
confidential_transfer_mint.authority = *new_authority_info.key;
|
return Err(ProgramError::MissingRequiredSignature);
|
||||||
confidential_transfer_mint.auto_approve_new_accounts = auto_approve_new_account;
|
|
||||||
confidential_transfer_mint.auditor_encryption_pubkey = *auditor_encryption_pubkey;
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ProgramError::MissingRequiredSignature)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *new_authority_info.key == Pubkey::default() {
|
||||||
|
confidential_transfer_mint.authority = None.try_into()?;
|
||||||
|
} else {
|
||||||
|
confidential_transfer_mint.authority = Some(*new_authority_info.key).try_into()?;
|
||||||
|
}
|
||||||
|
confidential_transfer_mint.auto_approve_new_accounts = auto_approve_new_account;
|
||||||
|
confidential_transfer_mint.auditor_encryption_pubkey = *auditor_encryption_pubkey;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes a [ConfigureAccount] instruction.
|
/// Processes a [ConfigureAccount] instruction.
|
||||||
|
@ -191,8 +199,12 @@ fn process_approve_account(accounts: &[AccountInfo]) -> ProgramResult {
|
||||||
let mint_data = &mint_info.data.borrow_mut();
|
let mint_data = &mint_info.data.borrow_mut();
|
||||||
let mint = StateWithExtensions::<Mint>::unpack(mint_data)?;
|
let mint = StateWithExtensions::<Mint>::unpack(mint_data)?;
|
||||||
let confidential_transfer_mint = mint.get_extension::<ConfidentialTransferMint>()?;
|
let confidential_transfer_mint = mint.get_extension::<ConfidentialTransferMint>()?;
|
||||||
|
let maybe_confidential_transfer_mint_authority: Option<Pubkey> =
|
||||||
|
confidential_transfer_mint.authority.into();
|
||||||
|
let confidential_transfer_mint_authority =
|
||||||
|
maybe_confidential_transfer_mint_authority.ok_or(TokenError::NoAuthorityExists)?;
|
||||||
|
|
||||||
if authority_info.is_signer && *authority_info.key == confidential_transfer_mint.authority {
|
if authority_info.is_signer && *authority_info.key == confidential_transfer_mint_authority {
|
||||||
let mut confidential_transfer_state =
|
let mut confidential_transfer_state =
|
||||||
token_account.get_extension_mut::<ConfidentialTransferAccount>()?;
|
token_account.get_extension_mut::<ConfidentialTransferAccount>()?;
|
||||||
confidential_transfer_state.approved = true.into();
|
confidential_transfer_state.approved = true.into();
|
||||||
|
@ -502,8 +514,9 @@ fn process_transfer(
|
||||||
)?;
|
)?;
|
||||||
// Check that the auditor encryption public key associated wth the confidential mint is
|
// Check that the auditor encryption public key associated wth the confidential mint is
|
||||||
// consistent with what was actually used to generate the zkp.
|
// consistent with what was actually used to generate the zkp.
|
||||||
if proof_data.transfer_pubkeys.auditor_pubkey
|
if !confidential_transfer_mint
|
||||||
!= confidential_transfer_mint.auditor_encryption_pubkey
|
.auditor_encryption_pubkey
|
||||||
|
.equals(&proof_data.transfer_pubkeys.auditor_pubkey)
|
||||||
{
|
{
|
||||||
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
||||||
}
|
}
|
||||||
|
@ -562,15 +575,19 @@ fn process_transfer(
|
||||||
)?;
|
)?;
|
||||||
// Check that the encryption public keys associated with the confidential extension mint
|
// Check that the encryption public keys associated with the confidential extension mint
|
||||||
// are consistent with the keys that were used to generate the zkp.
|
// are consistent with the keys that were used to generate the zkp.
|
||||||
if proof_data.transfer_with_fee_pubkeys.auditor_pubkey
|
if !confidential_transfer_mint
|
||||||
!= confidential_transfer_mint.auditor_encryption_pubkey
|
.auditor_encryption_pubkey
|
||||||
|
.equals(&proof_data.transfer_with_fee_pubkeys.auditor_pubkey)
|
||||||
{
|
{
|
||||||
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
||||||
}
|
}
|
||||||
if proof_data
|
if !confidential_transfer_mint
|
||||||
.transfer_with_fee_pubkeys
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
.withdraw_withheld_authority_pubkey
|
.equals(
|
||||||
!= confidential_transfer_mint.withdraw_withheld_authority_encryption_pubkey
|
&proof_data
|
||||||
|
.transfer_with_fee_pubkeys
|
||||||
|
.withdraw_withheld_authority_pubkey,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
||||||
}
|
}
|
||||||
|
@ -970,8 +987,9 @@ fn process_withdraw_withheld_tokens_from_mint(
|
||||||
)?;
|
)?;
|
||||||
// Checks that the withdraw authority encryption public key associated with the mint is
|
// Checks that the withdraw authority encryption public key associated with the mint is
|
||||||
// consistent with what was actually used to generate the zkp.
|
// consistent with what was actually used to generate the zkp.
|
||||||
if proof_data.withdraw_withheld_authority_pubkey
|
if !confidential_transfer_mint
|
||||||
!= confidential_transfer_mint.withdraw_withheld_authority_encryption_pubkey
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.equals(&proof_data.withdraw_withheld_authority_pubkey)
|
||||||
{
|
{
|
||||||
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
||||||
}
|
}
|
||||||
|
@ -1097,8 +1115,9 @@ fn process_withdraw_withheld_tokens_from_accounts(
|
||||||
// Checks that the withdraw authority encryption public key associated with the mint is
|
// Checks that the withdraw authority encryption public key associated with the mint is
|
||||||
// consistent with what was actually used to generate the zkp.
|
// consistent with what was actually used to generate the zkp.
|
||||||
let confidential_transfer_mint = mint.get_extension_mut::<ConfidentialTransferMint>()?;
|
let confidential_transfer_mint = mint.get_extension_mut::<ConfidentialTransferMint>()?;
|
||||||
if proof_data.withdraw_withheld_authority_pubkey
|
if !confidential_transfer_mint
|
||||||
!= confidential_transfer_mint.withdraw_withheld_authority_encryption_pubkey
|
.withdraw_withheld_authority_encryption_pubkey
|
||||||
|
.equals(&proof_data.withdraw_withheld_authority_pubkey)
|
||||||
{
|
{
|
||||||
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
use {
|
use {
|
||||||
bytemuck::{Pod, Zeroable},
|
bytemuck::{Pod, Zeroable},
|
||||||
solana_program::{program_error::ProgramError, program_option::COption, pubkey::Pubkey},
|
solana_program::{program_error::ProgramError, program_option::COption, pubkey::Pubkey},
|
||||||
|
solana_zk_token_sdk::zk_token_elgamal::pod,
|
||||||
std::convert::TryFrom,
|
std::convert::TryFrom,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +60,44 @@ impl From<OptionalNonZeroPubkey> for COption<Pubkey> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ElGamal public key used for encryption
|
||||||
|
pub type EncryptionPubkey = pod::ElGamalPubkey;
|
||||||
|
/// An EncryptionPubkey that encodes `None` as all `0`, meant to be usable as a Pod type.
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct OptionalNonZeroEncryptionPubkey(EncryptionPubkey);
|
||||||
|
impl OptionalNonZeroEncryptionPubkey {
|
||||||
|
/// Checks equality between an OptionalNonZeroEncryptionPubkey and an EncryptionPubkey when
|
||||||
|
/// interpreted as bytes.
|
||||||
|
pub fn equals(&self, other: &EncryptionPubkey) -> bool {
|
||||||
|
&self.0 == other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl TryFrom<Option<EncryptionPubkey>> for OptionalNonZeroEncryptionPubkey {
|
||||||
|
type Error = ProgramError;
|
||||||
|
fn try_from(p: Option<EncryptionPubkey>) -> Result<Self, Self::Error> {
|
||||||
|
match p {
|
||||||
|
None => Ok(Self(EncryptionPubkey::default())),
|
||||||
|
Some(encryption_pubkey) => {
|
||||||
|
if encryption_pubkey == EncryptionPubkey::default() {
|
||||||
|
Err(ProgramError::InvalidArgument)
|
||||||
|
} else {
|
||||||
|
Ok(Self(encryption_pubkey))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<OptionalNonZeroEncryptionPubkey> for Option<EncryptionPubkey> {
|
||||||
|
fn from(p: OptionalNonZeroEncryptionPubkey) -> Self {
|
||||||
|
if p.0 == EncryptionPubkey::default() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(p.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The standard `bool` is not a `Pod`, define a replacement that is
|
/// The standard `bool` is not a `Pod`, define a replacement that is
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|
Loading…
Reference in New Issue