gmsol_treasury/instructions/
config.rs1use anchor_lang::prelude::*;
2use gmsol_store::{
3 cpi::{accept_receiver, accounts::AcceptReceiver},
4 program::GmsolStore,
5 states::{Seed, Store},
6 utils::{CpiAuthentication, WithStore},
7};
8use gmsol_utils::InitSpace;
9
10use crate::{
11 constants,
12 states::{
13 config::{Config, ReceiverSigner},
14 treasury::TreasuryVaultConfig,
15 },
16};
17
18#[derive(Accounts)]
20pub struct InitializeConfig<'info> {
21 #[account(mut)]
23 pub payer: Signer<'info>,
24 #[account(mut)]
26 pub store: AccountLoader<'info, Store>,
27 #[account(
29 init,
30 payer = payer,
31 space = 8 + Config::INIT_SPACE,
32 seeds = [Config::SEED, store.key().as_ref()],
33 bump,
34 )]
35 pub config: AccountLoader<'info, Config>,
36 #[account(
38 seeds = [constants::RECEIVER_SEED, config.key().as_ref()],
39 bump,
40 )]
41 pub receiver: SystemAccount<'info>,
42 pub store_program: Program<'info, GmsolStore>,
44 pub system_program: Program<'info, System>,
46}
47
48pub(crate) fn initialize_config(ctx: Context<InitializeConfig>) -> Result<()> {
49 let receiver_bump = ctx.bumps.receiver;
50
51 ctx.accounts.accept_receiver(receiver_bump)?;
52
53 let mut config = ctx.accounts.config.load_init()?;
54 let store = ctx.accounts.store.key();
55 config.init(ctx.bumps.config, receiver_bump, &store);
56
57 msg!("[Treasury] initialized the treasury config for {}", store);
58 Ok(())
59}
60
61impl InitializeConfig<'_> {
62 fn accept_receiver(&self, receiver_bump: u8) -> Result<()> {
63 if self.store.load()?.receiver() != self.receiver.key() {
64 let signer = ReceiverSigner::new(self.config.key(), receiver_bump);
65 accept_receiver(
66 CpiContext::new(
67 self.store_program.to_account_info(),
68 AcceptReceiver {
69 next_receiver: self.receiver.to_account_info(),
70 store: self.store.to_account_info(),
71 },
72 )
73 .with_signer(&[&signer.as_seeds()]),
74 )?;
75 }
76 Ok(())
77 }
78}
79
80#[derive(Accounts)]
82pub struct SetTreasuryVaultConfig<'info> {
83 pub authority: Signer<'info>,
85 pub store: UncheckedAccount<'info>,
88 #[account(mut, has_one = store)]
90 pub config: AccountLoader<'info, Config>,
91 #[account(has_one = config)]
93 pub treasury_vault_config: AccountLoader<'info, TreasuryVaultConfig>,
94 pub store_program: Program<'info, GmsolStore>,
96}
97
98pub(crate) fn unchecked_set_treasury_vault_config(
102 ctx: Context<SetTreasuryVaultConfig>,
103) -> Result<()> {
104 let address = ctx.accounts.treasury_vault_config.key();
105 let previous = ctx
106 .accounts
107 .config
108 .load_mut()?
109 .set_treasury_vault_config(address)?;
110 msg!(
111 "[Treasury] the treasury address has been updated from {} to {}",
112 previous,
113 address
114 );
115 Ok(())
116}
117
118impl<'info> WithStore<'info> for SetTreasuryVaultConfig<'info> {
119 fn store_program(&self) -> AccountInfo<'info> {
120 self.store_program.to_account_info()
121 }
122
123 fn store(&self) -> AccountInfo<'info> {
124 self.store.to_account_info()
125 }
126}
127
128impl<'info> CpiAuthentication<'info> for SetTreasuryVaultConfig<'info> {
129 fn authority(&self) -> AccountInfo<'info> {
130 self.authority.to_account_info()
131 }
132
133 fn on_error(&self) -> Result<()> {
134 err!(gmsol_store::CoreError::PermissionDenied)
135 }
136}
137
138#[derive(Accounts)]
140pub struct UpdateConfig<'info> {
141 pub authority: Signer<'info>,
143 pub store: UncheckedAccount<'info>,
146 #[account(mut, has_one = store)]
148 pub config: AccountLoader<'info, Config>,
149 pub store_program: Program<'info, GmsolStore>,
151}
152
153impl<'info> WithStore<'info> for UpdateConfig<'info> {
154 fn store_program(&self) -> AccountInfo<'info> {
155 self.store_program.to_account_info()
156 }
157
158 fn store(&self) -> AccountInfo<'info> {
159 self.store.to_account_info()
160 }
161}
162
163impl<'info> CpiAuthentication<'info> for UpdateConfig<'info> {
164 fn authority(&self) -> AccountInfo<'info> {
165 self.authority.to_account_info()
166 }
167
168 fn on_error(&self) -> Result<()> {
169 err!(gmsol_store::CoreError::PermissionDenied)
170 }
171}
172
173pub(crate) fn unchecked_set_gt_factor(ctx: Context<UpdateConfig>, factor: u128) -> Result<()> {
177 let previous = ctx.accounts.config.load_mut()?.set_gt_factor(factor)?;
178 msg!(
179 "[Treasury] the GT factor has been updated from {} to {}",
180 previous,
181 factor
182 );
183 Ok(())
184}
185
186pub(crate) fn unchecked_set_buyback_factor(ctx: Context<UpdateConfig>, factor: u128) -> Result<()> {
190 let previous = ctx.accounts.config.load_mut()?.set_buyback_factor(factor)?;
191 msg!(
192 "[Treasury] the buyback factor has been updated from {} to {}",
193 previous,
194 factor
195 );
196 Ok(())
197}