use crate::*;
use anchor_spl::token::{Mint, TokenAccount};
use locked_voter::Locker;
use yi::YiToken;
#[derive(Accounts)]
pub struct CreateSAVE<'info> {
pub save_mint: Account<'info, Mint>,
#[account(
init,
seeds = [
b"SAVE".as_ref(),
save_mint.key().as_ref()
],
bump,
payer = payer
)]
pub save: AccountLoader<'info, Save>,
pub yi: AccountLoader<'info, YiToken>,
pub yi_mint: Account<'info, Mint>,
pub yi_tokens: Account<'info, TokenAccount>,
pub locker: Account<'info, Locker>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
}
impl<'info> CreateSAVE<'info> {
fn init_save(&mut self, bump: u8, min_lock_duration: u64) -> Result<()> {
let save = &mut self.save.load_init()?;
save.mint = self.save_mint.key();
save.min_lock_duration = min_lock_duration;
save.bump = bump;
let yi = self.yi.load()?;
save.underlying_mint = yi.underlying_token_mint;
save.yi_mint = yi.mint;
save.yi = self.yi.key();
save.yi_tokens = self.yi_tokens.key();
save.locker = self.locker.key();
Ok(())
}
}
pub fn handler(ctx: Context<CreateSAVE>, min_lock_duration: u64) -> Result<()> {
ctx.accounts
.init_save(unwrap_bump!(ctx, "save"), min_lock_duration)
}
impl<'info> Validate<'info> for CreateSAVE<'info> {
fn validate(&self) -> Result<()> {
assert_keys_eq!(self.save_mint.mint_authority.unwrap(), self.save);
assert_keys_eq!(self.save_mint.freeze_authority.unwrap(), self.save);
invariant!(self.save_mint.supply == 0);
let yi = self.yi.load()?;
invariant!(yi.stake_fee_millibps == 0);
invariant!(yi.unstake_fee_millibps == 0);
assert_keys_eq!(yi.mint, self.yi_mint);
invariant!(self.yi_mint.supply == 0);
invariant!(self.save_mint.decimals == self.yi_mint.decimals);
assert_keys_eq!(self.yi_tokens.owner, self.save);
assert_keys_eq!(self.yi_tokens.mint, self.yi_mint);
assert_is_zero_token_account!(self.yi_tokens);
Ok(())
}
}