fn process_transfer(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    new_source_decryptable_available_balance: pod::AeCiphertext,
    proof_instruction_offset: i64,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let token_account_info = next_account_info(account_info_iter)?;
    let dest_token_account_info = next_account_info(account_info_iter)?;
    let mint_info = next_account_info(account_info_iter)?;
    let instructions_sysvar_info = next_account_info(account_info_iter)?;
    let authority_info = next_account_info(account_info_iter)?;

    check_program_account(mint_info.owner)?;
    let mint_data = &mint_info.data.borrow_mut();
    let mint = StateWithExtensions::<Mint>::unpack(mint_data)?;
    let ct_mint = mint.get_extension::<ConfidentialTransferMint>()?;

    let previous_instruction =
        get_instruction_relative(proof_instruction_offset, instructions_sysvar_info)?;

    if let Ok(transfer_fee_config) = mint.get_extension::<TransferFeeConfig>() {
        // mint is extended for fees
        let proof_data = decode_proof_instruction::<TransferWithFeeData>(
            ProofInstruction::VerifyTransfer,
            &previous_instruction,
        )?;

        if proof_data.transfer_with_fee_pubkeys.auditor != ct_mint.auditor_pubkey {
            return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
        }

        // `withdraw_withheld_authority` ElGamal pubkey in proof data and mint must match
        if proof_data.transfer_with_fee_pubkeys.fee_collector
            != ct_mint.withdraw_withheld_authority_pubkey
        {
            return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
        }

        // fee parameters in proof data and mint must match
        let epoch = Clock::get()?.epoch;
        let (maximum_fee, transfer_fee_basis_points) =
            if u64::from(transfer_fee_config.newer_transfer_fee.epoch) < epoch {
                (
                    u64::from(transfer_fee_config.older_transfer_fee.maximum_fee),
                    u16::from(
                        transfer_fee_config
                            .older_transfer_fee
                            .transfer_fee_basis_points,
                    ),
                )
            } else {
                (
                    u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee),
                    u16::from(
                        transfer_fee_config
                            .newer_transfer_fee
                            .transfer_fee_basis_points,
                    ),
                )
            };

        if u64::from(proof_data.fee_parameters.maximum_fee) != maximum_fee
            || u16::from(proof_data.fee_parameters.fee_rate_basis_points)
                != transfer_fee_basis_points
        {
            return Err(TokenError::FeeParametersMismatch.into());
        }

        // Process source account
        let ciphertext_lo_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));

        process_source_for_transfer(
            program_id,
            token_account_info,
            mint_info,
            authority_info,
            account_info_iter.as_slice(),
            &proof_data.transfer_with_fee_pubkeys.source,
            ciphertext_lo_source,
            ciphertext_hi_source,
            new_source_decryptable_available_balance,
        )?;

        // Process destination account (with fee)
        let ciphertext_lo_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));

        process_dest_for_transfer(
            dest_token_account_info,
            mint_info,
            &proof_data.transfer_with_fee_pubkeys.dest,
            ciphertext_lo_dest,
            ciphertext_hi_dest,
            Some(proof_data.ciphertext_fee),
        )?;
    } else {
        // mint is not extended for fees
        let proof_data = decode_proof_instruction::<TransferData>(
            ProofInstruction::VerifyTransfer,
            &previous_instruction,
        )?;

        if proof_data.transfer_pubkeys.auditor != ct_mint.auditor_pubkey {
            return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
        }

        // Process source account
        let ciphertext_lo_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));

        process_source_for_transfer(
            program_id,
            token_account_info,
            mint_info,
            authority_info,
            account_info_iter.as_slice(),
            &proof_data.transfer_pubkeys.source,
            ciphertext_lo_source,
            ciphertext_hi_source,
            new_source_decryptable_available_balance,
        )?;

        // Process destination account (without fee)
        let ciphertext_lo_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));

        process_dest_for_transfer(
            dest_token_account_info,
            mint_info,
            &proof_data.transfer_pubkeys.dest,
            ciphertext_lo_dest,
            ciphertext_hi_dest,
            None,
        )?;
    }

    Ok(())
}
/// Processes an [Transfer] instruction.
Processes an [Transfer] instruction.
Processes an [ Transfer ] instruction .
fn process_transfer(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    new_source_decryptable_available_balance: pod::AeCiphertext,
    proof_instruction_offset: i64,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let token_account_info = next_account_info(account_info_iter)?;
    let dest_token_account_info = next_account_info(account_info_iter)?;
    let mint_info = next_account_info(account_info_iter)?;
    let instructions_sysvar_info = next_account_info(account_info_iter)?;
    let authority_info = next_account_info(account_info_iter)?;
    check_program_account(mint_info.owner)?;
    let mint_data = &mint_info.data.borrow_mut();
    let mint = StateWithExtensions::<Mint>::unpack(mint_data)?;
    let ct_mint = mint.get_extension::<ConfidentialTransferMint>()?;
    let previous_instruction =
        get_instruction_relative(proof_instruction_offset, instructions_sysvar_info)?;
    if let Ok(transfer_fee_config) = mint.get_extension::<TransferFeeConfig>() {
        // mint is extended for fees
        let proof_data = decode_proof_instruction::<TransferWithFeeData>(
            ProofInstruction::VerifyTransfer,
            &previous_instruction,
        )?;
        if proof_data.transfer_with_fee_pubkeys.auditor != ct_mint.auditor_pubkey {
            return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
        }
        // `withdraw_withheld_authority` ElGamal pubkey in proof data and mint must match
        if proof_data.transfer_with_fee_pubkeys.fee_collector
            != ct_mint.withdraw_withheld_authority_pubkey
        {
            return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
        }
        // fee parameters in proof data and mint must match
        let epoch = Clock::get()?.epoch;
        let (maximum_fee, transfer_fee_basis_points) =
            if u64::from(transfer_fee_config.newer_transfer_fee.epoch) < epoch {
                (
                    u64::from(transfer_fee_config.older_transfer_fee.maximum_fee),
                    u16::from(
                        transfer_fee_config
                            .older_transfer_fee
                            .transfer_fee_basis_points,
                    ),
                )
            } else {
                (
                    u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee),
                    u16::from(
                        transfer_fee_config
                            .newer_transfer_fee
                            .transfer_fee_basis_points,
                    ),
                )
            };
        if u64::from(proof_data.fee_parameters.maximum_fee) != maximum_fee
            || u16::from(proof_data.fee_parameters.fee_rate_basis_points)
                != transfer_fee_basis_points
        {
            return Err(TokenError::FeeParametersMismatch.into());
        }
        // Process source account
        let ciphertext_lo_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));
        process_source_for_transfer(
            program_id,
            token_account_info,
            mint_info,
            authority_info,
            account_info_iter.as_slice(),
            &proof_data.transfer_with_fee_pubkeys.source,
            ciphertext_lo_source,
            ciphertext_hi_source,
            new_source_decryptable_available_balance,
        )?;
        // Process destination account (with fee)
        let ciphertext_lo_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));
        process_dest_for_transfer(
            dest_token_account_info,
            mint_info,
            &proof_data.transfer_with_fee_pubkeys.dest,
            ciphertext_lo_dest,
            ciphertext_hi_dest,
            Some(proof_data.ciphertext_fee),
        )?;
    } else {
        // mint is not extended for fees
        let proof_data = decode_proof_instruction::<TransferData>(
            ProofInstruction::VerifyTransfer,
            &previous_instruction,
        )?;
        if proof_data.transfer_pubkeys.auditor != ct_mint.auditor_pubkey {
            return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
        }
        // Process source account
        let ciphertext_lo_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_source = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));
        process_source_for_transfer(
            program_id,
            token_account_info,
            mint_info,
            authority_info,
            account_info_iter.as_slice(),
            &proof_data.transfer_pubkeys.source,
            ciphertext_lo_source,
            ciphertext_hi_source,
            new_source_decryptable_available_balance,
        )?;
        // Process destination account (without fee)
        let ciphertext_lo_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_lo.commitment,
            proof_data.ciphertext_lo.source,
        ));
        let ciphertext_hi_dest = pod::ElGamalCiphertext::from((
            proof_data.ciphertext_hi.commitment,
            proof_data.ciphertext_hi.source,
        ));
        process_dest_for_transfer(
            dest_token_account_info,
            mint_info,
            &proof_data.transfer_pubkeys.dest,
            ciphertext_lo_dest,
            ciphertext_hi_dest,
            None,
        )?;
    }
    Ok(())
}
fn process_transfer ( program_id : & Pubkey , accounts : & [ AccountInfo ] , new_source_decryptable_available_balance : pod :: AeCiphertext , proof_instruction_offset : i64 , ) -> ProgramResult { let account_info_iter = & mut accounts . iter ( ) ; let token_account_info = next_account_info ( account_info_iter ) ? ; let dest_token_account_info = next_account_info ( account_info_iter ) ? ; let mint_info = next_account_info ( account_info_iter ) ? ; let instructions_sysvar_info = next_account_info ( account_info_iter ) ? ; let authority_info = next_account_info ( account_info_iter ) ? ; check_program_account ( mint_info . owner ) ? ; let mint_data = & mint_info . data . borrow_mut ( ) ; let mint = StateWithExtensions :: < Mint > :: unpack ( mint_data ) ? ; let ct_mint = mint . get_extension :: < ConfidentialTransferMint > ( ) ? ; let previous_instruction = get_instruction_relative ( proof_instruction_offset , instructions_sysvar_info ) ? ; if let Ok ( transfer_fee_config ) = mint . get_extension :: < TransferFeeConfig > ( ) { // mint is extended for fees let proof_data = decode_proof_instruction :: < TransferWithFeeData > ( ProofInstruction :: VerifyTransfer , & previous_instruction , ) ? ; if proof_data . transfer_with_fee_pubkeys . auditor != ct_mint . auditor_pubkey { return Err ( TokenError :: ConfidentialTransferElGamalPubkeyMismatch . into ( ) ) ; } // `withdraw_withheld_authority` ElGamal pubkey in proof data and mint must match if proof_data . transfer_with_fee_pubkeys . fee_collector != ct_mint . withdraw_withheld_authority_pubkey { return Err ( TokenError :: ConfidentialTransferElGamalPubkeyMismatch . into ( ) ) ; } // fee parameters in proof data and mint must match let epoch = Clock :: get ( ) ? . epoch ; let ( maximum_fee , transfer_fee_basis_points ) = if u64 :: from ( transfer_fee_config . newer_transfer_fee . epoch ) < epoch { ( u64 :: from ( transfer_fee_config . older_transfer_fee . maximum_fee ) , u16 :: from ( transfer_fee_config . older_transfer_fee . transfer_fee_basis_points , ) , ) } else { ( u64 :: from ( transfer_fee_config . newer_transfer_fee . maximum_fee ) , u16 :: from ( transfer_fee_config . newer_transfer_fee . transfer_fee_basis_points , ) , ) } ; if u64 :: from ( proof_data . fee_parameters . maximum_fee ) != maximum_fee || u16 :: from ( proof_data . fee_parameters . fee_rate_basis_points ) != transfer_fee_basis_points { return Err ( TokenError :: FeeParametersMismatch . into ( ) ) ; } // Process source account let ciphertext_lo_source = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_lo . commitment , proof_data . ciphertext_lo . source , ) ) ; let ciphertext_hi_source = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_hi . commitment , proof_data . ciphertext_hi . source , ) ) ; process_source_for_transfer ( program_id , token_account_info , mint_info , authority_info , account_info_iter . as_slice ( ) , & proof_data . transfer_with_fee_pubkeys . source , ciphertext_lo_source , ciphertext_hi_source , new_source_decryptable_available_balance , ) ? ; // Process destination account (with fee) let ciphertext_lo_dest = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_lo . commitment , proof_data . ciphertext_lo . source , ) ) ; let ciphertext_hi_dest = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_hi . commitment , proof_data . ciphertext_hi . source , ) ) ; process_dest_for_transfer ( dest_token_account_info , mint_info , & proof_data . transfer_with_fee_pubkeys . dest , ciphertext_lo_dest , ciphertext_hi_dest , Some ( proof_data . ciphertext_fee ) , ) ? ; } else { // mint is not extended for fees let proof_data = decode_proof_instruction :: < TransferData > ( ProofInstruction :: VerifyTransfer , & previous_instruction , ) ? ; if proof_data . transfer_pubkeys . auditor != ct_mint . auditor_pubkey { return Err ( TokenError :: ConfidentialTransferElGamalPubkeyMismatch . into ( ) ) ; } // Process source account let ciphertext_lo_source = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_lo . commitment , proof_data . ciphertext_lo . source , ) ) ; let ciphertext_hi_source = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_hi . commitment , proof_data . ciphertext_hi . source , ) ) ; process_source_for_transfer ( program_id , token_account_info , mint_info , authority_info , account_info_iter . as_slice ( ) , & proof_data . transfer_pubkeys . source , ciphertext_lo_source , ciphertext_hi_source , new_source_decryptable_available_balance , ) ? ; // Process destination account (without fee) let ciphertext_lo_dest = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_lo . commitment , proof_data . ciphertext_lo . source , ) ) ; let ciphertext_hi_dest = pod :: ElGamalCiphertext :: from ( ( proof_data . ciphertext_hi . commitment , proof_data . ciphertext_hi . source , ) ) ; process_dest_for_transfer ( dest_token_account_info , mint_info , & proof_data . transfer_pubkeys . dest , ciphertext_lo_dest , ciphertext_hi_dest , None , ) ? ; } Ok ( ( ) ) }
Processes an [Transfer] instruction.
Processes an [ Transfer ] instruction .
program_id
&Pubkey
accounts
&[AccountInfo]
new_source_decryptable_available_balance
pod::AeCiphertext
proof_instruction_offset
i64
program_id
&Pubkey
accounts
&[AccountInfo]
new_source_decryptable_available_balance
pod::AeCiphertext
proof_instruction_offset
i64