This commit is contained in:
Hardhat Chad
2025-10-15 12:50:20 -07:00
parent 4e3ecff458
commit d2e1567f8d
7 changed files with 109 additions and 58 deletions

View File

@@ -28,8 +28,6 @@ pub enum OreInstruction {
// Seeker // Seeker
ClaimSeeker = 17, ClaimSeeker = 17,
MigrateTreasury = 18,
MigrateMiner = 19,
} }
#[repr(C)] #[repr(C)]
@@ -152,14 +150,6 @@ pub struct Checkpoint {}
#[derive(Clone, Copy, Debug, Pod, Zeroable)] #[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Close {} pub struct Close {}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct MigrateTreasury {}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct MigrateMiner {}
instruction!(OreInstruction, Automate); instruction!(OreInstruction, Automate);
instruction!(OreInstruction, Boost); instruction!(OreInstruction, Boost);
instruction!(OreInstruction, Close); instruction!(OreInstruction, Close);
@@ -178,5 +168,3 @@ instruction!(OreInstruction, Deposit);
instruction!(OreInstruction, Withdraw); instruction!(OreInstruction, Withdraw);
instruction!(OreInstruction, ClaimYield); instruction!(OreInstruction, ClaimYield);
instruction!(OreInstruction, ClaimSeeker); instruction!(OreInstruction, ClaimSeeker);
instruction!(OreInstruction, MigrateTreasury);
instruction!(OreInstruction, MigrateMiner);

View File

@@ -184,35 +184,6 @@ pub fn deploy(
} }
} }
pub fn migrate_miner(signer: Pubkey, address: Pubkey) -> Instruction {
let config_address = config_pda().0;
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(config_address, false),
AccountMeta::new(address, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: MigrateMiner {}.to_bytes(),
}
}
pub fn migrate_treasury(signer: Pubkey) -> Instruction {
let config_address = config_pda().0;
// let treasury_address = treasury_pda().0;
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(config_address, false),
// AccountMeta::new(treasury_address, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: MigrateTreasury {}.to_bytes(),
}
}
const POOL_ADDRESS: Pubkey = pubkey!("GgaDTFbqdgjoZz3FP7zrtofGwnRS4E6MCzmmD5Ni1Mxj"); const POOL_ADDRESS: Pubkey = pubkey!("GgaDTFbqdgjoZz3FP7zrtofGwnRS4E6MCzmmD5Ni1Mxj");
const TOKEN_A_MINT: Pubkey = MINT_ADDRESS; // pubkey!("oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp"); const TOKEN_A_MINT: Pubkey = MINT_ADDRESS; // pubkey!("oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp");
const TOKEN_B_MINT: Pubkey = SOL_MINT; //pubkey!("So11111111111111111111111111111111111111112"); const TOKEN_B_MINT: Pubkey = SOL_MINT; //pubkey!("So11111111111111111111111111111111111111112");
@@ -429,19 +400,20 @@ pub fn claim_seeker(signer: Pubkey, mint: Pubkey) -> Instruction {
pub fn deposit(signer: Pubkey, amount: u64) -> Instruction { pub fn deposit(signer: Pubkey, amount: u64) -> Instruction {
let stake_address = stake_pda(signer).0; let stake_address = stake_pda(signer).0;
let stake_tokens_address = get_associated_token_address(&stake_address, &MINT_ADDRESS);
let sender_address = get_associated_token_address(&signer, &MINT_ADDRESS); let sender_address = get_associated_token_address(&signer, &MINT_ADDRESS);
let treasury_address = TREASURY_ADDRESS; let treasury_address = TREASURY_ADDRESS;
let treasury_tokens_address = treasury_tokens_address();
Instruction { Instruction {
program_id: crate::ID, program_id: crate::ID,
accounts: vec![ accounts: vec![
AccountMeta::new(signer, true), AccountMeta::new(signer, true),
AccountMeta::new(sender_address, false), AccountMeta::new(sender_address, false),
AccountMeta::new(stake_address, false), AccountMeta::new(stake_address, false),
AccountMeta::new(stake_tokens_address, false),
AccountMeta::new(treasury_address, false), AccountMeta::new(treasury_address, false),
AccountMeta::new(treasury_tokens_address, false),
AccountMeta::new_readonly(system_program::ID, false), AccountMeta::new_readonly(system_program::ID, false),
AccountMeta::new_readonly(spl_token::ID, false), AccountMeta::new_readonly(spl_token::ID, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
], ],
data: Deposit { data: Deposit {
amount: amount.to_le_bytes(), amount: amount.to_le_bytes(),
@@ -454,10 +426,10 @@ pub fn deposit(signer: Pubkey, amount: u64) -> Instruction {
pub fn withdraw(signer: Pubkey, amount: u64) -> Instruction { pub fn withdraw(signer: Pubkey, amount: u64) -> Instruction {
let stake_address = stake_pda(signer).0; let stake_address = stake_pda(signer).0;
let stake_tokens_address = get_associated_token_address(&stake_address, &MINT_ADDRESS);
let mint_address = MINT_ADDRESS; let mint_address = MINT_ADDRESS;
let recipient_address = get_associated_token_address(&signer, &MINT_ADDRESS); let recipient_address = get_associated_token_address(&signer, &MINT_ADDRESS);
let treasury_address = TREASURY_ADDRESS; let treasury_address = TREASURY_ADDRESS;
let treasury_tokens_address = treasury_tokens_address();
Instruction { Instruction {
program_id: crate::ID, program_id: crate::ID,
accounts: vec![ accounts: vec![
@@ -465,8 +437,8 @@ pub fn withdraw(signer: Pubkey, amount: u64) -> Instruction {
AccountMeta::new(mint_address, false), AccountMeta::new(mint_address, false),
AccountMeta::new(recipient_address, false), AccountMeta::new(recipient_address, false),
AccountMeta::new(stake_address, false), AccountMeta::new(stake_address, false),
AccountMeta::new(stake_tokens_address, false),
AccountMeta::new(treasury_address, false), AccountMeta::new(treasury_address, false),
AccountMeta::new(treasury_tokens_address, false),
AccountMeta::new_readonly(system_program::ID, false), AccountMeta::new_readonly(system_program::ID, false),
AccountMeta::new_readonly(spl_token::ID, false), AccountMeta::new_readonly(spl_token::ID, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false), AccountMeta::new_readonly(spl_associated_token_account::ID, false),

View File

@@ -117,6 +117,11 @@ async fn main() {
}; };
} }
async fn get_stakers(rpc: &RpcClient) -> Result<Vec<(Pubkey, Stake)>, anyhow::Error> {
let stakers = get_program_accounts(rpc, ore_api::ID, vec![]).await?;
Ok(stakers)
}
async fn participating_miners(rpc: &RpcClient) -> Result<(), anyhow::Error> { async fn participating_miners(rpc: &RpcClient) -> Result<(), anyhow::Error> {
let round_id = std::env::var("ID").expect("Missing ID env var"); let round_id = std::env::var("ID").expect("Missing ID env var");
let round_id = u64::from_str(&round_id).expect("Invalid ID"); let round_id = u64::from_str(&round_id).expect("Invalid ID");

View File

@@ -3,6 +3,8 @@ use solana_program::log::sol_log;
use spl_token::amount_to_ui_amount; use spl_token::amount_to_ui_amount;
use steel::*; use steel::*;
use crate::AUTHORIZED_ACCOUNTS;
/// Deposits ORE into the staking contract. /// Deposits ORE into the staking contract.
pub fn process_deposit(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { pub fn process_deposit(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
// Parse data. // Parse data.
@@ -11,22 +13,27 @@ pub fn process_deposit(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu
// Load accounts. // Load accounts.
let clock = Clock::get()?; let clock = Clock::get()?;
let [signer_info, sender_info, stake_info, treasury_info, treasury_tokens_info, system_program, token_program] = let [signer_info, mint_info, sender_info, stake_info, stake_tokens_info, treasury_info, system_program, token_program, associated_token_program] =
accounts accounts
else { else {
return Err(ProgramError::NotEnoughAccountKeys); return Err(ProgramError::NotEnoughAccountKeys);
}; };
signer_info.is_signer()?; signer_info.is_signer()?;
mint_info.has_address(&MINT_ADDRESS)?.as_mint()?;
let sender = sender_info let sender = sender_info
.is_writable()? .is_writable()?
.as_associated_token_account(&signer_info.key, &MINT_ADDRESS)?; .as_associated_token_account(&signer_info.key, &MINT_ADDRESS)?;
stake_info.is_writable()?; stake_info.is_writable()?;
let treasury = treasury_info.as_account_mut::<Treasury>(&ore_api::ID)?; let treasury = treasury_info.as_account_mut::<Treasury>(&ore_api::ID)?;
treasury_tokens_info
.is_writable()?
.as_associated_token_account(&treasury_info.key, &MINT_ADDRESS)?;
system_program.is_program(&system_program::ID)?; system_program.is_program(&system_program::ID)?;
token_program.is_program(&spl_token::ID)?; token_program.is_program(&spl_token::ID)?;
associated_token_program.is_program(&spl_associated_token_account::ID)?;
// Whitelist
assert!(
AUTHORIZED_ACCOUNTS.contains(&signer_info.key),
"Signer not whitelisted"
);
// Open stake account. // Open stake account.
let stake = if stake_info.data_is_empty() { let stake = if stake_info.data_is_empty() {
@@ -54,6 +61,21 @@ pub fn process_deposit(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu
.assert_mut(|s| s.authority == *signer_info.key)? .assert_mut(|s| s.authority == *signer_info.key)?
}; };
// Create stake tokens account.
if stake_tokens_info.data_is_empty() {
create_associated_token_account(
signer_info,
stake_info,
stake_tokens_info,
mint_info,
system_program,
token_program,
associated_token_program,
)?;
} else {
stake_tokens_info.as_associated_token_account(stake_info.key, mint_info.key)?;
}
// Only allow deposits from seekers. // Only allow deposits from seekers.
// assert!(stake.is_seeker == 1, "Only seekers can deposit stake"); // assert!(stake.is_seeker == 1, "Only seekers can deposit stake");
@@ -64,7 +86,7 @@ pub fn process_deposit(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu
transfer( transfer(
signer_info, signer_info,
sender_info, sender_info,
treasury_tokens_info, stake_tokens_info,
token_program, token_program,
amount, amount,
)?; )?;

View File

@@ -61,7 +61,7 @@ pub fn process_instruction(
// Staker // Staker
OreInstruction::Deposit => process_deposit(accounts, data)?, OreInstruction::Deposit => process_deposit(accounts, data)?,
OreInstruction::Withdraw => process_withdraw(accounts, data)?, OreInstruction::Withdraw => process_withdraw(accounts, data)?,
OreInstruction::ClaimYield => process_claim_yield(accounts, data)?, // OreInstruction::ClaimYield => process_claim_yield(accounts, data)?,
// Admin // Admin
OreInstruction::Bury => process_bury(accounts, data)?, OreInstruction::Bury => process_bury(accounts, data)?,

View File

@@ -0,0 +1,59 @@
use ore_api::prelude::*;
use steel::*;
/// Sets the admin.
pub fn process_migrate_staker(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
// Load accounts.
let [signer_info, config_info, mint_info, stake_info, stake_tokens_info, treasury_info, treasury_tokens_info, system_program, token_program, associated_token_program] =
accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};
signer_info.is_signer()?;
config_info.as_account::<Config>(&ore_api::ID)?.assert_err(
|c| c.admin == *signer_info.key,
OreError::NotAuthorized.into(),
)?;
mint_info.has_address(&MINT_ADDRESS)?.as_mint()?;
let stake = stake_info.as_account_mut::<Stake>(&ore_api::ID)?;
stake_tokens_info.is_empty()?.is_writable()?;
treasury_info.as_account_mut::<Treasury>(&ore_api::ID)?;
treasury_tokens_info.as_associated_token_account(&treasury_info.key, &MINT_ADDRESS)?;
system_program.is_program(&system_program::ID)?;
token_program.is_program(&spl_token::ID)?;
associated_token_program.is_program(&spl_associated_token_account::ID)?;
// Create stake tokens account.
if stake_tokens_info.data_is_empty() {
create_associated_token_account(
signer_info,
stake_info,
stake_tokens_info,
mint_info,
system_program,
token_program,
associated_token_program,
)?;
}
let stake_tokens =
stake_tokens_info.as_associated_token_account(stake_info.key, mint_info.key)?;
// Move tokens from treasury to stake tokens.
if stake_tokens.amount() == 0 {
transfer_signed(
treasury_info,
treasury_tokens_info,
stake_tokens_info,
token_program,
stake.balance,
&[TREASURY],
)?;
}
// Safety check.
let stake_tokens =
stake_tokens_info.as_associated_token_account(stake_info.key, mint_info.key)?;
assert_eq!(stake_tokens.amount(), stake.balance);
Ok(())
}

View File

@@ -3,6 +3,8 @@ use solana_program::log::sol_log;
use spl_token::amount_to_ui_amount; use spl_token::amount_to_ui_amount;
use steel::*; use steel::*;
use crate::AUTHORIZED_ACCOUNTS;
/// Withdraws ORE from the staking contract. /// Withdraws ORE from the staking contract.
pub fn process_withdraw(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { pub fn process_withdraw(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
// Parse data. // Parse data.
@@ -11,7 +13,7 @@ pub fn process_withdraw(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramRes
// Load accounts. // Load accounts.
let clock = Clock::get()?; let clock = Clock::get()?;
let [signer_info, mint_info, recipient_info, stake_info, treasury_info, treasury_tokens_info, system_program, token_program, associated_token_program] = let [signer_info, mint_info, recipient_info, stake_info, stake_tokens_info, treasury_info, system_program, token_program, associated_token_program] =
accounts accounts
else { else {
return Err(ProgramError::NotEnoughAccountKeys); return Err(ProgramError::NotEnoughAccountKeys);
@@ -24,14 +26,17 @@ pub fn process_withdraw(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramRes
let stake = stake_info let stake = stake_info
.as_account_mut::<Stake>(&ore_api::ID)? .as_account_mut::<Stake>(&ore_api::ID)?
.assert_mut(|s| s.authority == *signer_info.key)?; .assert_mut(|s| s.authority == *signer_info.key)?;
stake_tokens_info.as_associated_token_account(stake_info.key, mint_info.key)?;
let treasury = treasury_info.as_account_mut::<Treasury>(&ore_api::ID)?; let treasury = treasury_info.as_account_mut::<Treasury>(&ore_api::ID)?;
treasury_tokens_info
.is_writable()?
.as_associated_token_account(&treasury_info.key, &mint_info.key)?;
system_program.is_program(&system_program::ID)?; system_program.is_program(&system_program::ID)?;
token_program.is_program(&spl_token::ID)?; token_program.is_program(&spl_token::ID)?;
associated_token_program.is_program(&spl_associated_token_account::ID)?; associated_token_program.is_program(&spl_associated_token_account::ID)?;
assert!(
AUTHORIZED_ACCOUNTS.contains(&signer_info.key),
"Signer not whitelisted"
);
// Open recipient token account. // Open recipient token account.
if recipient_info.data_is_empty() { if recipient_info.data_is_empty() {
create_associated_token_account( create_associated_token_account(
@@ -50,12 +55,12 @@ pub fn process_withdraw(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramRes
// Transfer ORE to recipient. // Transfer ORE to recipient.
transfer_signed( transfer_signed(
treasury_info, stake_info,
treasury_tokens_info, stake_tokens_info,
recipient_info, recipient_info,
token_program, token_program,
amount, amount,
&[TREASURY], &[STAKE, &stake.authority.to_bytes()],
)?; )?;
// Log withdraw. // Log withdraw.