diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 3051f78..c322b78 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -4,13 +4,14 @@ use steel::*; #[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] pub enum OreInstruction { // User - ClaimSOL = 0, - ClaimORE = 1, - Initialize = 2, - InitializeSquares = 3, - Prospect = 4, - Redeem = 5, - Reset = 6, + Boost = 0, + ClaimSOL = 1, + ClaimORE = 2, + Initialize = 3, + InitializeSquares = 4, + Prospect = 5, + Redeem = 6, + Reset = 7, // Admin SetAdmin = 8, @@ -20,6 +21,10 @@ pub enum OreInstruction { ClaimSeeker = 13, } +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Boost {} + #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct ClaimSOL { @@ -111,6 +116,7 @@ pub struct SetSniperFeeDuration { #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct ClaimSeeker {} +instruction!(OreInstruction, Boost); instruction!(OreInstruction, ClaimSOL); instruction!(OreInstruction, ClaimORE); instruction!(OreInstruction, Redeem); diff --git a/api/src/sdk.rs b/api/src/sdk.rs index 611dd86..be4c1e2 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -7,6 +7,28 @@ use crate::{ state::*, }; +// let [signer_info, config_info, mint_info, reserve_tokens_info, treasury_info, system_program, token_program] = + +pub fn boost(signer: Pubkey) -> Instruction { + let config_address = config_pda().0; + let mint_address = MINT_ADDRESS; + let reserve_tokens_address = BOOST_RESERVE_TOKEN; + let treasury_address = TREASURY_ADDRESS; + Instruction { + program_id: crate::ID, + accounts: vec![ + AccountMeta::new(signer, true), + AccountMeta::new(config_address, false), + AccountMeta::new(mint_address, false), + AccountMeta::new(reserve_tokens_address, false), + AccountMeta::new(treasury_address, false), + AccountMeta::new_readonly(system_program::ID, false), + AccountMeta::new_readonly(spl_token::ID, false), + ], + data: Boost {}.to_bytes(), + } +} + // let [signer_info, board_info, config_info, mint_info, treasury_info, vault_info, system_program, token_program, associated_token_program] = pub fn initialize(signer: Pubkey) -> Instruction { diff --git a/api/src/state/config.rs b/api/src/state/config.rs index 63ad89c..26a2ac6 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -10,16 +10,18 @@ pub struct Config { // The address that can set the admin. pub admin: Pubkey, - // The block duration in slots. - pub block_duration: u64, + // The last boost timestamp. + pub last_boost: i64, // The duration in slots for which the sniper fee is applied. + #[deprecated(since = "1.0.0", note = "Unused")] pub sniper_fee_duration: u64, // The address that receives fees. pub fee_collector: Pubkey, // The fee rate taken for each swap. + #[deprecated(since = "1.0.0", note = "Unused")] pub fee_rate: u64, } diff --git a/cli/src/main.rs b/cli/src/main.rs index db69b14..4a2a1a3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -30,6 +30,9 @@ async fn main() { .expect("Missing COMMAND env var") .as_str() { + "boost" => { + boost(&rpc, &payer).await.unwrap(); + } "clock" => { log_clock(&rpc).await.unwrap(); } @@ -88,6 +91,15 @@ async fn main() { }; } +async fn boost( + rpc: &RpcClient, + payer: &solana_sdk::signer::keypair::Keypair, +) -> Result<(), anyhow::Error> { + let ix = ore_api::sdk::boost(payer.pubkey()); + submit_transaction(rpc, payer, &[ix]).await?; + Ok(()) +} + async fn keys() -> Result<(), anyhow::Error> { let treasury_address = ore_api::state::treasury_pda().0; let config_address = ore_api::state::config_pda().0; @@ -282,7 +294,7 @@ async fn log_config(rpc: &RpcClient) -> Result<(), anyhow::Error> { let config = get_config(&rpc).await?; println!("Config"); println!(" admin: {}", config.admin); - println!(" block_duration: {}", config.block_duration); + println!(" last_boost: {}", config.last_boost); println!(" sniper_fee_duration: {}", config.sniper_fee_duration); println!(" fee_collector: {}", config.fee_collector); println!(" fee_rate: {}", config.fee_rate); diff --git a/program/src/boost.rs b/program/src/boost.rs new file mode 100644 index 0000000..f99f536 --- /dev/null +++ b/program/src/boost.rs @@ -0,0 +1,39 @@ +use ore_api::prelude::*; +use steel::*; + +/// Sets the admin. +pub fn process_boost(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { + // Load accounts. + let clock = Clock::get()?; + let [signer_info, config_info, mint_info, reserve_tokens_info, treasury_info, system_program, token_program] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + signer_info.is_signer()?; + let config = config_info + .as_account_mut::(&ore_api::ID)? + .assert_mut(|c| clock.unix_timestamp >= c.last_boost + (10 * ONE_MINUTE))?; + mint_info.has_address(&MINT_ADDRESS)?.as_mint()?; + reserve_tokens_info + .has_address(&BOOST_RESERVE_TOKEN)? + .as_token_account()? + .assert(|t| t.mint() == MINT_ADDRESS)?; + system_program.is_program(&system_program::ID)?; + token_program.is_program(&spl_token::ID)?; + + // Update config. + config.last_boost = clock.unix_timestamp; + + // Mint tokens to the boost program. + mint_to_signed( + mint_info, + reserve_tokens_info, + treasury_info, + token_program, + ONE_ORE * 3, + &[TREASURY], + )?; + + Ok(()) +} diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 137f032..479a0c7 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -54,9 +54,9 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program )?; let config = config_info.as_account_mut::(&ore_api::ID)?; config.admin = *signer_info.key; - config.block_duration = 0; - config.sniper_fee_duration = 0; + config.last_boost = 0; config.fee_collector = *signer_info.key; + config.sniper_fee_duration = 0; config.fee_rate = 0; } else { config_info.as_account::(&ore_api::ID)?; diff --git a/program/src/lib.rs b/program/src/lib.rs index 47c2397..8eb62f3 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -1,3 +1,4 @@ +mod boost; mod claim_ore; mod claim_seeker; mod claim_sol; @@ -10,6 +11,7 @@ mod set_admin; mod set_fee_collector; mod whitelist; +use boost::*; use claim_ore::*; use claim_seeker::*; use claim_sol::*; @@ -33,6 +35,7 @@ pub fn process_instruction( match ix { // User + OreInstruction::Boost => process_boost(accounts, data)?, OreInstruction::ClaimSOL => process_claim_sol(accounts, data)?, OreInstruction::ClaimORE => process_claim_ore(accounts, data)?, OreInstruction::Initialize => process_initialize(accounts, data)?, diff --git a/program/src/reset.rs b/program/src/reset.rs index 2b6a1ee..ff76868 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -7,7 +7,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul // Load accounts. let clock = Clock::get()?; let (required_accounts, miner_accounts) = accounts.split_at(9); - let [signer_info, board_info, mint_info, reserve_tokens_info, treasury_info, treasury_tokens_info, system_program, token_program, slot_hashes_sysvar] = + let [signer_info, board_info, mint_info, treasury_info, treasury_tokens_info, system_program, token_program, slot_hashes_sysvar] = required_accounts else { return Err(ProgramError::NotEnoughAccountKeys); @@ -18,26 +18,12 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul .assert_mut(|b| b.slot_hash == [0; 32])? .assert_mut(|b| clock.slot >= b.end_slot)?; let mint = mint_info.has_address(&MINT_ADDRESS)?.as_mint()?; - reserve_tokens_info - .has_address(&BOOST_RESERVE_TOKEN)? - .as_token_account()? - .assert(|t| t.mint() == MINT_ADDRESS)?; let treasury = treasury_info.as_account_mut::(&ore_api::ID)?; treasury_tokens_info.as_associated_token_account(&treasury_info.key, &mint_info.key)?; system_program.is_program(&system_program::ID)?; token_program.is_program(&spl_token::ID)?; slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?; - // Mint tokens to the boost program. - mint_to_signed( - mint_info, - reserve_tokens_info, - treasury_info, - token_program, - ONE_ORE / 3, - &[TREASURY], - )?; - // Sample slot hash. let (winning_square, square_prospects) = if let Ok(slot_hash) = get_slot_hash(board.end_slot, slot_hashes_sysvar) {