scaffold bury ix

This commit is contained in:
Hardhat Chad
2025-05-23 17:52:47 -07:00
parent b5a50622a2
commit e942e7ae5b
11 changed files with 146 additions and 9 deletions

13
Cargo.lock generated
View File

@@ -1110,6 +1110,18 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "meteora-pools-sdk"
version = "0.1.1"
source = "git+https://github.com/regolith-labs/meteora-pools-sdk?branch=master#6f5a7eab4a460435591765a7d278f117a946b3bd"
dependencies = [
"borsh 0.10.4",
"num-derive 0.4.2",
"num-traits",
"solana-program",
"thiserror 2.0.12",
]
[[package]] [[package]]
name = "mpl-token-metadata" name = "mpl-token-metadata"
version = "5.1.0" version = "5.1.0"
@@ -1306,6 +1318,7 @@ name = "ore-program"
version = "3.7.0" version = "3.7.0"
dependencies = [ dependencies = [
"drillx", "drillx",
"meteora-pools-sdk",
"mpl-token-metadata", "mpl-token-metadata",
"ore-api 3.7.0", "ore-api 3.7.0",
"ore-boost-api", "ore-boost-api",

View File

@@ -19,6 +19,7 @@ bytemuck = "1.14.3"
bytemuck_derive = "1.7.0" bytemuck_derive = "1.7.0"
const-crypto = "0.1.0" const-crypto = "0.1.0"
drillx = { version = "2.2", features = ["solana"] } drillx = { version = "2.2", features = ["solana"] }
meteora-pools-sdk = "0.1"
mpl-token-metadata = "5.1" mpl-token-metadata = "5.1"
num_enum = "0.7.2" num_enum = "0.7.2"
ore-api = { path = "api" } ore-api = { path = "api" }
@@ -34,6 +35,7 @@ thiserror = "1.0.57"
tokio = { version = "1.37.0", features = ["full"] } tokio = { version = "1.37.0", features = ["full"] }
[patch.crates-io] [patch.crates-io]
meteora-pools-sdk = { git = "https://github.com/regolith-labs/meteora-pools-sdk", branch = "master" }
[profile.release] [profile.release]
overflow-checks = true overflow-checks = true

View File

@@ -1,7 +1,6 @@
# ORE # ORE
**ORE is a cryptocurrency everyone can mine.** **Digital gold, accelerated.**
## API ## API
- [`Consts`](api/src/consts.rs)  Program constants. - [`Consts`](api/src/consts.rs)  Program constants.

View File

@@ -5,9 +5,10 @@ use steel::*;
pub enum OreInstruction { pub enum OreInstruction {
// User // User
Bet = 0, Bet = 0,
Close = 1, Bury = 1,
Payout = 2, Close = 2,
Reset = 3, Payout = 3,
Reset = 4,
// Admin // Admin
Initialize = 100, Initialize = 100,
@@ -20,6 +21,10 @@ pub struct Bet {
pub seed: [u8; 32], pub seed: [u8; 32],
} }
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Bury {}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)] #[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Close {} pub struct Close {}
@@ -37,6 +42,7 @@ pub struct Payout {}
pub struct Initialize {} pub struct Initialize {}
instruction!(OreInstruction, Bet); instruction!(OreInstruction, Bet);
instruction!(OreInstruction, Bury);
instruction!(OreInstruction, Close); instruction!(OreInstruction, Close);
instruction!(OreInstruction, Payout); instruction!(OreInstruction, Payout);
instruction!(OreInstruction, Reset); instruction!(OreInstruction, Reset);

View File

@@ -1,3 +1,35 @@
use steel::*; use steel::*;
use crate::{consts::*, instruction::*, state::*}; use crate::{instruction::*, state::*};
pub fn bet(
signer: Pubkey,
mint: Pubkey,
amount: u64,
id: u64,
round: u64,
seed: Option<[u8; 32]>,
) -> Instruction {
let sender = spl_associated_token_account::get_associated_token_address(&signer, &mint);
let block = block_pda().0;
let block_bets = spl_associated_token_account::get_associated_token_address(&signer, &mint);
let wager = wager_pda(round, id).0;
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(block, false),
AccountMeta::new(block_bets, false),
AccountMeta::new(sender, false),
AccountMeta::new(wager, false),
AccountMeta::new_readonly(spl_token::ID, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
AccountMeta::new_readonly(sysvar::slot_hashes::ID, false),
],
data: Bet {
amount: amount.to_le_bytes(),
seed: seed.unwrap_or([0; 32]),
}
.to_bytes(),
}
}

View File

@@ -19,6 +19,7 @@ default = []
[dependencies] [dependencies]
drillx.workspace = true drillx.workspace = true
meteora-pools-sdk.workspace = true
mpl-token-metadata.workspace = true mpl-token-metadata.workspace = true
ore-api.workspace = true ore-api.workspace = true
ore-boost-api.workspace = true ore-boost-api.workspace = true

View File

@@ -11,7 +11,7 @@ pub fn process_bet(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
// Load accounts. // Load accounts.
let clock = Clock::get()?; let clock = Clock::get()?;
let [signer_info, block_info, wager_info, block_bets_info, sender_info, system_program, token_program, slot_hashes_sysvar] = let [signer_info, block_info, block_bets_info, sender_info, wager_info, system_program, token_program, slot_hashes_sysvar] =
accounts accounts
else { else {
return Err(ProgramError::NotEnoughAccountKeys); return Err(ProgramError::NotEnoughAccountKeys);

69
program/src/bury.rs Normal file
View File

@@ -0,0 +1,69 @@
use meteora_pools_sdk::instructions::{SwapCpi, SwapCpiAccounts, SwapInstructionArgs};
use ore_api::prelude::*;
use steel::*;
pub fn process_bury(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
// Load accounts.
let (required_accounts, meteora_accounts) = accounts.split_at(5);
let [signer_info, block_info, block_bets_info, block_ore_info, bet_mint_info, ore_mint_info] =
required_accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};
signer_info.is_signer()?.has_address(&INITIALIZER_ADDRESS)?;
block_info.as_account::<Block>(&ore_api::ID)?;
let block_bets =
block_bets_info.as_associated_token_account(block_info.key, bet_mint_info.key)?;
block_ore_info.as_associated_token_account(block_info.key, &MINT_ADDRESS)?;
bet_mint_info.as_mint()?;
ore_mint_info.has_address(&MINT_ADDRESS)?.as_mint()?;
// Load meteora accounts.
let [pool_info, a_vault_info, b_vault_info, a_token_vault_info, b_token_vault_info, a_vault_lp_mint_info, b_vault_lp_mint_info, a_vault_lp_info, b_vault_lp_info, protocol_token_fee_info, vault_program_info, token_program_info, meteora_pools_program] =
meteora_accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};
meteora_pools_program.is_program(&meteora_pools_sdk::programs::AMM_ID)?;
// Execute swap.
let swap = SwapCpi::new(
&meteora_pools_program,
SwapCpiAccounts {
pool: pool_info,
user_source_token: block_bets_info,
user_destination_token: block_ore_info,
a_vault: a_vault_info,
b_vault: b_vault_info,
a_token_vault: a_token_vault_info,
b_token_vault: b_token_vault_info,
a_vault_lp_mint: a_vault_lp_mint_info,
b_vault_lp_mint: b_vault_lp_mint_info,
a_vault_lp: a_vault_lp_info,
b_vault_lp: b_vault_lp_info,
protocol_token_fee: protocol_token_fee_info,
user: block_info,
vault_program: vault_program_info,
token_program: token_program_info,
},
SwapInstructionArgs {
in_amount: block_bets.amount(),
minimum_out_amount: 0, // TODO: Calculate minimum out amount with slippage
},
);
let block_bump = block_pda().1;
swap.invoke_signed(&[&[BLOCK, &[block_bump]]])?;
// Burn (bury) the purchased ORE.
let block_ore = block_ore_info.as_associated_token_account(block_info.key, &MINT_ADDRESS)?;
burn_signed(
block_ore_info,
ore_mint_info,
block_info,
token_program_info,
block_ore.amount(),
&[BLOCK, &[block_bump]],
)?;
Ok(())
}

View File

@@ -4,7 +4,7 @@ use steel::*;
/// Initialize sets up the ORE program to begin mining. /// Initialize sets up the ORE program to begin mining.
pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
// Load accounts. // Load accounts.
let [signer_info, block_info, block_bets_info, sol_mint_info, system_program, token_program, associated_token_program] = let [signer_info, block_info, block_bets_info, block_ore_info, ore_mint_info, sol_mint_info, system_program, token_program, associated_token_program] =
accounts accounts
else { else {
return Err(ProgramError::NotEnoughAccountKeys); return Err(ProgramError::NotEnoughAccountKeys);
@@ -15,6 +15,8 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
.is_writable()? .is_writable()?
.has_seeds(&[BLOCK], &ore_api::ID)?; .has_seeds(&[BLOCK], &ore_api::ID)?;
block_bets_info.is_empty()?.is_writable()?; block_bets_info.is_empty()?.is_writable()?;
block_ore_info.is_empty()?.is_writable()?;
ore_mint_info.has_address(&MINT_ADDRESS)?.as_mint()?;
sol_mint_info sol_mint_info
.has_address(&spl_token::native_mint::ID)? .has_address(&spl_token::native_mint::ID)?
.as_mint()?; .as_mint()?;
@@ -41,7 +43,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
block.reward = 0; block.reward = 0;
block.noise = [0; 32]; block.noise = [0; 32];
// Initialize treasury token account. // Initialize block token accounts.
create_associated_token_account( create_associated_token_account(
signer_info, signer_info,
block_info, block_info,
@@ -51,6 +53,15 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
token_program, token_program,
associated_token_program, associated_token_program,
)?; )?;
create_associated_token_account(
signer_info,
block_info,
block_ore_info,
ore_mint_info,
system_program,
token_program,
associated_token_program,
)?;
Ok(()) Ok(())
} }

View File

@@ -1,10 +1,12 @@
mod bet; mod bet;
mod bury;
mod close; mod close;
mod initialize; mod initialize;
mod payout; mod payout;
mod reset; mod reset;
use bet::*; use bet::*;
use bury::*;
use close::*; use close::*;
use initialize::*; use initialize::*;
use payout::*; use payout::*;
@@ -22,6 +24,7 @@ pub fn process_instruction(
match ix { match ix {
OreInstruction::Bet => process_bet(accounts, data)?, OreInstruction::Bet => process_bet(accounts, data)?,
OreInstruction::Bury => process_bury(accounts, data)?,
OreInstruction::Close => process_close(accounts, data)?, OreInstruction::Close => process_close(accounts, data)?,
OreInstruction::Reset => process_reset(accounts, data)?, OreInstruction::Reset => process_reset(accounts, data)?,
OreInstruction::Initialize => process_initialize(accounts, data)?, OreInstruction::Initialize => process_initialize(accounts, data)?,

View File

@@ -26,6 +26,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
token_program.is_program(&spl_token::ID)?; token_program.is_program(&spl_token::ID)?;
slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?; slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?;
// Load boost accounts.
let [boost_config_info, boost_proof_info] = boost_accounts else { let [boost_config_info, boost_proof_info] = boost_accounts else {
return Err(ProgramError::NotEnoughAccountKeys); return Err(ProgramError::NotEnoughAccountKeys);
}; };