1use borsh::{BorshDeserialize, BorshSerialize};
4use solana_program::{
5 clock::Slot,
6 instruction::{AccountMeta, Instruction},
7 program_error::ProgramError,
8 pubkey::Pubkey,
9 sysvar,
10};
11
12#[repr(C)]
14#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
15pub struct InitArgs {
16 pub mint_end_slot: Slot,
18 pub decide_end_slot: Slot,
20 pub bump_seed: u8,
22}
23
24#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
26pub enum PoolInstruction {
27 InitPool(InitArgs),
39
40 Deposit(u64),
54
55 Withdraw(u64),
75
76 Decide(bool),
82}
83
84#[allow(clippy::too_many_arguments)]
86pub fn init_pool(
87 program_id: &Pubkey,
88 pool: &Pubkey,
89 authority: &Pubkey,
90 decider: &Pubkey,
91 deposit_token_mint: &Pubkey,
92 deposit_account: &Pubkey,
93 token_pass_mint: &Pubkey,
94 token_fail_mint: &Pubkey,
95 token_program_id: &Pubkey,
96 init_args: InitArgs,
97) -> Result<Instruction, ProgramError> {
98 let init_data = PoolInstruction::InitPool(init_args);
99 let data = init_data.try_to_vec()?;
100 let accounts = vec![
101 AccountMeta::new(*pool, false),
102 AccountMeta::new_readonly(*authority, false),
103 AccountMeta::new_readonly(*decider, false),
104 AccountMeta::new_readonly(*deposit_token_mint, false),
105 AccountMeta::new(*deposit_account, false),
106 AccountMeta::new(*token_pass_mint, false),
107 AccountMeta::new(*token_fail_mint, false),
108 AccountMeta::new_readonly(sysvar::rent::id(), false),
109 AccountMeta::new_readonly(*token_program_id, false),
110 ];
111 Ok(Instruction {
112 program_id: *program_id,
113 accounts,
114 data,
115 })
116}
117
118#[allow(clippy::too_many_arguments)]
120pub fn deposit(
121 program_id: &Pubkey,
122 pool: &Pubkey,
123 authority: &Pubkey,
124 user_transfer_authority: &Pubkey,
125 user_token_account: &Pubkey,
126 pool_deposit_token_account: &Pubkey,
127 token_pass_mint: &Pubkey,
128 token_fail_mint: &Pubkey,
129 token_pass_destination_account: &Pubkey,
130 token_fail_destination_account: &Pubkey,
131 token_program_id: &Pubkey,
132 amount: u64,
133) -> Result<Instruction, ProgramError> {
134 let init_data = PoolInstruction::Deposit(amount);
135 let data = init_data.try_to_vec()?;
136
137 let accounts = vec![
138 AccountMeta::new_readonly(*pool, false),
139 AccountMeta::new_readonly(*authority, false),
140 AccountMeta::new_readonly(
141 *user_transfer_authority,
142 authority != user_transfer_authority,
143 ),
144 AccountMeta::new(*user_token_account, false),
145 AccountMeta::new(*pool_deposit_token_account, false),
146 AccountMeta::new(*token_pass_mint, false),
147 AccountMeta::new(*token_fail_mint, false),
148 AccountMeta::new(*token_pass_destination_account, false),
149 AccountMeta::new(*token_fail_destination_account, false),
150 AccountMeta::new_readonly(sysvar::clock::id(), false),
151 AccountMeta::new_readonly(*token_program_id, false),
152 ];
153 Ok(Instruction {
154 program_id: *program_id,
155 accounts,
156 data,
157 })
158}
159
160#[allow(clippy::too_many_arguments)]
162pub fn withdraw(
163 program_id: &Pubkey,
164 pool: &Pubkey,
165 authority: &Pubkey,
166 user_transfer_authority: &Pubkey,
167 pool_deposit_token_account: &Pubkey,
168 token_pass_user_account: &Pubkey,
169 token_fail_user_account: &Pubkey,
170 token_pass_mint: &Pubkey,
171 token_fail_mint: &Pubkey,
172 user_token_destination_account: &Pubkey,
173 token_program_id: &Pubkey,
174 amount: u64,
175) -> Result<Instruction, ProgramError> {
176 let init_data = PoolInstruction::Withdraw(amount);
177 let data = init_data.try_to_vec()?;
178 let accounts = vec![
179 AccountMeta::new_readonly(*pool, false),
180 AccountMeta::new_readonly(*authority, false),
181 AccountMeta::new_readonly(
182 *user_transfer_authority,
183 authority != user_transfer_authority,
184 ),
185 AccountMeta::new(*pool_deposit_token_account, false),
186 AccountMeta::new(*token_pass_user_account, false),
187 AccountMeta::new(*token_fail_user_account, false),
188 AccountMeta::new(*token_pass_mint, false),
189 AccountMeta::new(*token_fail_mint, false),
190 AccountMeta::new(*user_token_destination_account, false),
191 AccountMeta::new_readonly(sysvar::clock::id(), false),
192 AccountMeta::new_readonly(*token_program_id, false),
193 ];
194 Ok(Instruction {
195 program_id: *program_id,
196 accounts,
197 data,
198 })
199}
200
201pub fn decide(
203 program_id: &Pubkey,
204 pool: &Pubkey,
205 decider: &Pubkey,
206 decision: bool,
207) -> Result<Instruction, ProgramError> {
208 let init_data = PoolInstruction::Decide(decision);
209 let data = init_data.try_to_vec()?;
210 let accounts = vec![
211 AccountMeta::new(*pool, false),
212 AccountMeta::new_readonly(*decider, true),
213 AccountMeta::new_readonly(sysvar::clock::id(), false),
214 ];
215 Ok(Instruction {
216 program_id: *program_id,
217 accounts,
218 data,
219 })
220}