shadow_drive_user_staking/instructions/
unmark_delete_account.rs1use crate::constants::*;
2use crate::errors::ErrorCodes;
3use crate::instructions::{initialize_account::{ShadowDriveStorageAccount, StorageAccount, StorageAccountV2}, initialize_config::StorageConfig};
4use anchor_lang::prelude::*;
5use anchor_spl::token::{Mint, TokenAccount};
6
7
8pub fn handler(mut ctx: impl UnmarkDeleteAccount) -> Result<()> {
10 require!(
12 !ctx.check_immutable(),
13 ErrorCodes::StorageAccountMarkedImmutable
14 );
15
16 require!(
18 ctx.check_delete_flag(),
19 ErrorCodes::AccountNotMarkedToBeDeleted
20 );
21
22 require_gt!(
24 ctx.get_balance(),
25 0,
26 ErrorCodes::EmptyStakeAccount
27 );
28
29 msg!(
30 "Unmarking storage account {} for deletion",
31 ctx.get_identifier()
32 );
33 ctx.unmark_delete();
34
35 Ok(())
36}
37
38#[derive(Accounts)]
39pub struct UnmarkDeleteAccountV1<'info> {
42 #[account(
44 seeds = [
45 "storage-config".as_bytes()
46 ],
47 bump,
48 )]
49 pub storage_config: Box<Account<'info, StorageConfig>>,
50
51 #[account(
53 mut,
54 seeds = [
55 "storage-account".as_bytes(),
56 &storage_account.owner_1.key().to_bytes(),
57 &storage_account.account_counter_seed.to_le_bytes()
58 ],
59 bump,
60 )]
61 pub storage_account: Box<Account<'info, StorageAccount>>,
62
63 #[account(
65 mut,
66 seeds = [
67 "stake-account".as_bytes(),
68 &storage_account.key().to_bytes()
69 ],
70 bump,
71 )]
72 pub stake_account: Box<Account<'info, TokenAccount>>,
73
74 #[account(mut, constraint=storage_account.is_owner(owner.key()))]
77 pub owner: Signer<'info>,
78
79 #[account(address = shdw::ID)]
81 pub token_mint: Account<'info, Mint>,
82
83 pub system_program: Program<'info, System>,
85}
86
87#[derive(Accounts)]
88pub struct UnmarkDeleteAccountV2<'info> {
91 #[account(
93 seeds = [
94 "storage-config".as_bytes()
95 ],
96 bump,
97 )]
98 pub storage_config: Box<Account<'info, StorageConfig>>,
99
100 #[account(
102 mut,
103 seeds = [
104 "storage-account".as_bytes(),
105 &storage_account.owner_1.key().to_bytes(),
106 &storage_account.account_counter_seed.to_le_bytes()
107 ],
108 bump,
109 )]
110 pub storage_account: Box<Account<'info, StorageAccountV2>>,
111
112 #[account(
114 mut,
115 seeds = [
116 "stake-account".as_bytes(),
117 &storage_account.key().to_bytes()
118 ],
119 bump,
120 )]
121 pub stake_account: Box<Account<'info, TokenAccount>>,
122
123 #[account(mut, constraint=storage_account.is_owner(owner.key()))]
126 pub owner: Signer<'info>,
127
128 #[account(address = shdw::ID)]
130 pub token_mint: Account<'info, Mint>,
131
132 pub system_program: Program<'info, System>,
134}
135
136type Shades = u64;
137
138pub trait UnmarkDeleteAccount {
139 fn check_immutable(&self) -> bool;
140 fn check_delete_flag(&self) -> bool;
141 fn get_identifier(&self) -> String;
142 fn get_balance(&self) -> Shades;
143 fn unmark_delete(&mut self);
144}
145
146impl UnmarkDeleteAccount for Context<'_,'_,'_,'_, UnmarkDeleteAccountV1<'_>> {
147 fn check_immutable(&self) -> bool {
148 self.accounts.storage_account.check_immutable()
149 }
150 fn check_delete_flag(&self) -> bool {
151 self.accounts.storage_account.to_be_deleted
152 }
153 fn get_identifier(&self) -> String {
154 self.accounts.storage_account.get_identifier()
155 }
156 fn get_balance(&self) -> Shades {
157 self.accounts.stake_account.amount
158 }
159 fn unmark_delete(&mut self) {
160 let storage_account = &mut self.accounts.storage_account;
161
162 storage_account.to_be_deleted = false;
164 storage_account.delete_request_epoch = 0;
165 }
166}
167
168
169impl UnmarkDeleteAccount for Context<'_,'_,'_,'_, UnmarkDeleteAccountV2<'_>> {
170 fn check_immutable(&self) -> bool {
171 self.accounts.storage_account.check_immutable()
172 }
173 fn check_delete_flag(&self) -> bool {
174 self.accounts.storage_account.to_be_deleted
175 }
176 fn get_identifier(&self) -> String {
177 self.accounts.storage_account.get_identifier()
178 }
179 fn get_balance(&self) -> Shades {
180 self.accounts.stake_account.amount
181 }
182 fn unmark_delete(&mut self) {
183 let storage_account = &mut self.accounts.storage_account;
184
185 storage_account.to_be_deleted = false;
187 storage_account.delete_request_epoch = 0;
188 }
189}