sniper fee duration

This commit is contained in:
Hardhat Chad
2025-07-18 11:43:24 -07:00
parent b35d487b31
commit 5551ce1c7f
7 changed files with 30 additions and 40 deletions

View File

@@ -67,6 +67,9 @@ pub const DENOMINATOR_BPS: u64 = 10_000;
/// Window to submit hashes, in slots.
pub const INITIAL_BLOCK_DURATION: u64 = 1500;
/// Window to submit hashes, in slots.
pub const INITIAL_SNIPER_FEE_DURATION: u64 = 100;
/// Window to submit hashes, in slots.
pub const MINING_WINDOW: u64 = 1500;

View File

@@ -54,9 +54,7 @@ pub struct Initialize {}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Log {
pub block_id: [u8; 8],
}
pub struct Log {}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]

View File

@@ -2,16 +2,13 @@ use spl_associated_token_account::get_associated_token_address;
use steel::*;
use crate::{
consts::{BLOCK, MINT_ADDRESS, TREASURY_ADDRESS},
consts::{MARKET, MINT_ADDRESS, TREASURY_ADDRESS},
instruction::*,
state::*,
};
pub fn log(signer: Pubkey, block_id: u64, msg: &[u8]) -> Instruction {
let mut data = Log {
block_id: block_id.to_le_bytes(),
}
.to_bytes();
pub fn log(signer: Pubkey, msg: &[u8]) -> Instruction {
let mut data = Log {}.to_bytes();
data.extend_from_slice(msg);
Instruction {
program_id: crate::ID,
@@ -20,17 +17,8 @@ pub fn log(signer: Pubkey, block_id: u64, msg: &[u8]) -> Instruction {
}
}
pub fn program_log(
block_id: u64,
accounts: &[AccountInfo],
msg: &[u8],
) -> Result<(), ProgramError> {
invoke_signed(
&log(*accounts[0].key, block_id, msg),
accounts,
&crate::ID,
&[BLOCK, &block_id.to_le_bytes()],
)
pub fn program_log(accounts: &[AccountInfo], msg: &[u8]) -> Result<(), ProgramError> {
invoke_signed(&log(*accounts[0].key, msg), accounts, &crate::ID, &[MARKET])
}
pub fn mine(signer: Pubkey, authority: Pubkey, id: u64, nonce: u64) -> Instruction {

View File

@@ -13,6 +13,9 @@ pub struct Config {
// The block duration in slots.
pub block_duration: u64,
// The duration in slots for which the sniper fee is applied.
pub sniper_fee_duration: u64,
// The address that receives fees.
pub fee_collector: Pubkey,

View File

@@ -44,6 +44,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
let config = config_info.as_account_mut::<Config>(&ore_api::ID)?;
config.admin = *signer_info.key;
config.block_duration = INITIAL_BLOCK_DURATION;
config.sniper_fee_duration = INITIAL_SNIPER_FEE_DURATION;
config.fee_collector = *signer_info.key;
config.fee_rate = FEE_LAMPORTS;

View File

@@ -69,7 +69,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
}
}
// Burn vault liquidity.
// Burn all ORE in market liquidity vault.
let burn_amount = vault.amount();
burn_signed(
vault_info,

View File

@@ -68,7 +68,7 @@ pub fn process_swap(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult
}
// Set the sniper fee based on time since the market began.
let fee_rate = calculate_sniper_fee(&clock, block);
let fee_rate = calculate_sniper_fee(block, &clock, config);
market.fee.rate = fee_rate;
// Execute the swap
@@ -105,7 +105,7 @@ pub fn process_swap(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult
miner.total_hashpower -= swap_event.base_to_transfer;
block.total_hashpower -= swap_event.base_to_transfer;
// Trasnfer ORE from market to signer.
// Transfer ORE from market to signer.
transfer_signed(
market_info,
vault_info,
@@ -123,35 +123,32 @@ pub fn process_swap(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult
// Emit event.
program_log(
block.id,
&[block_info.clone(), ore_program.clone()],
&[market_info.clone(), ore_program.clone()],
&swap_event.to_bytes(),
)?;
Ok(())
}
fn calculate_sniper_fee(clock: &Clock, block: &Block) -> u64 {
fn calculate_sniper_fee(block: &Block, clock: &Clock, config: &Config) -> u64 {
let elapsed_slots = clock.slot.saturating_sub(block.start_slot);
if elapsed_slots >= 100 {
if elapsed_slots >= config.sniper_fee_duration {
return 0;
}
// Linear decay from 5000 bps (50%) to 0 bps over 100 slots
// Using formula: y = mx + b
// Where:
// - x is elapsed_slots (0 to 100)
// - y is fee_bps (5000 to 0)
// - m = -50 (slope)
// - b = 5000 (y-intercept)
let remaining_fee = 5000 - (elapsed_slots * 50);
remaining_fee
let fee_bps = 5000 * (config.sniper_fee_duration - elapsed_slots) / config.sniper_fee_duration;
fee_bps
}
#[test]
fn test_sniper_fees() {
let config = Config {
sniper_fee_duration: 100,
fee_rate: 0,
fee_collector: Pubkey::default(),
admin: Pubkey::default(),
block_duration: 0,
};
let mut clock = Clock {
slot: 0,
epoch_start_timestamp: 0,
@@ -174,7 +171,7 @@ fn test_sniper_fees() {
for i in 0..200 {
clock.slot = i;
let fee = calculate_sniper_fee(&clock, &block);
let fee = calculate_sniper_fee(&block, &clock, &config);
println!("Slot {}: {} bps fee", i, fee);
}