use crate::{
error::SwapError,
processor::utils,
state::{SwapInfo, SwapTokenInfo},
};
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
pubkey::Pubkey,
};
use super::logging::log_slippage_error;
fn check_reserves_match(token: &SwapTokenInfo, reserves_info_key: &Pubkey) -> ProgramResult {
check_token_keys_equal!(
token,
*reserves_info_key,
token.reserves,
"Reserves",
SwapError::IncorrectSwapAccount
);
Ok(())
}
pub fn check_has_admin_signer(
expected_admin_key: &Pubkey,
admin_account_info: &AccountInfo,
) -> ProgramResult {
check_keys_equal!(
*expected_admin_key,
*admin_account_info.key,
"Admin signer",
SwapError::Unauthorized
);
if !admin_account_info.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
Ok(())
}
pub fn check_deposit_token_accounts(
token: &SwapTokenInfo,
source_key: &Pubkey,
reserves_info_key: &Pubkey,
) -> ProgramResult {
check_token_keys_not_equal!(
token,
*source_key,
token.reserves,
"Source account cannot be swap token account of token",
SwapError::InvalidInput
);
check_reserves_match(token, reserves_info_key)?;
Ok(())
}
pub fn check_can_withdraw_token(
rate: Option<(u64, u64, u64)>,
minimum_token_amount: u64,
) -> Result<(u64, u64, u64), ProgramError> {
let (amount, fee, admin_fee) = rate.ok_or(SwapError::CalculationFailure)?;
if amount < minimum_token_amount {
log_slippage_error(minimum_token_amount, amount);
return Err(SwapError::ExceededSlippage.into());
}
Ok((amount, fee, admin_fee))
}
pub fn check_withdraw_token_accounts(
token: &SwapTokenInfo,
reserves_info_key: &Pubkey,
admin_fee_dest_key: &Pubkey,
) -> ProgramResult {
check_reserves_match(token, reserves_info_key)?;
check_keys_equal!(
*admin_fee_dest_key,
token.admin_fees,
"Admin fee dest",
SwapError::InvalidAdmin
);
Ok(())
}
pub fn check_swap_authority(
token_swap: &SwapInfo,
swap_info_key: &Pubkey,
program_id: &Pubkey,
swap_authority_key: &Pubkey,
) -> ProgramResult {
let swap_authority = utils::authority_id(program_id, swap_info_key, token_swap.nonce)?;
check_keys_equal!(
*swap_authority_key,
swap_authority,
"Swap authority",
SwapError::InvalidProgramAddress
);
Ok(())
}
pub fn check_swap_token_destination_accounts(
token: &SwapTokenInfo,
swap_destination_info_key: &Pubkey,
admin_destination_info_key: &Pubkey,
) -> ProgramResult {
check_keys_equal!(
*swap_destination_info_key,
token.reserves,
"Incorrect destination, expected",
SwapError::IncorrectSwapAccount
);
check_keys_equal!(
*admin_destination_info_key,
token.admin_fees,
"Admin fee",
SwapError::InvalidAdmin
);
Ok(())
}