triad_protocol/instructions/stake/
request_withdraw_stake.rs1use crate::constants::TTRIAD_MINT;
2use crate::constraints::{ is_authority_for_stake, is_mint_for_stake };
3use crate::{ StakeV2, User };
4use crate::{ errors::TriadProtocolError, StakeVault };
5use anchor_lang::prelude::*;
6use anchor_spl::token_2022::Token2022;
7use anchor_spl::token_interface::Mint;
8
9#[derive(Accounts)]
10pub struct RequestWithdrawStake<'info> {
11 #[account(mut)]
12 pub signer: Signer<'info>,
13
14 #[account(mut)]
15 pub stake_vault: Box<Account<'info, StakeVault>>,
16
17 #[account(mut, constraint = user.authority == *signer.key)]
18 pub user: Box<Account<'info, User>>,
19
20 #[account(mut, constraint = is_authority_for_stake(&stake, &signer)?)]
21 pub stake: Box<Account<'info, StakeV2>>,
22
23 #[account(mut, constraint = is_mint_for_stake(&stake, &mint.key())?)]
24 pub mint: Box<InterfaceAccount<'info, Mint>>,
25
26 pub token_program: Program<'info, Token2022>,
27 pub system_program: Program<'info, System>,
28}
29
30pub fn request_withdraw_stake(ctx: Context<RequestWithdrawStake>) -> Result<()> {
31 let stake: &mut Box<Account<StakeV2>> = &mut ctx.accounts.stake;
32 let user: &mut Box<Account<User>> = &mut ctx.accounts.user;
33 let stake_vault: &mut Box<Account<StakeVault>> = &mut ctx.accounts.stake_vault;
34
35 if stake.withdraw_ts != 0 {
36 return Err(TriadProtocolError::Unauthorized.into());
37 }
38
39 let mut days = 3;
40
41 if stake.mint.to_string() == TTRIAD_MINT {
42 days = 7;
43
44 let result = user.staked / (10u64).pow(stake_vault.token_decimals as u32) / 10000;
45
46 if result > (i16::MAX as u64) {
47 return Err(TriadProtocolError::StakeOverflow.into());
48 } else {
49 user.swaps = result as i16;
50 }
51 }
52
53 stake.withdraw_ts = Clock::get()?.unix_timestamp + days * 24 * 60 * 60;
54
55 Ok(())
56}