Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 6386f24

Browse files
[confidential-extension] Restrict InitializeMint and UpdateMint instructions (#3938)
* restrict `UpdateMint` instruction * update tests and token client for `UpdateMint` * restrict `InitializeAccount` instruction * update client and tests for `InitializeMint` instruction
1 parent ac02e0a commit 6386f24

File tree

4 files changed

+273
-59
lines changed

4 files changed

+273
-59
lines changed

token/client/src/token.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use {
2020
},
2121
spl_token_2022::{
2222
extension::{
23-
confidential_transfer, cpi_guard, default_account_state, interest_bearing_mint,
24-
memo_transfer, transfer_fee, BaseStateWithExtensions, ExtensionType,
25-
StateWithExtensionsOwned,
23+
confidential_transfer, confidential_transfer::EncryptionPubkey, cpi_guard,
24+
default_account_state, interest_bearing_mint, memo_transfer, transfer_fee,
25+
BaseStateWithExtensions, ExtensionType, StateWithExtensionsOwned,
2626
},
2727
instruction,
2828
solana_zk_token_sdk::{
@@ -104,7 +104,10 @@ impl PartialEq for TokenError {
104104
#[derive(Clone, Debug, PartialEq)]
105105
pub enum ExtensionInitializationParams {
106106
ConfidentialTransferMint {
107-
ct_mint: confidential_transfer::ConfidentialTransferMint,
107+
authority: Option<Pubkey>,
108+
auto_approve_new_accounts: bool,
109+
auditor_encryption_pubkey: EncryptionPubkey,
110+
withdraw_withheld_authority_encryption_pubkey: EncryptionPubkey,
108111
},
109112
DefaultAccountState {
110113
state: AccountState,
@@ -147,13 +150,19 @@ impl ExtensionInitializationParams {
147150
mint: &Pubkey,
148151
) -> Result<Instruction, ProgramError> {
149152
match self {
150-
Self::ConfidentialTransferMint { ct_mint } => {
151-
confidential_transfer::instruction::initialize_mint(
152-
token_program_id,
153-
mint,
154-
&ct_mint,
155-
)
156-
}
153+
Self::ConfidentialTransferMint {
154+
authority,
155+
auto_approve_new_accounts,
156+
auditor_encryption_pubkey,
157+
withdraw_withheld_authority_encryption_pubkey,
158+
} => confidential_transfer::instruction::initialize_mint(
159+
token_program_id,
160+
mint,
161+
authority.as_ref(),
162+
auto_approve_new_accounts,
163+
&auditor_encryption_pubkey,
164+
&withdraw_withheld_authority_encryption_pubkey,
165+
),
157166
Self::DefaultAccountState { state } => {
158167
default_account_state::instruction::initialize_default_account_state(
159168
token_program_id,
@@ -1481,19 +1490,26 @@ where
14811490
pub async fn confidential_transfer_update_mint<S: Signer>(
14821491
&self,
14831492
authority: &S,
1484-
new_ct_mint: confidential_transfer::ConfidentialTransferMint,
14851493
new_authority: Option<&S>,
1494+
auto_approve_new_account: bool,
1495+
auditor_encryption_pubkey: &EncryptionPubkey,
14861496
) -> TokenResult<T::Output> {
14871497
let mut signers = vec![authority];
1488-
if let Some(new_authority) = new_authority {
1498+
let new_authority_pubkey = if let Some(new_authority) = new_authority {
14891499
signers.push(new_authority);
1490-
}
1500+
Some(new_authority.pubkey())
1501+
} else {
1502+
None
1503+
};
1504+
14911505
self.process_ixs(
14921506
&[confidential_transfer::instruction::update_mint(
14931507
&self.program_id,
14941508
&self.pubkey,
1495-
&new_ct_mint,
14961509
&authority.pubkey(),
1510+
new_authority_pubkey.as_ref(),
1511+
auto_approve_new_account,
1512+
auditor_encryption_pubkey,
14971513
)?],
14981514
&signers,
14991515
)

token/program-2022-test/tests/confidential_transfer.rs

Lines changed: 138 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,13 @@ async fn ct_initialize_and_update_mint() {
285285
let mut context = TestContext::new().await;
286286
context
287287
.init_token_with_mint(vec![
288-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
288+
ExtensionInitializationParams::ConfidentialTransferMint {
289+
authority: Some(ct_mint.authority),
290+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
291+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
292+
withdraw_withheld_authority_encryption_pubkey: ct_mint
293+
.withdraw_withheld_authority_encryption_pubkey,
294+
},
289295
])
290296
.await
291297
.unwrap();
@@ -306,8 +312,12 @@ async fn ct_initialize_and_update_mint() {
306312
let err = token
307313
.confidential_transfer_update_mint(
308314
&wrong_keypair,
309-
new_ct_mint,
310315
Some(&new_ct_mint_authority),
316+
new_ct_mint.auto_approve_new_accounts.into(),
317+
&new_ct_mint
318+
.withdraw_withheld_authority_encryption_pubkey
319+
.try_into()
320+
.unwrap(),
311321
)
312322
.await
313323
.unwrap_err();
@@ -320,26 +330,64 @@ async fn ct_initialize_and_update_mint() {
320330
token
321331
.confidential_transfer_update_mint(
322332
&ct_mint_authority,
323-
new_ct_mint,
324333
Some(&new_ct_mint_authority),
334+
new_ct_mint.auto_approve_new_accounts.into(),
335+
&new_ct_mint
336+
.withdraw_withheld_authority_encryption_pubkey
337+
.try_into()
338+
.unwrap(),
325339
)
326340
.await
327341
.unwrap();
328342

329343
let state = token.get_mint_info().await.unwrap();
330344
let extension = state.get_extension::<ConfidentialTransferMint>().unwrap();
331-
assert_eq!(*extension, new_ct_mint);
345+
assert_eq!(extension.authority, new_ct_mint.authority);
346+
assert_eq!(
347+
extension.auto_approve_new_accounts,
348+
new_ct_mint.auto_approve_new_accounts
349+
);
350+
assert_eq!(
351+
extension.auditor_encryption_pubkey,
352+
new_ct_mint.auditor_encryption_pubkey
353+
);
354+
assert_eq!(
355+
extension.withdraw_withheld_authority_encryption_pubkey,
356+
ct_mint.withdraw_withheld_authority_encryption_pubkey,
357+
);
358+
assert_eq!(extension.withheld_amount, ct_mint.withheld_amount);
332359

333360
// Clear the authority
334361
let new_ct_mint = ConfidentialTransferMint::default();
335362
token
336-
.confidential_transfer_update_mint(&new_ct_mint_authority, new_ct_mint, None)
363+
.confidential_transfer_update_mint(
364+
&new_ct_mint_authority,
365+
None,
366+
new_ct_mint.auto_approve_new_accounts.into(),
367+
&new_ct_mint
368+
.withdraw_withheld_authority_encryption_pubkey
369+
.try_into()
370+
.unwrap(),
371+
)
337372
.await
338373
.unwrap();
339374

340375
let state = token.get_mint_info().await.unwrap();
341376
let extension = state.get_extension::<ConfidentialTransferMint>().unwrap();
342-
assert_eq!(*extension, new_ct_mint);
377+
assert_eq!(extension.authority, new_ct_mint.authority);
378+
assert_eq!(
379+
extension.auto_approve_new_accounts,
380+
new_ct_mint.auto_approve_new_accounts
381+
);
382+
assert_eq!(
383+
extension.auditor_encryption_pubkey,
384+
new_ct_mint.auditor_encryption_pubkey
385+
);
386+
assert_eq!(
387+
extension.withdraw_withheld_authority_encryption_pubkey,
388+
ct_mint.withdraw_withheld_authority_encryption_pubkey,
389+
);
390+
assert_eq!(extension.withheld_amount, ct_mint.withheld_amount);
343391
}
344392

345393
#[tokio::test]
@@ -353,7 +401,13 @@ async fn ct_configure_token_account() {
353401
let mut context = TestContext::new().await;
354402
context
355403
.init_token_with_mint(vec![
356-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
404+
ExtensionInitializationParams::ConfidentialTransferMint {
405+
authority: Some(ct_mint.authority),
406+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
407+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
408+
withdraw_withheld_authority_encryption_pubkey: ct_mint
409+
.withdraw_withheld_authority_encryption_pubkey,
410+
},
357411
])
358412
.await
359413
.unwrap();
@@ -424,7 +478,13 @@ async fn ct_enable_disable_confidential_credits() {
424478
let mut context = TestContext::new().await;
425479
context
426480
.init_token_with_mint(vec![
427-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
481+
ExtensionInitializationParams::ConfidentialTransferMint {
482+
authority: Some(ct_mint.authority),
483+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
484+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
485+
withdraw_withheld_authority_encryption_pubkey: ct_mint
486+
.withdraw_withheld_authority_encryption_pubkey,
487+
},
428488
])
429489
.await
430490
.unwrap();
@@ -466,7 +526,13 @@ async fn ct_enable_disable_non_confidential_credits() {
466526
let mut context = TestContext::new().await;
467527
context
468528
.init_token_with_mint(vec![
469-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
529+
ExtensionInitializationParams::ConfidentialTransferMint {
530+
authority: Some(ct_mint.authority),
531+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
532+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
533+
withdraw_withheld_authority_encryption_pubkey: ct_mint
534+
.withdraw_withheld_authority_encryption_pubkey,
535+
},
470536
])
471537
.await
472538
.unwrap();
@@ -557,7 +623,13 @@ async fn ct_new_account_is_empty() {
557623
let mut context = TestContext::new().await;
558624
context
559625
.init_token_with_mint(vec![
560-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
626+
ExtensionInitializationParams::ConfidentialTransferMint {
627+
authority: Some(ct_mint.authority),
628+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
629+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
630+
withdraw_withheld_authority_encryption_pubkey: ct_mint
631+
.withdraw_withheld_authority_encryption_pubkey,
632+
},
561633
])
562634
.await
563635
.unwrap();
@@ -579,7 +651,13 @@ async fn ct_deposit() {
579651
let mut context = TestContext::new().await;
580652
context
581653
.init_token_with_mint(vec![
582-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
654+
ExtensionInitializationParams::ConfidentialTransferMint {
655+
authority: Some(ct_mint.authority),
656+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
657+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
658+
withdraw_withheld_authority_encryption_pubkey: ct_mint
659+
.withdraw_withheld_authority_encryption_pubkey,
660+
},
583661
])
584662
.await
585663
.unwrap();
@@ -703,7 +781,13 @@ async fn ct_withdraw() {
703781
let mut context = TestContext::new().await;
704782
context
705783
.init_token_with_mint(vec![
706-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
784+
ExtensionInitializationParams::ConfidentialTransferMint {
785+
authority: Some(ct_mint.authority),
786+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
787+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
788+
withdraw_withheld_authority_encryption_pubkey: ct_mint
789+
.withdraw_withheld_authority_encryption_pubkey,
790+
},
707791
])
708792
.await
709793
.unwrap();
@@ -806,7 +890,13 @@ async fn ct_transfer() {
806890
let mut context = TestContext::new().await;
807891
context
808892
.init_token_with_mint(vec![
809-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
893+
ExtensionInitializationParams::ConfidentialTransferMint {
894+
authority: Some(ct_mint.authority),
895+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
896+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
897+
withdraw_withheld_authority_encryption_pubkey: ct_mint
898+
.withdraw_withheld_authority_encryption_pubkey,
899+
},
810900
])
811901
.await
812902
.unwrap();
@@ -1044,7 +1134,13 @@ async fn ct_transfer_with_fee() {
10441134
transfer_fee_basis_points: TEST_FEE_BASIS_POINTS,
10451135
maximum_fee: TEST_MAXIMUM_FEE,
10461136
},
1047-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1137+
ExtensionInitializationParams::ConfidentialTransferMint {
1138+
authority: Some(ct_mint.authority),
1139+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
1140+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
1141+
withdraw_withheld_authority_encryption_pubkey: ct_mint
1142+
.withdraw_withheld_authority_encryption_pubkey,
1143+
},
10481144
])
10491145
.await
10501146
.unwrap();
@@ -1262,7 +1358,13 @@ async fn ct_withdraw_withheld_tokens_from_mint() {
12621358
transfer_fee_basis_points: TEST_FEE_BASIS_POINTS,
12631359
maximum_fee: TEST_MAXIMUM_FEE,
12641360
},
1265-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1361+
ExtensionInitializationParams::ConfidentialTransferMint {
1362+
authority: Some(ct_mint.authority),
1363+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
1364+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
1365+
withdraw_withheld_authority_encryption_pubkey: ct_mint
1366+
.withdraw_withheld_authority_encryption_pubkey,
1367+
},
12661368
])
12671369
.await
12681370
.unwrap();
@@ -1418,7 +1520,13 @@ async fn ct_withdraw_withheld_tokens_from_accounts() {
14181520
transfer_fee_basis_points: TEST_FEE_BASIS_POINTS,
14191521
maximum_fee: TEST_MAXIMUM_FEE,
14201522
},
1421-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1523+
ExtensionInitializationParams::ConfidentialTransferMint {
1524+
authority: Some(ct_mint.authority),
1525+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
1526+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
1527+
withdraw_withheld_authority_encryption_pubkey: ct_mint
1528+
.withdraw_withheld_authority_encryption_pubkey,
1529+
},
14221530
])
14231531
.await
14241532
.unwrap();
@@ -1525,7 +1633,13 @@ async fn ct_transfer_memo() {
15251633
let mut context = TestContext::new().await;
15261634
context
15271635
.init_token_with_mint(vec![
1528-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1636+
ExtensionInitializationParams::ConfidentialTransferMint {
1637+
authority: Some(ct_mint.authority),
1638+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
1639+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
1640+
withdraw_withheld_authority_encryption_pubkey: ct_mint
1641+
.withdraw_withheld_authority_encryption_pubkey,
1642+
},
15291643
])
15301644
.await
15311645
.unwrap();
@@ -1633,7 +1747,13 @@ async fn ct_transfer_with_fee_memo() {
16331747
transfer_fee_basis_points: TEST_FEE_BASIS_POINTS,
16341748
maximum_fee: TEST_MAXIMUM_FEE,
16351749
},
1636-
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1750+
ExtensionInitializationParams::ConfidentialTransferMint {
1751+
authority: Some(ct_mint.authority),
1752+
auto_approve_new_accounts: ct_mint.auto_approve_new_accounts.try_into().unwrap(),
1753+
auditor_encryption_pubkey: ct_mint.auditor_encryption_pubkey,
1754+
withdraw_withheld_authority_encryption_pubkey: ct_mint
1755+
.withdraw_withheld_authority_encryption_pubkey,
1756+
},
16371757
])
16381758
.await
16391759
.unwrap();

0 commit comments

Comments
 (0)