This commit is contained in:
Hardhat Chad
2025-06-25 14:52:31 -05:00
parent d03acda291
commit f8a554b29f
6 changed files with 71 additions and 6 deletions

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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::<Block>(&ore_api::ID)?
.assert_mut(|b| clock.slot >= b.start_slot + 1500)?;
let config = config_info.as_account::<Config>(&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::<Market>(&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();

View File

@@ -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)?,
}

View File

@@ -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::<Config>(&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::<Block>(

View File

@@ -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::<Config>(&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(())
}