diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 63d713f..2b2062f 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -3,6 +3,7 @@ use steel::*; #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] pub enum OreInstruction { + // User Open = 0, Close = 1, Commit = 2, @@ -11,6 +12,11 @@ pub enum OreInstruction { Swap = 5, Uncommit = 6, Withdraw = 7, + + // Admin + SetAdmin = 10, + SetFeeCollector = 9, + SetFeeRate = 8, } #[repr(C)] @@ -64,6 +70,24 @@ pub struct Withdraw { pub amount: [u8; 8], } +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct SetAdmin { + pub admin: [u8; 32], +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct SetFeeCollector { + pub fee_collector: [u8; 32], +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct SetFeeRate { + pub fee_rate: [u8; 8], +} + instruction!(OreInstruction, Open); instruction!(OreInstruction, Close); instruction!(OreInstruction, Commit); @@ -72,3 +96,6 @@ instruction!(OreInstruction, Mine); instruction!(OreInstruction, Swap); instruction!(OreInstruction, Uncommit); instruction!(OreInstruction, Withdraw); +instruction!(OreInstruction, SetAdmin); +instruction!(OreInstruction, SetFeeCollector); +instruction!(OreInstruction, SetFeeRate); diff --git a/api/src/state/config.rs b/api/src/state/config.rs index 931f4d4..bdc2084 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -4,11 +4,13 @@ use crate::state::config_pda; use super::OreAccount; -// TODO Config stuff - #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] -pub struct Config {} +pub struct Config { + pub admin: Pubkey, + pub fee_collector: Pubkey, + pub fee_rate: u64, +} impl Config { pub fn pda() -> (Pubkey, u8) { diff --git a/program/src/lib.rs b/program/src/lib.rs index 7b29b83..66384aa 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -3,6 +3,9 @@ mod commit; mod deposit; mod mine; mod open; +mod set_admin; +mod set_fee_collector; +mod set_fee_rate; mod swap; mod uncommit; mod withdraw; @@ -12,6 +15,9 @@ use commit::*; use deposit::*; use mine::*; use open::*; +use set_admin::*; +use set_fee_collector::*; +use set_fee_rate::*; use swap::*; use uncommit::*; use withdraw::*; @@ -35,6 +41,9 @@ pub fn process_instruction( OreInstruction::Swap => process_swap(accounts, data)?, OreInstruction::Uncommit => process_uncommit(accounts, data)?, OreInstruction::Withdraw => process_withdraw(accounts, data)?, + OreInstruction::SetAdmin => process_set_admin(accounts, data)?, + OreInstruction::SetFeeCollector => process_set_fee_collector(accounts, data)?, + OreInstruction::SetFeeRate => process_set_fee_rate(accounts, data)?, } Ok(()) diff --git a/program/src/set_admin.rs b/program/src/set_admin.rs new file mode 100644 index 0000000..f71940b --- /dev/null +++ b/program/src/set_admin.rs @@ -0,0 +1,45 @@ +use ore_api::prelude::*; +use steel::*; + +/// Sets the admin. +pub fn process_set_admin(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse data. + let args = SetAdmin::try_from_bytes(data)?; + let new_admin = Pubkey::new_from_array(args.admin); + + // Load accounts. + let [signer_info, config_info, system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + signer_info.is_signer()?; + system_program.is_program(&system_program::ID)?; + + // Load config account. + let config = if config_info.data_is_empty() { + // Assert signer is admin. + // signer_info.has_address(&ADMIN_ADDRESS)?; + + // Create config account. + create_program_account::( + config_info, + system_program, + signer_info, + &ore_api::ID, + &[CONFIG], + )?; + let config = config_info.as_account_mut::(&ore_api::ID)?; + config.admin = *signer_info.key; + config.fee_collector = *signer_info.key; + config.fee_rate = 0; + config + } else { + config_info + .as_account_mut::(&ore_api::ID)? + .assert_mut(|c| c.admin == *signer_info.key)? + }; + + // Set admin. + config.admin = new_admin; + + Ok(()) +} diff --git a/program/src/set_fee_collector.rs b/program/src/set_fee_collector.rs new file mode 100644 index 0000000..34ddfaf --- /dev/null +++ b/program/src/set_fee_collector.rs @@ -0,0 +1,24 @@ +use ore_api::prelude::*; +use steel::*; + +/// Sets the fee collector. +pub fn process_set_fee_collector(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse data. + let args = SetFeeCollector::try_from_bytes(data)?; + let new_fee_collector = Pubkey::new_from_array(args.fee_collector); + + // Load accounts. + let [signer_info, config_info, system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + signer_info.is_signer()?; + let config = config_info + .as_account_mut::(&ore_api::ID)? + .assert_mut(|c| c.admin == *signer_info.key)?; + system_program.is_program(&system_program::ID)?; + + // Set fee collector. + config.fee_collector = new_fee_collector; + + Ok(()) +} diff --git a/program/src/set_fee_rate.rs b/program/src/set_fee_rate.rs new file mode 100644 index 0000000..03c6259 --- /dev/null +++ b/program/src/set_fee_rate.rs @@ -0,0 +1,24 @@ +use ore_api::prelude::*; +use steel::*; + +/// Sets the fee rate. +pub fn process_set_fee_rate(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse data. + let args = SetFeeRate::try_from_bytes(data)?; + let new_fee_rate = u64::from_le_bytes(args.fee_rate); + + // Load accounts. + let [signer_info, config_info, system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + signer_info.is_signer()?; + let config = config_info + .as_account_mut::(&ore_api::ID)? + .assert_mut(|c| c.admin == *signer_info.key)?; + system_program.is_program(&system_program::ID)?; + + // Set fee rate. + config.fee_rate = new_fee_rate; + + Ok(()) +}