1#![deny(rustdoc::all)]
3#![allow(rustdoc::missing_doc_code_examples)]
4
5#[macro_use]
6mod macros;
7
8mod account_validators;
9mod instructions;
10
11pub mod addresses;
12pub mod events;
13pub mod state;
14
15use anchor_lang::prelude::*;
16use anchor_spl::token::{Mint, Token, TokenAccount};
17use sunny_anchor::{Pool, Vault};
18use vipers::prelude::*;
19
20pub use events::*;
21pub use state::*;
22
23declare_id!("ARoWLTBWoWrKMvxEiaE2EH9DrWyV7mLpKywGDWxBGeq9");
24
25#[program]
27pub mod arrow_sunny {
28 use super::*;
29
30 #[access_control(ctx.accounts.validate())]
32 pub fn new_arrow(ctx: Context<NewArrow>, _bump: u8, vault_bump: u8) -> Result<()> {
33 let bump = unwrap_bump!(ctx, "arrow");
34 ctx.accounts.init_vault(vault_bump)?;
35 ctx.accounts.init_arrow(bump)
36 }
37
38 #[access_control(ctx.accounts.validate())]
40 pub fn init_arrow_internal_miner(
41 ctx: Context<InitArrowMiner>,
42 internal_miner_bump: u8,
43 ) -> Result<()> {
44 ctx.accounts.init_arrow_internal_miner(internal_miner_bump)
45 }
46
47 #[access_control(ctx.accounts.validate())]
49 pub fn init_arrow_vendor_miner(
50 ctx: Context<InitArrowMiner>,
51 vendor_miner_bump: u8,
52 ) -> Result<()> {
53 ctx.accounts.init_arrow_vendor_miner(vendor_miner_bump)
54 }
55
56 #[access_control(ctx.accounts.validate())]
58 pub fn deposit_vendor(ctx: Context<DepositVendor>, amount: u64) -> Result<()> {
59 ctx.accounts.deposit_vendor(amount)
60 }
61
62 #[access_control(ctx.accounts.validate())]
67 pub fn stake_internal(ctx: Context<StakeInternal>) -> Result<()> {
68 ctx.accounts.stake_internal()
69 }
70
71 #[access_control(ctx.accounts.validate())]
73 pub fn unstake_internal(ctx: Context<UnstakeInternal>, amount: u64) -> Result<()> {
74 ctx.accounts.unstake_internal(amount)
75 }
76
77 #[access_control(ctx.accounts.validate())]
82 pub fn withdraw_vendor_tokens(ctx: Context<WithdrawVendorTokens>, amount: u64) -> Result<()> {
83 ctx.accounts.withdraw_vendor_tokens(amount)
84 }
85
86 #[access_control(ctx.accounts.validate())]
89 pub fn claim(ctx: Context<Claim>) -> Result<()> {
90 ctx.accounts.claim()
91 }
92
93 #[access_control(ctx.accounts.validate())]
96 pub fn withdraw_rewards_to_beneficiary(
97 ctx: Context<WithdrawRewardsToBeneficiary>,
98 ) -> Result<()> {
99 ctx.accounts.withdraw_rewards_to_beneficiary()
100 }
101}
102
103#[derive(Accounts)]
109pub struct NewArrow<'info> {
110 #[account(
112 init,
113 seeds = [
114 b"arrow".as_ref(),
115 arrow_mint.key().to_bytes().as_ref()
116 ],
117 bump,
118 space = 8 + Arrow::LEN,
119 payer = payer
120 )]
121 pub arrow: Box<Account<'info, Arrow>>,
122
123 pub arrow_mint: Box<Account<'info, Mint>>,
127
128 #[account(mut)]
130 pub payer: Signer<'info>,
131
132 pub beneficiary: UncheckedAccount<'info>,
135
136 pub pool: Box<Account<'info, Pool>>,
138 #[account(mut)]
140 pub vault: SystemAccount<'info>,
141 pub vendor_mint: Box<Account<'info, Mint>>,
143
144 pub sunny_program: Program<'info, sunny_anchor::program::SunnyAnchor>,
146 pub system_program: Program<'info, System>,
148}
149
150#[derive(Accounts)]
152pub struct InitArrowMiner<'info> {
153 #[account(mut)]
155 pub arrow: Box<Account<'info, Arrow>>,
156 #[account(mut)]
158 pub payer: Signer<'info>,
159
160 pub pool: Box<Account<'info, Pool>>,
162 pub vault: Box<Account<'info, Vault>>,
164
165 pub miner: InitMiner<'info>,
167
168 pub mine_program: Program<'info, quarry_mine::program::QuarryMine>,
170 pub sunny_program: Program<'info, sunny_anchor::program::SunnyAnchor>,
172 pub system_program: Program<'info, System>,
174 pub token_program: Program<'info, Token>,
176}
177
178#[derive(Accounts)]
180pub struct InitMiner<'info> {
181 pub rewarder: Box<Account<'info, quarry_mine::Rewarder>>,
183 #[account(mut)]
185 pub quarry: Box<Account<'info, quarry_mine::Quarry>>,
186 #[account(mut)]
188 pub miner: SystemAccount<'info>,
189 pub miner_vault: Box<Account<'info, TokenAccount>>,
193 pub token_mint: Box<Account<'info, Mint>>,
195}
196
197#[derive(Accounts)]
199pub struct DepositVendor<'info> {
200 pub arrow: Box<Account<'info, Arrow>>,
202 pub arrow_stake: ArrowStake<'info>,
204
205 #[account(mut)]
207 pub depositor_staked_tokens: Box<Account<'info, TokenAccount>>,
208
209 #[account(mut)]
211 pub vault_vendor_token_account: Box<Account<'info, TokenAccount>>,
212
213 pub vendor_stake: StakeCommon<'info>,
215
216 #[account(mut)]
218 pub pool: Box<Account<'info, Pool>>,
219 #[account(mut)]
221 pub vault: Box<Account<'info, Vault>>,
222
223 pub token_program: Program<'info, Token>,
225 pub mine_program: Program<'info, quarry_mine::program::QuarryMine>,
227 pub sunny_program: Program<'info, sunny_anchor::program::SunnyAnchor>,
229 pub clock: Sysvar<'info, Clock>,
231}
232
233#[derive(Accounts)]
235pub struct StakeInternal<'info> {
236 pub arrow: Box<Account<'info, Arrow>>,
238
239 #[account(mut)]
241 pub internal_mint: Box<Account<'info, Mint>>,
242 #[account(mut)]
244 pub vault_internal_token_account: Box<Account<'info, TokenAccount>>,
245
246 pub internal_stake: StakeCommon<'info>,
248 #[account(mut)]
250 pub pool: Box<Account<'info, Pool>>,
251 #[account(mut)]
253 pub vault: Box<Account<'info, Vault>>,
254
255 pub token_program: Program<'info, Token>,
257 pub mine_program: Program<'info, quarry_mine::program::QuarryMine>,
259 pub sunny_program: Program<'info, sunny_anchor::program::SunnyAnchor>,
261 pub clock: Sysvar<'info, Clock>,
263}
264
265#[derive(Accounts)]
267pub struct UnstakeInternal<'info> {
268 pub arrow_stake: ArrowStake<'info>,
270 pub stake: StakeInternal<'info>,
272}
273
274#[derive(Accounts)]
276pub struct ArrowStake<'info> {
277 #[account(mut)]
279 pub arrow_mint: Box<Account<'info, Mint>>,
280 pub depositor: Signer<'info>,
282 #[account(mut)]
284 pub depositor_arrow_tokens: Box<Account<'info, TokenAccount>>,
285}
286
287#[derive(Accounts)]
291pub struct StakeCommon<'info> {
292 pub rewarder: UncheckedAccount<'info>,
295 #[account(mut)]
298 pub quarry: UncheckedAccount<'info>,
299 #[account(mut)]
302 pub miner: UncheckedAccount<'info>,
303 #[account(mut)]
306 pub miner_vault: UncheckedAccount<'info>,
307}
308
309#[derive(Accounts)]
311pub struct WithdrawVendorTokens<'info> {
312 pub stake: DepositVendor<'info>,
314 #[account(mut)]
316 pub sunny_pool_fee_destination: Account<'info, TokenAccount>,
317}
318
319#[derive(Accounts)]
321pub struct Claim<'info> {
322 pub arrow: Box<Account<'info, Arrow>>,
324
325 #[account(mut)]
327 pub vault_rewards_token_account: Box<Account<'info, TokenAccount>>,
328
329 #[account(mut)]
333 pub claim_fee_token_account: UncheckedAccount<'info>,
334 #[account(mut)]
338 pub stake_token_account: UncheckedAccount<'info>,
339 pub stake: StakeCommon<'info>,
341
342 #[account(mut)]
348 pub mint_wrapper: UncheckedAccount<'info>,
349 #[account(mut)]
351 pub minter: Box<Account<'info, quarry_mint_wrapper::Minter>>,
352 #[account(mut)]
354 pub rewards_token_mint: Box<Account<'info, Mint>>,
355
356 #[account(mut)]
361 pub pool: UncheckedAccount<'info>,
362 #[account(mut)]
365 pub vault: UncheckedAccount<'info>,
366
367 pub mine_program: Program<'info, quarry_mine::program::QuarryMine>,
370 pub mint_wrapper_program: Program<'info, quarry_mint_wrapper::program::QuarryMintWrapper>,
372 pub sunny_program: Program<'info, sunny_anchor::program::SunnyAnchor>,
374 pub token_program: Program<'info, Token>,
376 pub clock: Sysvar<'info, Clock>,
378}
379
380#[derive(Accounts)]
382pub struct WithdrawRewardsToBeneficiary<'info> {
383 pub arrow: Box<Account<'info, Arrow>>,
385
386 #[account(mut)]
389 pub beneficiary_account: Box<Account<'info, TokenAccount>>,
390 #[account(mut)]
392 pub arrow_fee_account: Box<Account<'info, TokenAccount>>,
393 #[account(mut)]
395 pub sunny_pool_fee_account: Box<Account<'info, TokenAccount>>,
396 #[account(mut)]
398 pub arrow_staging_account: Box<Account<'info, TokenAccount>>,
399 #[account(mut)]
401 pub vault_rewards_token_account: Box<Account<'info, TokenAccount>>,
402
403 pub pool: Box<Account<'info, Pool>>,
406 #[account(mut)]
408 pub vault: Box<Account<'info, Vault>>,
409
410 pub sunny_program: Program<'info, sunny_anchor::program::SunnyAnchor>,
412 pub token_program: Program<'info, Token>,
414}
415
416#[error_code]
417pub enum ErrorCode {
418 #[msg("Invalid rewards mint.")]
419 InvalidRewardsMint,
420
421 #[msg("The Arrow's mint's authority must be the arrow.", offset = 10)]
422 NewArrowMintAuthorityInvalid,
423 #[msg("The Arrow's freeze authority must be the arrow.")]
424 NewArrowFreezeAuthorityInvalid,
425 #[msg("Arrow mint must have zero supply")]
426 NewArrowNonZeroSupply,
427 #[msg("Arrow decimals must match the staked token")]
428 NewArrowDecimalMismatch,
429
430 #[msg("Miners already initialized.", offset = 20)]
431 InitArrowMinersAlreadyInitialized,
432}