@@ -45,6 +45,38 @@ fn decode_proof_instruction<T: Pod>(
45
45
ProofInstruction :: decode_data ( & instruction. data ) . ok_or ( ProgramError :: InvalidInstructionData )
46
46
}
47
47
48
+ /// Checks if a confidential extension is configured to send funds
49
+ fn check_source_confidential_account (
50
+ source_confidential_transfer_account : & ConfidentialTransferAccount ,
51
+ ) -> ProgramResult {
52
+ source_confidential_transfer_account. approved ( )
53
+ }
54
+
55
+ /// Checks if a confidential extension is configured to receive funds
56
+ fn check_destination_confidential_account (
57
+ destination_confidential_transfer_account : & ConfidentialTransferAccount ,
58
+ ) -> ProgramResult {
59
+ destination_confidential_transfer_account. approved ( ) ?;
60
+
61
+ if !bool:: from ( & destination_confidential_transfer_account. allow_balance_credits ) {
62
+ return Err ( TokenError :: ConfidentialTransferDepositsAndTransfersDisabled . into ( ) ) ;
63
+ }
64
+
65
+ let new_destination_pending_balance_credit_counter =
66
+ u64:: from ( destination_confidential_transfer_account. pending_balance_credit_counter )
67
+ . checked_add ( 1 )
68
+ . ok_or ( ProgramError :: InvalidInstructionData ) ?;
69
+ if new_destination_pending_balance_credit_counter
70
+ > u64:: from (
71
+ destination_confidential_transfer_account. maximum_pending_balance_credit_counter ,
72
+ )
73
+ {
74
+ return Err ( TokenError :: MaximumPendingBalanceCreditCounterExceeded . into ( ) ) ;
75
+ }
76
+
77
+ Ok ( ( ) )
78
+ }
79
+
48
80
/// Processes an [InitializeMint] instruction.
49
81
fn process_initialize_mint (
50
82
accounts : & [ AccountInfo ] ,
@@ -326,11 +358,7 @@ fn process_deposit(
326
358
327
359
let mut confidential_transfer_account =
328
360
token_account. get_extension_mut :: < ConfidentialTransferAccount > ( ) ?;
329
- confidential_transfer_account. approved ( ) ?;
330
-
331
- if !bool:: from ( & confidential_transfer_account. allow_balance_credits ) {
332
- return Err ( TokenError :: ConfidentialTransferDepositsAndTransfersDisabled . into ( ) ) ;
333
- }
361
+ check_destination_confidential_account ( confidential_transfer_account) ?;
334
362
335
363
// Divide the deposit amount into low 16 and high 48-bit numbers and then add to the
336
364
// appropriate pending ciphertexts
@@ -352,12 +380,6 @@ fn process_deposit(
352
380
. ok_or ( ProgramError :: InvalidInstructionData ) ?)
353
381
. into ( ) ;
354
382
355
- if u64:: from ( confidential_transfer_account. pending_balance_credit_counter )
356
- > u64:: from ( confidential_transfer_account. maximum_pending_balance_credit_counter )
357
- {
358
- return Err ( TokenError :: MaximumPendingBalanceCreditCounterExceeded . into ( ) ) ;
359
- }
360
-
361
383
Ok ( ( ) )
362
384
}
363
385
@@ -423,6 +445,7 @@ fn process_withdraw(
423
445
424
446
let mut confidential_transfer_account =
425
447
token_account. get_extension_mut :: < ConfidentialTransferAccount > ( ) ?;
448
+ check_source_confidential_account ( confidential_transfer_account) ?;
426
449
427
450
if confidential_transfer_account. encryption_pubkey != proof_data. pubkey {
428
451
return Err ( TokenError :: ConfidentialTransferElGamalPubkeyMismatch . into ( ) ) ;
@@ -664,7 +687,8 @@ fn process_source_for_transfer(
664
687
665
688
let mut confidential_transfer_account =
666
689
token_account. get_extension_mut :: < ConfidentialTransferAccount > ( ) ?;
667
- confidential_transfer_account. approved ( ) ?;
690
+ check_source_confidential_account ( confidential_transfer_account) ?;
691
+
668
692
if * source_encryption_pubkey != confidential_transfer_account. encryption_pubkey {
669
693
return Err ( TokenError :: ConfidentialTransferElGamalPubkeyMismatch . into ( ) ) ;
670
694
}
@@ -713,11 +737,7 @@ fn process_destination_for_transfer(
713
737
714
738
let mut destination_confidential_transfer_account =
715
739
destination_token_account. get_extension_mut :: < ConfidentialTransferAccount > ( ) ?;
716
- destination_confidential_transfer_account. approved ( ) ?;
717
-
718
- if !bool:: from ( & destination_confidential_transfer_account. allow_balance_credits ) {
719
- return Err ( TokenError :: ConfidentialTransferDepositsAndTransfersDisabled . into ( ) ) ;
720
- }
740
+ check_destination_confidential_account ( destination_confidential_transfer_account) ?;
721
741
722
742
if * destination_encryption_pubkey != destination_confidential_transfer_account. encryption_pubkey
723
743
{
@@ -741,14 +761,6 @@ fn process_destination_for_transfer(
741
761
. checked_add ( 1 )
742
762
. ok_or ( ProgramError :: InvalidInstructionData ) ?;
743
763
744
- if new_destination_pending_balance_credit_counter
745
- > u64:: from (
746
- destination_confidential_transfer_account. maximum_pending_balance_credit_counter ,
747
- )
748
- {
749
- return Err ( TokenError :: MaximumPendingBalanceCreditCounterExceeded . into ( ) ) ;
750
- }
751
-
752
764
destination_confidential_transfer_account. pending_balance_lo =
753
765
new_destination_pending_balance_lo;
754
766
destination_confidential_transfer_account. pending_balance_hi =
@@ -908,6 +920,7 @@ fn process_withdraw_withheld_tokens_from_mint(
908
920
let mut destination_account_data = destination_account_info. data . borrow_mut ( ) ;
909
921
let mut destination_account =
910
922
StateWithExtensionsMut :: < Account > :: unpack ( & mut destination_account_data) ?;
923
+
911
924
if destination_account. base . mint != * mint_account_info. key {
912
925
return Err ( TokenError :: MintMismatch . into ( ) ) ;
913
926
}
@@ -916,7 +929,8 @@ fn process_withdraw_withheld_tokens_from_mint(
916
929
}
917
930
let mut destination_confidential_transfer_account =
918
931
destination_account. get_extension_mut :: < ConfidentialTransferAccount > ( ) ?;
919
- destination_confidential_transfer_account. approved ( ) ?;
932
+ check_destination_confidential_account ( destination_confidential_transfer_account) ?;
933
+
920
934
// verify consistency of proof data
921
935
let previous_instruction =
922
936
get_instruction_relative ( proof_instruction_offset, instructions_sysvar_info) ?;
@@ -955,6 +969,12 @@ fn process_withdraw_withheld_tokens_from_mint(
955
969
956
970
destination_confidential_transfer_account. pending_balance_lo = new_destination_pending_balance;
957
971
972
+ destination_confidential_transfer_account. pending_balance_credit_counter =
973
+ ( u64:: from ( destination_confidential_transfer_account. pending_balance_credit_counter )
974
+ . checked_add ( 1 )
975
+ . ok_or ( ProgramError :: InvalidInstructionData ) ?)
976
+ . into ( ) ;
977
+
958
978
// fee is now withdrawn, so zero out mint withheld amount
959
979
confidential_transfer_mint. withheld_amount = EncryptedWithheldAmount :: zeroed ( ) ;
960
980
@@ -1040,7 +1060,8 @@ fn process_withdraw_withheld_tokens_from_accounts(
1040
1060
1041
1061
let mut destination_confidential_transfer_account =
1042
1062
destination_account. get_extension_mut :: < ConfidentialTransferAccount > ( ) ?;
1043
- destination_confidential_transfer_account. approved ( ) ?;
1063
+ check_destination_confidential_account ( destination_confidential_transfer_account) ?;
1064
+
1044
1065
// verify consistency of proof data
1045
1066
let previous_instruction =
1046
1067
get_instruction_relative ( proof_instruction_offset, instructions_sysvar_info) ?;
@@ -1075,6 +1096,12 @@ fn process_withdraw_withheld_tokens_from_accounts(
1075
1096
)
1076
1097
. ok_or ( ProgramError :: InvalidInstructionData ) ?;
1077
1098
1099
+ destination_confidential_transfer_account. pending_balance_credit_counter =
1100
+ ( u64:: from ( destination_confidential_transfer_account. pending_balance_credit_counter )
1101
+ . checked_add ( 1 )
1102
+ . ok_or ( ProgramError :: InvalidInstructionData ) ?)
1103
+ . into ( ) ;
1104
+
1078
1105
destination_confidential_transfer_account. pending_balance_lo = new_destination_pending_balance;
1079
1106
1080
1107
Ok ( ( ) )
0 commit comments