pub mod multisig;
pub mod order;
pub mod pool;
pub mod token_pair;
use {crate::math, anchor_lang::prelude::*};
pub fn is_empty_account(account_info: &AccountInfo) -> Result<bool> {
Ok(account_info.try_data_is_empty()? || account_info.try_lamports()? == 0)
}
pub fn initialize_account<'info>(
payer: AccountInfo<'info>,
target_account: AccountInfo<'info>,
system_program: AccountInfo<'info>,
owner: &Pubkey,
seeds: &[&[&[u8]]],
len: usize,
) -> Result<()> {
let current_lamports = target_account.try_lamports()?;
if current_lamports == 0 {
let lamports = Rent::get()?.minimum_balance(len);
let cpi_accounts = anchor_lang::system_program::CreateAccount {
from: payer,
to: target_account,
};
let cpi_context = anchor_lang::context::CpiContext::new(system_program, cpi_accounts);
anchor_lang::system_program::create_account(
cpi_context.with_signer(seeds),
lamports,
math::checked_as_u64(len)?,
owner,
)?;
} else {
let required_lamports = Rent::get()?
.minimum_balance(len)
.saturating_sub(current_lamports);
if required_lamports > 0 {
let cpi_accounts = anchor_lang::system_program::Transfer {
from: payer,
to: target_account.clone(),
};
let cpi_context =
anchor_lang::context::CpiContext::new(system_program.clone(), cpi_accounts);
anchor_lang::system_program::transfer(cpi_context, required_lamports)?;
}
let cpi_accounts = anchor_lang::system_program::Allocate {
account_to_allocate: target_account.clone(),
};
let cpi_context =
anchor_lang::context::CpiContext::new(system_program.clone(), cpi_accounts);
anchor_lang::system_program::allocate(
cpi_context.with_signer(seeds),
math::checked_as_u64(len)?,
)?;
let cpi_accounts = anchor_lang::system_program::Assign {
account_to_assign: target_account,
};
let cpi_context = anchor_lang::context::CpiContext::new(system_program, cpi_accounts);
anchor_lang::system_program::assign(cpi_context.with_signer(seeds), owner)?;
}
Ok(())
}
pub fn transfer_sol_from_owned<'a>(
program_owned_source_account: AccountInfo<'a>,
destination_account: AccountInfo<'a>,
amount: u64,
) -> Result<()> {
if amount == 0 {
return Ok(());
}
**destination_account.try_borrow_mut_lamports()? = destination_account
.try_lamports()?
.checked_add(amount)
.ok_or(ProgramError::InsufficientFunds)?;
let source_balance = program_owned_source_account.try_lamports()?;
if source_balance < amount {
msg!(
"Error: Not enough funds to withdraw {} lamports from {}",
amount,
program_owned_source_account.key
);
return Err(ProgramError::InsufficientFunds.into());
}
**program_owned_source_account.try_borrow_mut_lamports()? = source_balance
.checked_sub(amount)
.ok_or(ProgramError::InsufficientFunds)?;
Ok(())
}