@@ -47,30 +47,30 @@ struct ConfidentialTransferMintWithKeypairs {
47
47
ct_mint : ConfidentialTransferMint ,
48
48
ct_mint_authority : Keypair ,
49
49
#[ allow( dead_code) ]
50
- ct_mint_transfer_auditor : ElGamalKeypair ,
51
- #[ allow( dead_code) ]
52
- ct_mint_withdraw_withheld_authority : ElGamalKeypair ,
50
+ ct_mint_transfer_auditor_encryption_keypair : ElGamalKeypair ,
51
+ ct_mint_withdraw_withheld_authority_encryption_keypair : ElGamalKeypair ,
53
52
}
54
53
55
54
impl ConfidentialTransferMintWithKeypairs {
56
55
fn new ( ) -> Self {
57
56
let ct_mint_authority = Keypair :: new ( ) ;
58
- let ct_mint_transfer_auditor = ElGamalKeypair :: new_rand ( ) ;
59
- let ct_mint_withdraw_withheld_authority = ElGamalKeypair :: new_rand ( ) ;
57
+ let ct_mint_transfer_auditor_encryption_keypair = ElGamalKeypair :: new_rand ( ) ;
58
+ let ct_mint_withdraw_withheld_authority_encryption_keypair = ElGamalKeypair :: new_rand ( ) ;
60
59
let ct_mint = ConfidentialTransferMint {
61
60
authority : ct_mint_authority. pubkey ( ) . into ( ) ,
62
61
auto_approve_new_accounts : true . into ( ) ,
63
- auditor_encryption_pubkey : ct_mint_transfer_auditor. public . into ( ) ,
64
- withdraw_withheld_authority_encryption_pubkey : ct_mint_withdraw_withheld_authority
65
- . public
66
- . into ( ) ,
62
+ auditor_encryption_pubkey : ct_mint_transfer_auditor_encryption_keypair. public . into ( ) ,
63
+ withdraw_withheld_authority_encryption_pubkey :
64
+ ct_mint_withdraw_withheld_authority_encryption_keypair
65
+ . public
66
+ . into ( ) ,
67
67
withheld_amount : EncryptedWithheldAmount :: zeroed ( ) ,
68
68
} ;
69
69
Self {
70
70
ct_mint,
71
71
ct_mint_authority,
72
- ct_mint_transfer_auditor ,
73
- ct_mint_withdraw_withheld_authority ,
72
+ ct_mint_transfer_auditor_encryption_keypair ,
73
+ ct_mint_withdraw_withheld_authority_encryption_keypair ,
74
74
}
75
75
}
76
76
@@ -194,6 +194,22 @@ struct ConfidentialTokenAccountBalances {
194
194
decryptable_available_balance : u64 ,
195
195
}
196
196
197
+ async fn check_withheld_amount_in_mint < T > (
198
+ token : & Token < T , Keypair > ,
199
+ withdraw_withheld_authority_encryption_keypair : & ElGamalKeypair ,
200
+ expected : u64 ,
201
+ ) where
202
+ T : SendTransaction ,
203
+ {
204
+ let state = token. get_mint_info ( ) . await . unwrap ( ) ;
205
+ let extension = state. get_extension :: < ConfidentialTransferMint > ( ) . unwrap ( ) ;
206
+ let decrypted_amount = extension
207
+ . withheld_amount
208
+ . decrypt ( & withdraw_withheld_authority_encryption_keypair. secret )
209
+ . unwrap ( ) ;
210
+ assert_eq ! ( decrypted_amount, expected) ;
211
+ }
212
+
197
213
#[ tokio:: test]
198
214
async fn ct_initialize_and_update_mint ( ) {
199
215
let wrong_keypair = Keypair :: new ( ) ;
@@ -1017,3 +1033,135 @@ async fn ct_transfer_with_fee() {
1017
1033
Some ( 94 ) ,
1018
1034
) ;
1019
1035
}
1036
+
1037
+ #[ tokio:: test]
1038
+ async fn ct_withdraw_withheld_tokens_from_mint ( ) {
1039
+ let ConfidentialTransferMintWithKeypairs {
1040
+ ct_mint,
1041
+ ct_mint_withdraw_withheld_authority_encryption_keypair,
1042
+ ..
1043
+ } = ConfidentialTransferMintWithKeypairs :: new ( ) ;
1044
+
1045
+ let ct_mint_withdraw_withheld_authority = Keypair :: new ( ) ;
1046
+
1047
+ let mut context = TestContext :: new ( ) . await ;
1048
+ context
1049
+ . init_token_with_mint ( vec ! [
1050
+ ExtensionInitializationParams :: TransferFeeConfig {
1051
+ transfer_fee_config_authority: Some ( Pubkey :: new_unique( ) ) ,
1052
+ withdraw_withheld_authority: Some ( ct_mint_withdraw_withheld_authority. pubkey( ) ) ,
1053
+ transfer_fee_basis_points: TEST_FEE_BASIS_POINTS ,
1054
+ maximum_fee: TEST_MAXIMUM_FEE ,
1055
+ } ,
1056
+ ExtensionInitializationParams :: ConfidentialTransferMint { ct_mint } ,
1057
+ ] )
1058
+ . await
1059
+ . unwrap ( ) ;
1060
+
1061
+ let TokenContext {
1062
+ token,
1063
+ alice,
1064
+ bob,
1065
+ mint_authority,
1066
+ decimals,
1067
+ ..
1068
+ } = context. token_context . unwrap ( ) ;
1069
+
1070
+ let epoch_info = test_epoch_info ( ) ;
1071
+
1072
+ let alice_meta =
1073
+ ConfidentialTokenAccountMeta :: with_tokens ( & token, & alice, & mint_authority, 100 , decimals)
1074
+ . await ;
1075
+ let bob_meta = ConfidentialTokenAccountMeta :: new ( & token, & bob) . await ;
1076
+
1077
+ token
1078
+ . confidential_transfer_withdraw_withheld_tokens_from_mint (
1079
+ & ct_mint_withdraw_withheld_authority,
1080
+ & ct_mint_withdraw_withheld_authority_encryption_keypair,
1081
+ & alice_meta. token_account ,
1082
+ 0_u64 ,
1083
+ )
1084
+ . await
1085
+ . unwrap ( ) ;
1086
+
1087
+ alice_meta
1088
+ . check_balances (
1089
+ & token,
1090
+ ConfidentialTokenAccountBalances {
1091
+ pending_balance : 0 ,
1092
+ available_balance : 100 ,
1093
+ decryptable_available_balance : 100 ,
1094
+ } ,
1095
+ )
1096
+ . await ;
1097
+
1098
+ check_withheld_amount_in_mint (
1099
+ & token,
1100
+ & ct_mint_withdraw_withheld_authority_encryption_keypair,
1101
+ 0 ,
1102
+ )
1103
+ . await ;
1104
+
1105
+ // Test fee is 2.5% so the withheld fees should be 3
1106
+ token
1107
+ . confidential_transfer_transfer_with_fee (
1108
+ & alice_meta. token_account ,
1109
+ & bob_meta. token_account ,
1110
+ & alice,
1111
+ 100 ,
1112
+ 100 ,
1113
+ & alice_meta. elgamal_keypair ,
1114
+ alice_meta. ae_key . encrypt ( 0_u64 ) ,
1115
+ & epoch_info,
1116
+ )
1117
+ . await
1118
+ . unwrap ( ) ;
1119
+
1120
+ let state = token
1121
+ . get_account_info ( & bob_meta. token_account )
1122
+ . await
1123
+ . unwrap ( ) ;
1124
+ let extension = state
1125
+ . get_extension :: < ConfidentialTransferAccount > ( )
1126
+ . unwrap ( ) ;
1127
+
1128
+ assert_eq ! (
1129
+ extension
1130
+ . withheld_amount
1131
+ . decrypt( & ct_mint_withdraw_withheld_authority_encryption_keypair. secret) ,
1132
+ Some ( 3 ) ,
1133
+ ) ;
1134
+
1135
+ token
1136
+ . confidential_transfer_harvest_withheld_tokens_to_mint ( & [ & bob_meta. token_account ] )
1137
+ . await
1138
+ . unwrap ( ) ;
1139
+
1140
+ check_withheld_amount_in_mint (
1141
+ & token,
1142
+ & ct_mint_withdraw_withheld_authority_encryption_keypair,
1143
+ 3 ,
1144
+ )
1145
+ . await ;
1146
+
1147
+ token
1148
+ . confidential_transfer_withdraw_withheld_tokens_from_mint (
1149
+ & ct_mint_withdraw_withheld_authority,
1150
+ & ct_mint_withdraw_withheld_authority_encryption_keypair,
1151
+ & alice_meta. token_account ,
1152
+ 3_u64 ,
1153
+ )
1154
+ . await
1155
+ . unwrap ( ) ;
1156
+
1157
+ alice_meta
1158
+ . check_balances (
1159
+ & token,
1160
+ ConfidentialTokenAccountBalances {
1161
+ pending_balance : 3 ,
1162
+ available_balance : 0 ,
1163
+ decryptable_available_balance : 0 ,
1164
+ } ,
1165
+ )
1166
+ . await ;
1167
+ }
0 commit comments