gmsol_timelock/instructions/bypass/
set_expected_price_provider.rs1use anchor_lang::prelude::*;
2use gmsol_store::{
3 cpi::{accounts::SetExpectedProvider, set_expected_provider},
4 program::GmsolStore,
5 states::{PriceProviderKind, RoleKey, Seed, MAX_ROLE_NAME_LEN},
6 utils::{fixed_str::fixed_str_to_bytes, CpiAuthentication, WithStore},
7 CoreError,
8};
9
10use crate::states::{Executor, ExecutorWalletSigner};
11
12#[derive(Accounts)]
14pub struct SetExpectedPriceProvider<'info> {
15 pub authority: Signer<'info>,
17 #[account(mut)]
20 pub store: UncheckedAccount<'info>,
21 #[account(mut)]
24 pub token_map: UncheckedAccount<'info>,
25 #[account(
27 has_one = store,
28 constraint = executor.load()?.role_name()? == RoleKey::MARKET_KEEPER @ CoreError::InvalidArgument,
29 seeds = [
30 Executor::SEED,
31 store.key.as_ref(),
32 &fixed_str_to_bytes::<MAX_ROLE_NAME_LEN>(RoleKey::MARKET_KEEPER)?,
33 ],
34 bump = executor.load()?.bump,
35 )]
36 pub executor: AccountLoader<'info, Executor>,
37 #[account(
39 mut,
40 seeds = [Executor::WALLET_SEED, executor.key().as_ref()],
41 bump,
42 )]
43 pub wallet: SystemAccount<'info>,
44 pub token: UncheckedAccount<'info>,
47 pub store_program: Program<'info, GmsolStore>,
49 pub system_program: Program<'info, System>,
51}
52
53pub(crate) fn unchecked_set_expected_price_provider(
57 ctx: Context<SetExpectedPriceProvider>,
58 new_expected_price_provider: PriceProviderKind,
59) -> Result<()> {
60 let token = ctx.accounts.token.key;
61 let signer = ExecutorWalletSigner::new(ctx.accounts.executor.key(), ctx.bumps.wallet);
62 let ctx = ctx.accounts.set_expected_provider_ctx();
63
64 set_expected_provider(
65 ctx.with_signer(&[&signer.as_seeds()]),
66 *token,
67 new_expected_price_provider.into(),
68 )?;
69
70 Ok(())
71}
72
73impl<'info> WithStore<'info> for SetExpectedPriceProvider<'info> {
74 fn store_program(&self) -> AccountInfo<'info> {
75 self.store_program.to_account_info()
76 }
77
78 fn store(&self) -> AccountInfo<'info> {
79 self.store.to_account_info()
80 }
81}
82
83impl<'info> CpiAuthentication<'info> for SetExpectedPriceProvider<'info> {
84 fn authority(&self) -> AccountInfo<'info> {
85 self.authority.to_account_info()
86 }
87
88 fn on_error(&self) -> Result<()> {
89 err!(CoreError::PermissionDenied)
90 }
91}
92
93impl<'info> SetExpectedPriceProvider<'info> {
94 fn set_expected_provider_ctx(
95 &self,
96 ) -> CpiContext<'_, '_, '_, 'info, SetExpectedProvider<'info>> {
97 CpiContext::new(
98 self.store_program.to_account_info(),
99 SetExpectedProvider {
100 authority: self.wallet.to_account_info(),
101 store: self.store.to_account_info(),
102 token_map: self.token_map.to_account_info(),
103 },
104 )
105 }
106}