bonfida_utils/
checks.rs

1use solana_program::{
2    account_info::AccountInfo,
3    entrypoint::ProgramResult,
4    msg,
5    program_error::ProgramError,
6    program_pack::Pack,
7    pubkey::Pubkey,
8    sysvar::{rent::Rent, Sysvar},
9};
10use spl_token::state::Account;
11
12// Safety verification functions
13pub fn check_account_key(account: &AccountInfo, key: &Pubkey) -> ProgramResult {
14    if account.key != key {
15        msg!("Wrong account key: {} should be {}", account.key, key);
16        return Err(ProgramError::InvalidArgument);
17    }
18    Ok(())
19}
20
21pub fn check_account_owner(account: &AccountInfo, owner: &Pubkey) -> ProgramResult {
22    if account.owner != owner {
23        msg!("Wrong account owner: {} should be {}", account.owner, owner);
24        return Err(ProgramError::InvalidArgument);
25    }
26    Ok(())
27}
28
29pub fn check_signer(account: &AccountInfo) -> ProgramResult {
30    if !(account.is_signer) {
31        msg!("Missing signature for: {}", account.key);
32        return Err(ProgramError::MissingRequiredSignature);
33    }
34    Ok(())
35}
36
37pub fn check_account_derivation(
38    account: &AccountInfo,
39    seeds: &[&[u8]],
40    program_id: &Pubkey,
41) -> Result<u8, ProgramError> {
42    let (key, nonce) = Pubkey::find_program_address(seeds, program_id);
43    check_account_key(account, &key)?;
44    Ok(nonce)
45}
46
47pub fn check_rent_exempt(account: &AccountInfo) -> ProgramResult {
48    let rent = Rent::get()?;
49    if !rent.is_exempt(account.lamports(), account.data_len()) {
50        return Err(ProgramError::AccountNotRentExempt);
51    }
52    Ok(())
53}
54
55pub fn check_token_account_owner(
56    account: &AccountInfo,
57    owner: &Pubkey,
58) -> Result<Account, ProgramError> {
59    check_account_owner(account, &spl_token::ID)?;
60    let token_account = Account::unpack_from_slice(&account.data.borrow())?;
61    if token_account.owner != *owner {
62        msg!(
63            "Wrong account owner: {} should be {}",
64            token_account.owner,
65            owner
66        );
67        return Err(ProgramError::InvalidArgument);
68    }
69    Ok(token_account)
70}