arrow_sunny/instructions/
unstake_internal.rs

1//! [crate::arrow_sunny::unstake_internal] instruction processor.
2
3use crate::*;
4use anchor_lang::prelude::*;
5use anchor_spl::token;
6use vipers::{assert_keys_eq, validate::Validate};
7
8impl<'info> UnstakeInternal<'info> {
9    /// Unstakes from the internal miner and burns arrow tokens.
10    pub fn unstake_internal(&self, amount: u64) -> Result<()> {
11        self.arrow_stake
12            .burn(amount, self.stake.token_program.to_account_info())?;
13        self.stake.sunny_unstake_internal(amount)?;
14
15        emit!(BurnEvent {
16            arrow: self.stake.arrow.key(),
17            depositor: self.arrow_stake.depositor.key(),
18            amount,
19            timestamp: Clock::get()?.unix_timestamp
20        });
21
22        Ok(())
23    }
24}
25
26impl<'info> ArrowStake<'info> {
27    fn burn(&self, amount: u64, token_program: AccountInfo<'info>) -> Result<()> {
28        token::burn(
29            CpiContext::new(
30                token_program,
31                token::Burn {
32                    mint: self.arrow_mint.to_account_info(),
33                    from: self.depositor_arrow_tokens.to_account_info(),
34                    authority: self.depositor.to_account_info(),
35                },
36            ),
37            amount,
38        )
39    }
40}
41
42impl<'info> StakeInternal<'info> {
43    fn sunny_unstake_internal(&self, amount: u64) -> Result<()> {
44        let signer_seeds: &[&[&[u8]]] = gen_arrow_signer_seeds!(self.arrow);
45        sunny_anchor::cpi::unstake_internal(
46            CpiContext::new(
47                self.sunny_program.to_account_info(),
48                sunny_anchor::cpi::accounts::QuarryStakeInternal {
49                    vault_owner: self.arrow.to_account_info(),
50                    internal_mint: self.internal_mint.to_account_info(),
51                    internal_mint_token_account: self
52                        .vault_internal_token_account
53                        .to_account_info(),
54                    stake: sunny_anchor::cpi::accounts::QuarryStake {
55                        rewarder: self.internal_stake.rewarder.to_account_info(),
56                        quarry: self.internal_stake.quarry.to_account_info(),
57                        miner: self.internal_stake.miner.to_account_info(),
58                        miner_vault: self.internal_stake.miner_vault.to_account_info(),
59
60                        pool: self.pool.to_account_info(),
61                        vault: self.vault.to_account_info(),
62                        token_program: self.token_program.to_account_info(),
63                        mine_program: self.mine_program.to_account_info(),
64                        clock: self.clock.to_account_info(),
65                    },
66                },
67            )
68            .with_signer(signer_seeds),
69            amount,
70        )?;
71
72        Ok(())
73    }
74}
75
76impl<'info> Validate<'info> for UnstakeInternal<'info> {
77    fn validate(&self) -> Result<()> {
78        assert_keys_eq!(self.arrow_stake.arrow_mint, self.stake.arrow.mint);
79        self.arrow_stake.validate()?;
80        self.stake.validate()?;
81        Ok(())
82    }
83}
84
85impl<'info> Validate<'info> for ArrowStake<'info> {
86    fn validate(&self) -> Result<()> {
87        assert_keys_eq!(self.depositor_arrow_tokens.mint, self.arrow_mint);
88        assert_keys_eq!(self.depositor_arrow_tokens.owner, self.depositor);
89        Ok(())
90    }
91}