use crate::*;
use anchor_spl::token::{self, Token, TokenAccount};
#[derive(Accounts)]
pub struct WithdrawAuthorFee<'info> {
#[account(has_one = bankman @ crate::ErrorCode::UnauthorizedNotBankman)]
pub bank: Account<'info, Bank>,
pub bankman: Signer<'info>,
#[account(has_one = bank)]
pub collateral: Account<'info, Collateral>,
#[account(mut, constraint = author_fees.mint == collateral.mint)]
pub author_fees: Account<'info, TokenAccount>,
#[account(mut)]
pub destination: Account<'info, TokenAccount>,
pub token_program: Program<'info, Token>,
}
impl<'info> Validate<'info> for WithdrawAuthorFee<'info> {
fn validate(&self) -> Result<()> {
assert_keys_neq!(self.author_fees, self.destination);
assert_keys_eq!(self.author_fees.owner, self.bank);
assert_keys_eq!(self.author_fees.mint, self.collateral.mint);
Ok(())
}
}
pub fn handler(ctx: Context<WithdrawAuthorFee>, amount: u64) -> Result<()> {
let signer_seeds: &[&[&[u8]]] = &[&[
b"Bank".as_ref(),
&ctx.accounts.bank.crate_token.to_bytes(),
&[ctx.accounts.bank.bump],
]];
token::transfer(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
token::Transfer {
from: ctx.accounts.author_fees.to_account_info(),
to: ctx.accounts.destination.to_account_info(),
authority: ctx.accounts.bank.to_account_info(),
},
)
.with_signer(signer_seeds),
amount,
)?;
Ok(())
}