diff --git a/programs/kfarms/Cargo.toml b/programs/kfarms/Cargo.toml index dbee836..cd32fb5 100644 --- a/programs/kfarms/Cargo.toml +++ b/programs/kfarms/Cargo.toml @@ -36,3 +36,5 @@ static_assertions = "1.1.0" scope = { git = "https://github.com/Kamino-Finance/scope.git", package = "scope-types", branch = "anchor_0.29_idl" } bytemuck = { version = "1.4.0", features = ["min_const_generics", "derive"] } uint = "0.9.5" + + diff --git a/programs/kfarms/src/farm_operations.rs b/programs/kfarms/src/farm_operations.rs index f9c6cca..e27f753 100644 --- a/programs/kfarms/src/farm_operations.rs +++ b/programs/kfarms/src/farm_operations.rs @@ -258,10 +258,10 @@ pub fn update_farm_config( farm_state.scope_prices = pubkey; } FarmConfigOption::ScopeOraclePriceId => { - let value: u16 = BorshDeserialize::try_from_slice(&data[..2])?; + let value: u64 = BorshDeserialize::try_from_slice(&data[..8])?; xmsg!("farm_operations::update_farm_config scope_oracle_price_id={value}",); xmsg!("prev value {:?}", farm_state.scope_oracle_price_id); - farm_state.scope_oracle_price_id = value.into(); + farm_state.scope_oracle_price_id = value; } FarmConfigOption::ScopeOracleMaxAge => { let value: u64 = BorshDeserialize::try_from_slice(data)?; @@ -281,6 +281,12 @@ pub fn update_farm_config( xmsg!("prev value {:?}", farm_state.strategy_id); farm_state.strategy_id = pubkey; } + FarmConfigOption::UpdateDelegatedRpsAdmin => { + let pubkey: Pubkey = BorshDeserialize::try_from_slice(data)?; + xmsg!("farm_operations::update_farm_config delegated_rps_admin={pubkey}",); + xmsg!("prev value {}", farm_state.delegated_rps_admin); + farm_state.delegated_rps_admin = pubkey; + } }; Ok(()) } diff --git a/programs/kfarms/src/handlers/handler_update_farm_admin.rs b/programs/kfarms/src/handlers/handler_update_farm_admin.rs index baeb6d5..a771649 100644 --- a/programs/kfarms/src/handlers/handler_update_farm_admin.rs +++ b/programs/kfarms/src/handlers/handler_update_farm_admin.rs @@ -7,6 +7,12 @@ pub fn process(ctx: Context) -> Result<()> { let farm_state = &mut ctx.accounts.farm_state.load_mut()?; + msg!( + "Update farm admin prev={:?} new={:?}", + farm_state.farm_admin, + farm_state.pending_farm_admin + ); + farm_state.farm_admin = farm_state.pending_farm_admin; Ok(()) diff --git a/programs/kfarms/src/handlers/handler_update_farm_config.rs b/programs/kfarms/src/handlers/handler_update_farm_config.rs index c9e100a..bb36deb 100644 --- a/programs/kfarms/src/handlers/handler_update_farm_config.rs +++ b/programs/kfarms/src/handlers/handler_update_farm_config.rs @@ -1,6 +1,7 @@ use crate::state::FarmConfigOption; use crate::utils::constraints::check_remaining_accounts; use crate::utils::scope::load_scope_price; +use crate::FarmError; use crate::{farm_operations, FarmState}; use anchor_lang::prelude::*; @@ -11,6 +12,20 @@ pub fn process(ctx: Context, mode: u16, data: &[u8]) -> Result let scope_price = load_scope_price(&ctx.accounts.scope_prices, farm_state).map_or(None, |v| v); let mode: FarmConfigOption = mode.try_into().unwrap(); + + if matches!( + mode, + FarmConfigOption::UpdateRewardRps | FarmConfigOption::UpdateRewardScheduleCurvePoints + ) { + require!( + farm_state.delegated_rps_admin == *ctx.accounts.signer.key + || farm_state.farm_admin == *ctx.accounts.signer.key, + FarmError::InvalidFarmConfigUpdateAuthority + ); + } else { + require_keys_eq!(farm_state.farm_admin, *ctx.accounts.signer.key); + } + farm_operations::update_farm_config(farm_state, scope_price, mode, data)?; Ok(()) @@ -19,12 +34,9 @@ pub fn process(ctx: Context, mode: u16, data: &[u8]) -> Result #[derive(Accounts)] pub struct UpdateFarmConfig<'info> { #[account(mut)] - pub farm_admin: Signer<'info>, + pub signer: Signer<'info>, - #[account( - mut, - has_one = farm_admin, - )] + #[account(mut)] pub farm_state: AccountLoader<'info, FarmState>, pub scope_prices: Option>, diff --git a/programs/kfarms/src/handlers/handler_update_global_config_admin.rs b/programs/kfarms/src/handlers/handler_update_global_config_admin.rs index 263fff2..22b00d9 100644 --- a/programs/kfarms/src/handlers/handler_update_global_config_admin.rs +++ b/programs/kfarms/src/handlers/handler_update_global_config_admin.rs @@ -6,6 +6,12 @@ pub fn process(ctx: Context) -> Result<()> { check_remaining_accounts(&ctx)?; let global_config = &mut ctx.accounts.global_config.load_mut()?; + msg!( + "Update global admin prev={:?} new={:?}", + global_config.global_admin, + global_config.pending_global_admin + ); + global_config.global_admin = global_config.pending_global_admin; Ok(()) diff --git a/programs/kfarms/src/lib.rs b/programs/kfarms/src/lib.rs index 163369e..d985305 100644 --- a/programs/kfarms/src/lib.rs +++ b/programs/kfarms/src/lib.rs @@ -278,6 +278,8 @@ pub enum FarmError { RewardScheduleCurveSet, #[msg("Cannot initialize farm while having a mint with token22 and requested extensions")] UnsupportedTokenExtension, + #[msg("Invalid authority for updating farm config")] + InvalidFarmConfigUpdateAuthority, } impl From for FarmError { diff --git a/programs/kfarms/src/state.rs b/programs/kfarms/src/state.rs index 2ad23ef..f947e67 100644 --- a/programs/kfarms/src/state.rs +++ b/programs/kfarms/src/state.rs @@ -119,7 +119,9 @@ pub struct FarmState { pub pending_farm_admin: Pubkey, pub strategy_id: Pubkey, - pub _padding: [u64; 86], + + pub delegated_rps_admin: Pubkey, + pub _padding: [u64; 82], } impl FarmState { @@ -231,8 +233,9 @@ impl Default for FarmState { pending_farm_admin: Pubkey::default(), strategy_id: Pubkey::default(), + delegated_rps_admin: Pubkey::default(), - _padding: [0; 86], + _padding: [0; 82], } } } @@ -572,6 +575,7 @@ pub enum FarmConfigOption { UpdateRewardScheduleCurvePoints, UpdatePendingFarmAdmin, UpdateStrategyId, + UpdateDelegatedRpsAdmin, } #[derive(