brrr/actions/
print_cash.rs

1use std::convert::TryInto;
2
3use crate::*;
4use anchor_lang::prelude::*;
5use converter::CashSwap;
6use vipers::{assert_keys_eq, unwrap_int, validate::Validate};
7
8/// Prints $CASH.
9pub fn print_cash(ctx: Context<PrintCash>, deposit_amount: u64) -> Result<()> {
10    ctx.accounts.print_cash(deposit_amount)
11}
12
13impl<'info> PrintCash<'info> {
14    fn print_cash(&self, deposit_amount: u64) -> Result<()> {
15        let current_balance = self.common.crate_collateral_tokens.amount;
16        require!(
17            unwrap_int!(current_balance.checked_add(deposit_amount))
18                <= self.common.collateral.hard_cap,
19            CollateralHardCapHit
20        );
21
22        let swap: CashSwap = (&self.common.saber_swap).try_into()?;
23        let print_amount = unwrap_int!(swap.calculate_cash_for_pool_tokens(deposit_amount));
24        if print_amount == 0 {
25            return Ok(());
26        }
27
28        // transfer LP tokens to the crate
29        anchor_spl::token::transfer(
30            CpiContext::new(
31                self.common.token_program.to_account_info(),
32                anchor_spl::token::Transfer {
33                    from: self.depositor_source.to_account_info(),
34                    to: self.common.crate_collateral_tokens.to_account_info(),
35                    authority: self.depositor.to_account_info(),
36                },
37            ),
38            deposit_amount,
39        )?;
40
41        // issue new crate tokens
42        crate_token::cpi::issue(
43            CpiContext::new_with_signer(
44                self.common.crate_token_program.to_account_info(),
45                crate_token::cpi::accounts::Issue {
46                    crate_token: self.common.crate_token.to_account_info(),
47                    crate_mint: self.common.crate_mint.to_account_info(),
48                    issue_authority: self.issue_authority.to_account_info(),
49                    mint_destination: self.mint_destination.to_account_info(),
50
51                    // there are no author/protocol fees, so we pass in garbage here
52                    author_fee_destination: self.mint_destination.to_account_info(),
53                    protocol_fee_destination: self.mint_destination.to_account_info(),
54
55                    token_program: self.common.token_program.to_account_info(),
56                },
57                ISSUE_AUTHORITY_SIGNER_SEEDS,
58            ),
59            print_amount,
60        )?;
61
62        emit!(PrintCashEvent {
63            depositor: self.depositor.key(),
64            collateral_mint: self.common.crate_collateral_tokens.mint,
65            deposit_amount,
66            print_amount,
67            timestamp: Clock::get()?.unix_timestamp
68        });
69
70        Ok(())
71    }
72}
73
74impl<'info> Validate<'info> for PrintCash<'info> {
75    fn validate(&self) -> Result<()> {
76        self.common.validate()?;
77        assert_keys_eq!(self.depositor, self.depositor_source.owner);
78        assert_keys_eq!(self.depositor_source.mint, self.common.collateral.mint);
79        assert_keys_eq!(self.mint_destination.mint, self.common.crate_token.mint);
80        assert_keys_eq!(self.issue_authority, ISSUE_AUTHORITY_ADDRESS);
81        Ok(())
82    }
83}