solana_router_saber/
unwrap_token.rs

1//! Unwrap token from a Saber decimal token instruction
2
3use {
4    solana_farm_sdk::program::{account, protocol::saber},
5    solana_program::{
6        account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError,
7    },
8};
9
10pub fn unwrap_token(accounts: &[AccountInfo], amount: u64) -> ProgramResult {
11    msg!("Processing AmmInstruction::UnwrapToken");
12    msg!("amount {} ", amount);
13
14    #[allow(clippy::deprecated_cfg_attr)]
15    #[cfg_attr(rustfmt, rustfmt_skip)]
16    if let [
17        user_account,
18        user_underlying_token_account,
19        underlying_token_mint,
20        _spl_token_id,
21        decimal_wrapper_program,
22        user_wrapped_token_account,
23        wrapped_token_mint,
24        wrapped_token_vault,
25        decimal_wrapper
26        ] = accounts
27    {
28        if !account::check_token_account_owner(user_underlying_token_account, user_account.key)? {
29            return Err(ProgramError::IllegalOwner);
30        }
31
32        let initial_underlying_token_user_balance =
33            account::get_token_balance(user_underlying_token_account)?;
34        let initial_wrapped_token_user_balance =
35            account::get_token_balance(user_wrapped_token_account)?;
36
37        let underlying_decimals = account::get_token_decimals(underlying_token_mint)?;
38        let wrapped_decimals = account::get_token_decimals(wrapped_token_mint)?;
39
40        let unwrap_amount = if amount > 0 {
41            amount
42        } else {
43            initial_wrapped_token_user_balance
44        };
45
46        saber::unwrap_token(
47            decimal_wrapper,
48            wrapped_token_mint,
49            wrapped_token_vault,
50            user_account,
51            user_underlying_token_account,
52            user_wrapped_token_account,
53            decimal_wrapper_program.key,
54            unwrap_amount,
55        )?;
56
57        account::check_tokens_received(
58            user_underlying_token_account,
59            initial_underlying_token_user_balance,
60            account::to_amount_with_new_decimals(
61                unwrap_amount,
62                wrapped_decimals,
63                underlying_decimals,
64            )?,
65        )?;
66        account::check_tokens_spent(
67            user_wrapped_token_account,
68            initial_wrapped_token_user_balance,
69            unwrap_amount,
70        )?;
71    } else {
72        return Err(ProgramError::NotEnoughAccountKeys);
73    }
74
75    msg!("AmmInstruction::UnwrapToken complete");
76    Ok(())
77}