From f8a554b29f93e5f2d538dd35d3c4b798a956ab83 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Wed, 25 Jun 2025 14:52:31 -0500 Subject: [PATCH] config --- api/src/instruction.rs | 14 +++++++++++--- api/src/state/config.rs | 8 ++++++++ program/src/close.rs | 19 ++++++++++++++++++- program/src/lib.rs | 3 +++ program/src/open.rs | 9 +++++++-- program/src/set_block_limit.rs | 24 ++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 program/src/set_block_limit.rs diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 2b2062f..db53ab9 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -14,9 +14,10 @@ pub enum OreInstruction { Withdraw = 7, // Admin - SetAdmin = 10, - SetFeeCollector = 9, - SetFeeRate = 8, + SetAdmin = 8, + SetBlockLimit = 9, + SetFeeCollector = 10, + SetFeeRate = 11, } #[repr(C)] @@ -76,6 +77,12 @@ pub struct SetAdmin { pub admin: [u8; 32], } +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct SetBlockLimit { + pub block_limit: [u8; 8], +} + #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct SetFeeCollector { @@ -97,5 +104,6 @@ instruction!(OreInstruction, Swap); instruction!(OreInstruction, Uncommit); instruction!(OreInstruction, Withdraw); instruction!(OreInstruction, SetAdmin); +instruction!(OreInstruction, SetBlockLimit); instruction!(OreInstruction, SetFeeCollector); instruction!(OreInstruction, SetFeeRate); diff --git a/api/src/state/config.rs b/api/src/state/config.rs index bdc2084..6c10c57 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -7,9 +7,17 @@ use super::OreAccount; #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] pub struct Config { + // The address that can set the admin. pub admin: Pubkey, + + // The address that receives fees. pub fee_collector: Pubkey, + + // The fee rate taken for each swap. pub fee_rate: u64, + + /// Number of blocks that can be open for trading at one time. + pub block_limit: u64, } impl Config { diff --git a/program/src/close.rs b/program/src/close.rs index 25aa9e8..8472e0f 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -5,7 +5,7 @@ use steel::*; pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { // Load accounts. let clock = Clock::get()?; - let [signer_info, block_info, collateral_info, commitment_info, market_info, mint_base_info, mint_quote_info, recipient_info, treasury_info, vault_base_info, vault_quote_info, system_program, token_program] = + let [signer_info, block_info, config_info, collateral_info, commitment_info, fee_collector_info, market_info, mint_base_info, mint_quote_info, recipient_info, treasury_info, vault_base_info, vault_quote_info, system_program, token_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); @@ -14,6 +14,7 @@ pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul let block = block_info .as_account_mut::(&ore_api::ID)? .assert_mut(|b| clock.slot >= b.start_slot + 1500)?; + let config = config_info.as_account::(&ore_api::ID)?; collateral_info .is_writable()? .has_address(&collateral_pda(block.id).0)? @@ -26,6 +27,9 @@ pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul .as_token_account()? .assert(|t| t.mint() == *mint_base_info.key)? .assert(|t| t.owner() == *block_info.key)?; + fee_collector_info + .is_writable()? + .as_associated_token_account(&config.fee_collector, &mint_quote_info.key)?; let market = market_info .as_account_mut::(&ore_api::ID)? .assert_mut(|m| m.id == block.id)?; @@ -76,6 +80,19 @@ pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul .log(); } + // Payout fee. + if market.fee.uncollected > 0 { + transfer_signed( + market_info, + vault_quote_info, + fee_collector_info, + token_program, + market.fee.uncollected, + &[MARKET, &market.id.to_le_bytes()], + )?; + market.fee.uncollected = 0; + } + // Burn base liquidity. let vault_base = vault_base_info.as_token_account()?; let base_burned = vault_base.amount(); diff --git a/program/src/lib.rs b/program/src/lib.rs index 66384aa..d696404 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -4,6 +4,7 @@ mod deposit; mod mine; mod open; mod set_admin; +mod set_block_limit; mod set_fee_collector; mod set_fee_rate; mod swap; @@ -16,6 +17,7 @@ use deposit::*; use mine::*; use open::*; use set_admin::*; +use set_block_limit::*; use set_fee_collector::*; use set_fee_rate::*; use swap::*; @@ -42,6 +44,7 @@ pub fn process_instruction( OreInstruction::Uncommit => process_uncommit(accounts, data)?, OreInstruction::Withdraw => process_withdraw(accounts, data)?, OreInstruction::SetAdmin => process_set_admin(accounts, data)?, + OreInstruction::SetBlockLimit => process_set_block_limit(accounts, data)?, OreInstruction::SetFeeCollector => process_set_fee_collector(accounts, data)?, OreInstruction::SetFeeRate => process_set_fee_rate(accounts, data)?, } diff --git a/program/src/open.rs b/program/src/open.rs index ed35917..b67b756 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -12,7 +12,7 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult // Load accounts. let clock = Clock::get()?; - let [signer_info, block_info, collateral_info, commitment_info, market_info, mint_base_info, mint_quote_info, sender_info, treasury_info, vault_base_info, vault_quote_info, system_program, token_program, associated_token_program, rent_sysvar] = + let [signer_info, block_info, config_info, collateral_info, commitment_info, market_info, mint_base_info, mint_quote_info, sender_info, treasury_info, vault_base_info, vault_quote_info, system_program, token_program, associated_token_program, rent_sysvar] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); @@ -22,6 +22,7 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult .is_empty()? .is_writable()? .has_seeds(&[BLOCK, &id.to_le_bytes()], &ore_api::ID)?; + let config = config_info.as_account::(&ore_api::ID)?; market_info .is_empty()? .is_writable()? @@ -42,11 +43,15 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult // Error out if start slot is within the current period. let start_slot = id * 1500; - let current_period_start = (clock.slot / 1500) * 1500; + let current_block = clock.slot / 1500; + let current_period_start = current_block * 1500; let current_period_end = current_period_start + 1500; if start_slot < current_period_end { return Err(ProgramError::InvalidArgument); } + if id > current_block + config.block_limit { + return Err(ProgramError::InvalidArgument); + } // Initialize config. create_program_account::( diff --git a/program/src/set_block_limit.rs b/program/src/set_block_limit.rs new file mode 100644 index 0000000..65948d6 --- /dev/null +++ b/program/src/set_block_limit.rs @@ -0,0 +1,24 @@ +use ore_api::prelude::*; +use steel::*; + +/// Sets the block limit. +pub fn process_set_block_limit(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse data. + let args = SetBlockLimit::try_from_bytes(data)?; + let new_block_limit = u64::from_le_bytes(args.block_limit); + + // 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 block limit. + config.block_limit = new_block_limit; + + Ok(()) +}