From 7814e28847880ddd8a153c148d8042c8e0ed5400 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Wed, 25 Sep 2024 06:45:37 +0000 Subject: [PATCH 01/46] migrate to steel --- Cargo.lock | 16 ++++++++++++++-- Cargo.toml | 2 +- api/Cargo.toml | 2 +- api/src/error.rs | 2 +- api/src/event.rs | 2 +- api/src/instruction.rs | 2 +- api/src/loaders.rs | 2 +- api/src/state/bus.rs | 2 +- api/src/state/config.rs | 2 +- api/src/state/proof.rs | 2 +- api/src/state/treasury.rs | 2 +- program/Cargo.toml | 2 +- program/src/claim.rs | 2 +- program/src/close.rs | 2 +- program/src/initialize.rs | 2 +- program/src/mine.rs | 2 +- program/src/open.rs | 2 +- program/src/reset.rs | 2 +- program/src/stake.rs | 2 +- program/src/update.rs | 2 +- program/src/upgrade.rs | 2 +- 21 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de7049f..d6efac7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1294,11 +1294,11 @@ dependencies = [ "drillx", "mpl-token-metadata", "num_enum", - "ore-utils", "solana-program", "spl-associated-token-account", "spl-token", "static_assertions", + "steel", "thiserror", ] @@ -1309,11 +1309,11 @@ dependencies = [ "drillx", "mpl-token-metadata", "ore-api", - "ore-utils", "rand 0.8.5", "solana-program", "spl-associated-token-account", "spl-token", + "steel", ] [[package]] @@ -2219,6 +2219,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "steel" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b09eae425248a8afcef3cf3300dfa548791194fa9fe519dadd5c57d7964dbc" +dependencies = [ + "bytemuck", + "solana-program", + "spl-associated-token-account", + "spl-token", +] + [[package]] name = "strsim" version = "0.11.1" diff --git a/Cargo.toml b/Cargo.toml index 6d4b8d8..de4d323 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,11 +20,11 @@ drillx = { version = "2.0.0", features = ["solana"] } mpl-token-metadata = "4.1.2" num_enum = "0.7.2" ore-api = { path = "api", version = "2.1.9" } -ore-utils = { path = "utils", features = ["spl"], version = "2.1.9" } solana-program = "^1.18" spl-token = { version = "^4", features = ["no-entrypoint"] } spl-associated-token-account = { version = "^2.3", features = [ "no-entrypoint" ] } static_assertions = "1.1.0" +steel = { features = ["spl"], version = "0.1.0" } thiserror = "1.0.57" diff --git a/api/Cargo.toml b/api/Cargo.toml index aad2498..d11cc5a 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -16,9 +16,9 @@ const-crypto.workspace = true drillx.workspace = true mpl-token-metadata.workspace = true num_enum.workspace = true -ore-utils.workspace = true solana-program.workspace = true spl-token.workspace = true spl-associated-token-account.workspace = true static_assertions.workspace = true +steel.workspace = true thiserror.workspace = true diff --git a/api/src/error.rs b/api/src/error.rs index b0653ba..408681d 100644 --- a/api/src/error.rs +++ b/api/src/error.rs @@ -1,5 +1,5 @@ use num_enum::IntoPrimitive; -use ore_utils::*; +use steel::*; use thiserror::Error; #[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] diff --git a/api/src/event.rs b/api/src/event.rs index 9f41f25..b7068b3 100644 --- a/api/src/event.rs +++ b/api/src/event.rs @@ -1,5 +1,5 @@ use bytemuck::{Pod, Zeroable}; -use ore_utils::*; +use steel::*; #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 7010646..923b2c5 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; use num_enum::TryFromPrimitive; -use ore_utils::*; +use steel::*; #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] diff --git a/api/src/loaders.rs b/api/src/loaders.rs index 881ca5d..925335d 100644 --- a/api/src/loaders.rs +++ b/api/src/loaders.rs @@ -1,5 +1,5 @@ -use ore_utils::*; use solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}; +use steel::*; use crate::{ consts::*, diff --git a/api/src/state/bus.rs b/api/src/state/bus.rs index 0d07296..2c12776 100644 --- a/api/src/state/bus.rs +++ b/api/src/state/bus.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; -use ore_utils::*; use solana_program::pubkey::Pubkey; +use steel::*; use crate::consts::BUS; diff --git a/api/src/state/config.rs b/api/src/state/config.rs index 35dded5..e35216c 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; -use ore_utils::*; use solana_program::pubkey::Pubkey; +use steel::*; use crate::consts::CONFIG; diff --git a/api/src/state/proof.rs b/api/src/state/proof.rs index ba68660..33c0f4a 100644 --- a/api/src/state/proof.rs +++ b/api/src/state/proof.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; -use ore_utils::*; use solana_program::pubkey::Pubkey; +use steel::*; use crate::consts::PROOF; diff --git a/api/src/state/treasury.rs b/api/src/state/treasury.rs index 20c34fc..289fc35 100644 --- a/api/src/state/treasury.rs +++ b/api/src/state/treasury.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; -use ore_utils::*; use solana_program::pubkey::Pubkey; +use steel::*; use crate::consts::TREASURY; diff --git a/program/Cargo.toml b/program/Cargo.toml index 70af79c..1bf4718 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -21,10 +21,10 @@ default = [] drillx.workspace = true mpl-token-metadata.workspace = true ore-api.workspace = true -ore-utils.workspace = true solana-program.workspace = true spl-token.workspace = true spl-associated-token-account.workspace = true +steel.workspace = true [dev-dependencies] rand = "0.8.5" diff --git a/program/src/claim.rs b/program/src/claim.rs index aedf620..7cf33cc 100644 --- a/program/src/claim.rs +++ b/program/src/claim.rs @@ -1,8 +1,8 @@ use ore_api::{consts::*, error::OreError, instruction::*, loaders::*, state::Proof}; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, }; +use steel::*; /// Claim distributes claimable ORE from the treasury to a miner. pub fn process_claim(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { diff --git a/program/src/close.rs b/program/src/close.rs index c12150c..4529e39 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -1,9 +1,9 @@ use ore_api::{loaders::*, state::Proof}; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, system_program, }; +use steel::*; /// Close closes a proof account and returns the rent to the owner. pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 6759876..b4255d0 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -5,12 +5,12 @@ use ore_api::{ instruction::*, state::{Bus, Config, Treasury}, }; -use ore_utils::*; use solana_program::{ self, account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_pack::Pack, system_program, sysvar, }; use spl_token::state::Mint; +use steel::*; /// Initialize sets up the ORE program to begin mining. pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { diff --git a/program/src/mine.rs b/program/src/mine.rs index 9efd3dc..40aa1ee 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -9,7 +9,6 @@ use ore_api::{ loaders::*, state::{Bus, Config, Proof}, }; -use ore_utils::*; use solana_program::program::set_return_data; #[allow(deprecated)] use solana_program::{ @@ -24,6 +23,7 @@ use solana_program::{ slot_hashes::SlotHash, sysvar::{self, Sysvar}, }; +use steel::*; /// Mine validates hashes and increments a miner's collectable balance. pub fn process_mine(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { diff --git a/program/src/open.rs b/program/src/open.rs index 4ded87c..f914af8 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -1,7 +1,6 @@ use std::mem::size_of; use ore_api::{consts::*, instruction::Open, state::Proof}; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, clock::Clock, @@ -12,6 +11,7 @@ use solana_program::{ system_program, sysvar::{self, Sysvar}, }; +use steel::*; /// Open creates a new proof account to track a miner's state. pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { diff --git a/program/src/reset.rs b/program/src/reset.rs index eda9489..a3abcfa 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -4,12 +4,12 @@ use ore_api::{ loaders::*, state::{Bus, Config}, }; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, program_error::ProgramError, program_pack::Pack, sysvar::Sysvar, }; use spl_token::state::Mint; +use steel::*; /// Reset tops up the bus balances, updates the base reward rate, and sets up the ORE program for the next epoch. pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { diff --git a/program/src/stake.rs b/program/src/stake.rs index e64f5b3..08f33b5 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -1,9 +1,9 @@ use ore_api::{consts::*, instruction::Stake, loaders::*, state::Proof}; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, program_error::ProgramError, sysvar::Sysvar, }; +use steel::*; /// Stake deposits ORE into a proof account to earn multiplier. pub fn process_stake(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { diff --git a/program/src/update.rs b/program/src/update.rs index c5a21e7..6ffdf3b 100644 --- a/program/src/update.rs +++ b/program/src/update.rs @@ -1,8 +1,8 @@ use ore_api::{loaders::*, state::Proof}; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, }; +use steel::*; /// Update changes the miner authority on a proof account. pub fn process_update(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index a167872..7530117 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -1,10 +1,10 @@ use ore_api::{consts::*, error::OreError, instruction::Stake}; -use ore_utils::*; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_pack::Pack, }; use spl_token::state::Mint; +use steel::*; /// Upgrade allows a user to migrate a v1 token to a v2 token at a 1:1 exchange rate. pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { From 11d710ab9f89474b878c59f0ffb1dfd29b72c4d0 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Wed, 25 Sep 2024 06:46:34 +0000 Subject: [PATCH 02/46] remove ore-utils --- Cargo.lock | 10 -- Cargo.toml | 2 +- utils/Cargo.toml | 20 ---- utils/src/cpi.rs | 214 ------------------------------------- utils/src/lib.rs | 8 -- utils/src/loaders.rs | 249 ------------------------------------------- utils/src/macros.rs | 120 --------------------- utils/src/traits.rs | 10 -- 8 files changed, 1 insertion(+), 632 deletions(-) delete mode 100644 utils/Cargo.toml delete mode 100644 utils/src/cpi.rs delete mode 100644 utils/src/lib.rs delete mode 100644 utils/src/loaders.rs delete mode 100644 utils/src/macros.rs delete mode 100644 utils/src/traits.rs diff --git a/Cargo.lock b/Cargo.lock index d6efac7..3ffc70d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1316,16 +1316,6 @@ dependencies = [ "steel", ] -[[package]] -name = "ore-utils" -version = "2.1.9" -dependencies = [ - "bytemuck", - "solana-program", - "spl-associated-token-account", - "spl-token", -] - [[package]] name = "parking_lot" version = "0.12.3" diff --git a/Cargo.toml b/Cargo.toml index de4d323..3bb3b18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["api", "program", "utils"] +members = ["api", "program"] [workspace.package] version = "2.1.9" diff --git a/utils/Cargo.toml b/utils/Cargo.toml deleted file mode 100644 index 2af4092..0000000 --- a/utils/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "ore-utils" -description = "Utils for building ORE programs" -version.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -documentation.workspace = true -repository.workspace = true -keywords.workspace = true - -[features] -deafult = [] -spl = ["spl-token", "spl-associated-token-account"] - -[dependencies] -bytemuck.workspace = true -solana-program.workspace = true -spl-token = { workspace = true, optional = true } -spl-associated-token-account = { workspace = true, optional = true } diff --git a/utils/src/cpi.rs b/utils/src/cpi.rs deleted file mode 100644 index bce2c8e..0000000 --- a/utils/src/cpi.rs +++ /dev/null @@ -1,214 +0,0 @@ -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey, rent::Rent, - sysvar::Sysvar, -}; - -/// Creates a new pda. -#[inline(always)] -pub fn create_pda<'a, 'info>( - target_account: &'a AccountInfo<'info>, - owner: &Pubkey, - space: usize, - pda_seeds: &[&[u8]], - system_program: &'a AccountInfo<'info>, - payer: &'a AccountInfo<'info>, -) -> ProgramResult { - let rent = Rent::get()?; - if target_account.lamports().eq(&0) { - // If balance is zero, create account - solana_program::program::invoke_signed( - &solana_program::system_instruction::create_account( - payer.key, - target_account.key, - rent.minimum_balance(space), - space as u64, - owner, - ), - &[ - payer.clone(), - target_account.clone(), - system_program.clone(), - ], - &[pda_seeds], - )?; - } else { - // Otherwise, if balance is nonzero: - - // 1) transfer sufficient lamports for rent exemption - let rent_exempt_balance = rent - .minimum_balance(space) - .saturating_sub(target_account.lamports()); - if rent_exempt_balance.gt(&0) { - solana_program::program::invoke( - &solana_program::system_instruction::transfer( - payer.key, - target_account.key, - rent_exempt_balance, - ), - &[ - payer.clone(), - target_account.clone(), - system_program.clone(), - ], - )?; - } - - // 2) allocate space for the account - solana_program::program::invoke_signed( - &solana_program::system_instruction::allocate(target_account.key, space as u64), - &[target_account.clone(), system_program.clone()], - &[pda_seeds], - )?; - - // 3) assign our program as the owner - solana_program::program::invoke_signed( - &solana_program::system_instruction::assign(target_account.key, owner), - &[target_account.clone(), system_program.clone()], - &[pda_seeds], - )?; - } - - Ok(()) -} - -#[cfg(feature = "spl")] -#[inline(always)] -pub fn create_ata<'info>( - funder_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - system_program: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - associated_token_program: &AccountInfo<'info>, -) -> ProgramResult { - solana_program::program::invoke( - &spl_associated_token_account::instruction::create_associated_token_account( - funder_info.key, - owner_info.key, - mint_info.key, - &spl_token::id(), - ), - &[ - funder_info.clone(), - token_account_info.clone(), - owner_info.clone(), - mint_info.clone(), - system_program.clone(), - token_program.clone(), - associated_token_program.clone(), - ], - ) -} - -#[cfg(feature = "spl")] -#[inline(always)] -pub fn transfer<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token::instruction::transfer( - &spl_token::id(), - from_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - from_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - ) -} - -#[cfg(feature = "spl")] -#[inline(always)] -pub fn transfer_signed<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - signer_seeds: &[&[&[u8]]], -) -> ProgramResult { - solana_program::program::invoke_signed( - &spl_token::instruction::transfer( - &spl_token::id(), - from_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - from_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - signer_seeds, - ) -} - -#[cfg(feature = "spl")] -#[inline(always)] -pub fn mint_to_signed<'info>( - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - signer_seeds: &[&[&[u8]]], -) -> ProgramResult { - solana_program::program::invoke_signed( - &spl_token::instruction::mint_to( - &spl_token::id(), - mint_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - mint_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - signer_seeds, - ) -} - -#[cfg(feature = "spl")] -#[inline(always)] -pub fn burn<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token::instruction::burn( - &spl_token::id(), - token_account_info.key, - mint_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - authority_info.clone(), - ], - ) -} diff --git a/utils/src/lib.rs b/utils/src/lib.rs deleted file mode 100644 index d4c963a..0000000 --- a/utils/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod cpi; -mod loaders; -pub mod macros; -mod traits; - -pub use cpi::*; -pub use loaders::*; -pub use traits::*; diff --git a/utils/src/loaders.rs b/utils/src/loaders.rs deleted file mode 100644 index 72681fe..0000000 --- a/utils/src/loaders.rs +++ /dev/null @@ -1,249 +0,0 @@ -#[cfg(feature = "spl")] -use solana_program::program_pack::Pack; -use solana_program::{ - account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, system_program, sysvar, -}; -#[cfg(feature = "spl")] -use spl_token::state::Mint; - -/// Errors if: -/// - Account is not a signer. -pub fn load_signer(info: &AccountInfo<'_>) -> Result<(), ProgramError> { - if !info.is_signer { - return Err(ProgramError::MissingRequiredSignature); - } - - Ok(()) -} - -/// Errors if: -/// - Address does not match PDA derived from provided seeds. -/// - Cannot load as an uninitialized account. -pub fn load_uninitialized_pda( - info: &AccountInfo<'_>, - seeds: &[&[u8]], - bump: u8, - program_id: &Pubkey, -) -> Result<(), ProgramError> { - let pda = Pubkey::find_program_address(seeds, program_id); - - if info.key.ne(&pda.0) { - return Err(ProgramError::InvalidSeeds); - } - - if bump.ne(&pda.1) { - return Err(ProgramError::InvalidSeeds); - } - - load_system_account(info, true) -} - -/// Errors if: -/// - Owner is not the system program. -/// - Data is not empty. -/// - Account is not writable. -pub fn load_system_account(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&system_program::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if !info.data_is_empty() { - return Err(ProgramError::AccountAlreadyInitialized); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not the sysvar address. -/// - Account cannot load with the expected address. -pub fn load_sysvar(info: &AccountInfo<'_>, key: Pubkey) -> Result<(), ProgramError> { - if info.owner.ne(&sysvar::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - load_account(info, key, false) -} - -/// Errors if: -/// - Address does not match the expected value. -/// - Expected to be writable, but is not. -pub fn load_account( - info: &AccountInfo<'_>, - key: Pubkey, - is_writable: bool, -) -> Result<(), ProgramError> { - if info.key.ne(&key) { - return Err(ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Address does not match the expected value. -/// - Account is not executable. -pub fn load_program(info: &AccountInfo<'_>, key: Pubkey) -> Result<(), ProgramError> { - if info.key.ne(&key) { - return Err(ProgramError::IncorrectProgramId); - } - - if !info.executable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Account is not writable. -pub fn load_any(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not SPL token program. -/// - Address does not match the expected mint address. -/// - Data is empty. -/// - Data cannot deserialize into a mint account. -/// - Expected to be writable, but is not. -#[cfg(feature = "spl")] -pub fn load_mint( - info: &AccountInfo<'_>, - address: Pubkey, - is_writable: bool, -) -> Result<(), ProgramError> { - if info.owner.ne(&spl_token::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.key.ne(&address) { - return Err(ProgramError::InvalidSeeds); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - Mint::unpack(&info.data.borrow())?; - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not SPL token program. -/// - Data is empty. -/// - Data cannot deserialize into a mint account. -/// - Expected to be writable, but is not. -#[cfg(feature = "spl")] -pub fn load_any_mint(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&spl_token::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - Mint::unpack(&info.data.borrow())?; - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not SPL token program. -/// - Data is empty. -/// - Data cannot deserialize into a token account. -/// - Token account owner does not match the expected owner address. -/// - Token account mint does not match the expected mint address. -/// - Expected to be writable, but is not. -#[cfg(feature = "spl")] -pub fn load_token_account( - info: &AccountInfo<'_>, - owner: Option<&Pubkey>, - mint: &Pubkey, - is_writable: bool, -) -> Result<(), ProgramError> { - if info.owner.ne(&spl_token::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - let account_data = info.data.borrow(); - let account = spl_token::state::Account::unpack(&account_data)?; - - if account.mint.ne(&mint) { - return Err(ProgramError::InvalidAccountData); - } - - if let Some(owner) = owner { - if account.owner.ne(owner) { - return Err(ProgramError::InvalidAccountData); - } - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not SPL token program. -/// - Data is empty. -/// - Data cannot deserialize into a token account. -/// - Address does not match the expected associated token address. -/// - Expected to be writable, but is not. -#[cfg(feature = "spl")] -pub fn load_associated_token_account( - info: &AccountInfo<'_>, - owner: &Pubkey, - mint: &Pubkey, - is_writable: bool, -) -> Result<(), ProgramError> { - if info.owner.ne(&spl_token::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - let account_data = info.data.borrow(); - let _ = spl_token::state::Account::unpack(&account_data)?; - - let address = spl_associated_token_account::get_associated_token_address(owner, mint); - if info.key.ne(&address) { - return Err(ProgramError::InvalidSeeds); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} diff --git a/utils/src/macros.rs b/utils/src/macros.rs deleted file mode 100644 index 1bda272..0000000 --- a/utils/src/macros.rs +++ /dev/null @@ -1,120 +0,0 @@ -#[macro_export] -macro_rules! impl_to_bytes { - ($struct_name:ident) => { - impl $struct_name { - pub fn to_bytes(&self) -> &[u8] { - bytemuck::bytes_of(self) - } - } - }; -} - -#[macro_export] -macro_rules! impl_from_bytes { - ($struct_name:ident) => { - impl $struct_name { - pub fn from_bytes(data: &[u8]) -> &Self { - bytemuck::from_bytes::(data) - } - } - }; -} - -#[macro_export] -macro_rules! impl_account_from_bytes { - ($struct_name:ident) => { - impl $crate::AccountDeserialize for $struct_name { - fn try_from_bytes( - data: &[u8], - ) -> Result<&Self, solana_program::program_error::ProgramError> { - if Self::discriminator().ne(&data[0]) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); - } - bytemuck::try_from_bytes::(&data[8..]).or(Err( - solana_program::program_error::ProgramError::InvalidAccountData, - )) - } - fn try_from_bytes_mut( - data: &mut [u8], - ) -> Result<&mut Self, solana_program::program_error::ProgramError> { - if Self::discriminator().ne(&data[0]) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); - } - bytemuck::try_from_bytes_mut::(&mut data[8..]).or(Err( - solana_program::program_error::ProgramError::InvalidAccountData, - )) - } - } - }; -} - -#[macro_export] -macro_rules! impl_instruction_from_bytes { - ($struct_name:ident) => { - impl $struct_name { - pub fn try_from_bytes( - data: &[u8], - ) -> Result<&Self, solana_program::program_error::ProgramError> { - bytemuck::try_from_bytes::(data).or(Err( - solana_program::program_error::ProgramError::InvalidInstructionData, - )) - } - } - }; -} - -#[macro_export] -macro_rules! account { - ($discriminator_name:ident, $struct_name:ident) => { - $crate::impl_to_bytes!($struct_name); - $crate::impl_account_from_bytes!($struct_name); - - impl $crate::Discriminator for $struct_name { - fn discriminator() -> u8 { - $discriminator_name::$struct_name.into() - } - } - }; -} - -#[macro_export] -macro_rules! error { - ($struct_name:ident) => { - impl From<$struct_name> for solana_program::program_error::ProgramError { - fn from(e: $struct_name) -> Self { - solana_program::program_error::ProgramError::Custom(e as u32) - } - } - }; -} - -#[macro_export] -macro_rules! event { - ($struct_name:ident) => { - $crate::impl_to_bytes!($struct_name); - $crate::impl_from_bytes!($struct_name); - }; -} - -#[macro_export] -macro_rules! instruction { - ($discriminator_name:ident, $struct_name:ident) => { - $crate::impl_instruction_from_bytes!($struct_name); - - impl $crate::Discriminator for $struct_name { - fn discriminator() -> u8 { - $discriminator_name::$struct_name as u8 - } - } - - impl $struct_name { - pub fn to_bytes(&self) -> Vec { - [ - [$discriminator_name::$struct_name as u8].to_vec(), - bytemuck::bytes_of(self).to_vec(), - ] - .concat() - } - } - }; -} diff --git a/utils/src/traits.rs b/utils/src/traits.rs deleted file mode 100644 index 755a5fe..0000000 --- a/utils/src/traits.rs +++ /dev/null @@ -1,10 +0,0 @@ -use solana_program::program_error::ProgramError; - -pub trait AccountDeserialize { - fn try_from_bytes(data: &[u8]) -> Result<&Self, ProgramError>; - fn try_from_bytes_mut(data: &mut [u8]) -> Result<&mut Self, ProgramError>; -} - -pub trait Discriminator { - fn discriminator() -> u8; -} From b280ebf743afb3440835ce0c24ce2cfb977b0ab7 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Wed, 25 Sep 2024 06:52:17 +0000 Subject: [PATCH 03/46] rename audits to security --- audits/fuzzland.pdf => security/fuzzland-audit.pdf | Bin audits/ottersec.pdf => security/ottersec-audit.pdf | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename audits/fuzzland.pdf => security/fuzzland-audit.pdf (100%) rename audits/ottersec.pdf => security/ottersec-audit.pdf (100%) diff --git a/audits/fuzzland.pdf b/security/fuzzland-audit.pdf similarity index 100% rename from audits/fuzzland.pdf rename to security/fuzzland-audit.pdf diff --git a/audits/ottersec.pdf b/security/ottersec-audit.pdf similarity index 100% rename from audits/ottersec.pdf rename to security/ottersec-audit.pdf From 609349a5aa297e5f2187fd3a251dda45de3a2e1b Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Thu, 26 Sep 2024 03:50:36 +0000 Subject: [PATCH 04/46] upgrade to new version of steel --- Cargo.lock | 6 ++-- Cargo.toml | 2 ++ api/src/loaders.rs | 39 ++++++++-------------- api/src/state/bus.rs | 23 +++++++++++-- api/src/state/config.rs | 2 -- program/src/claim.rs | 6 ++-- program/src/close.rs | 10 +++--- program/src/initialize.rs | 70 +++++++++++++++------------------------ program/src/mine.rs | 12 +++---- program/src/open.rs | 27 +++++++-------- program/src/reset.rs | 10 +++--- program/src/stake.rs | 13 ++++---- program/src/update.rs | 4 +-- program/src/upgrade.rs | 21 +++++++----- 14 files changed, 120 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ffc70d..8758d26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,14 +2211,14 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "steel" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b09eae425248a8afcef3cf3300dfa548791194fa9fe519dadd5c57d7964dbc" +version = "0.1.5" dependencies = [ "bytemuck", + "num_enum", "solana-program", "spl-associated-token-account", "spl-token", + "thiserror", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3bb3b18..134951f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,5 @@ steel = { features = ["spl"], version = "0.1.0" } thiserror = "1.0.57" +[patch.crates-io] +steel = { path = "../steel/lib" } diff --git a/api/src/loaders.rs b/api/src/loaders.rs index 925335d..77fa46a 100644 --- a/api/src/loaders.rs +++ b/api/src/loaders.rs @@ -192,34 +192,23 @@ pub fn load_any_proof(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), P Ok(()) } -/// Errors if: -/// - Owner is not Ore program. -/// - Address does not match the expected address. -/// - Data is empty. -/// - Data cannot deserialize into a treasury account. -/// - Expected to be writable, but is not. -pub fn load_treasury(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); +pub trait OreAccountInfoValidation { + fn is_config(&self) -> Result<&Self, ProgramError>; + fn is_treasury(&self) -> Result<&Self, ProgramError>; +} + +impl<'a> OreAccountInfoValidation for AccountInfo<'a> { + fn is_config(&self) -> Result<&Self, ProgramError> { + self.has_address(&CONFIG_ADDRESS)? + .has_owner(&crate::ID)? + .is_type::() } - if info.key.ne(&TREASURY_ADDRESS) { - return Err(ProgramError::InvalidSeeds); + fn is_treasury(&self) -> Result<&Self, ProgramError> { + self.has_address(&TREASURY_ADDRESS)? + .has_owner(&crate::ID)? + .is_type::() } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - if info.data.borrow()[0].ne(&(Treasury::discriminator() as u8)) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) } /// Errors if: diff --git a/api/src/state/bus.rs b/api/src/state/bus.rs index 2c12776..f92f715 100644 --- a/api/src/state/bus.rs +++ b/api/src/state/bus.rs @@ -1,5 +1,3 @@ -use bytemuck::{Pod, Zeroable}; -use solana_program::pubkey::Pubkey; use steel::*; use crate::consts::BUS; @@ -30,4 +28,25 @@ pub fn bus_pda(id: u8) -> (Pubkey, u8) { Pubkey::find_program_address(&[BUS, &[id]], &crate::id()) } +impl<'a> From<&'a [u8]> for &'a Bus { + fn from(value: &'a [u8]) -> &'a Bus { + Bus::try_from_bytes(value).unwrap() + } +} + +impl<'a> From<*const u8> for &'a Bus { + fn from(value: *const u8) -> &'a Bus { + unsafe { + if Bus::discriminator().ne(&value.add(0).read()) { + panic!(""); + } + bytemuck::try_from_bytes::(std::slice::from_raw_parts( + value.add(8), + std::mem::size_of::(), + )) + .expect("") + } + } +} + account!(OreAccount, Bus); diff --git a/api/src/state/config.rs b/api/src/state/config.rs index e35216c..64bbf8c 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -1,5 +1,3 @@ -use bytemuck::{Pod, Zeroable}; -use solana_program::pubkey::Pubkey; use steel::*; use crate::consts::CONFIG; diff --git a/program/src/claim.rs b/program/src/claim.rs index 7cf33cc..9f564b8 100644 --- a/program/src/claim.rs +++ b/program/src/claim.rs @@ -16,12 +16,12 @@ pub fn process_claim(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; + signer.is_signer()?; load_token_account(beneficiary_info, None, &MINT_ADDRESS, true)?; load_proof(proof_info, signer.key, true)?; - load_treasury(treasury_info, false)?; + treasury_info.is_treasury()?; load_treasury_tokens(treasury_tokens_info, true)?; - load_program(token_program, spl_token::id())?; + token_program.has_address(&spl_token::ID)?; // Update miner balance. let mut proof_data = proof_info.data.borrow_mut(); diff --git a/program/src/close.rs b/program/src/close.rs index 4529e39..4201b5f 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -8,12 +8,12 @@ use steel::*; /// Close closes a proof account and returns the rent to the owner. pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { // Load accounts. - let [signer, proof_info, system_program] = accounts else { + let [signer_info, proof_info, system_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_proof(proof_info, signer.key, true)?; - load_program(system_program, system_program::id())?; + signer_info.is_signer()?; + load_proof(proof_info, signer_info.key, true)?; + system_program.is_program(&system_program::ID)?; // Validate balance is zero. let proof_data = proof_info.data.borrow(); @@ -27,7 +27,7 @@ pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul proof_info.realloc(0, true)?; // Send remaining lamports to signer. - **signer.lamports.borrow_mut() += proof_info.lamports(); + **signer_info.lamports.borrow_mut() += proof_info.lamports(); **proof_info.lamports.borrow_mut() = 0; Ok(()) diff --git a/program/src/initialize.rs b/program/src/initialize.rs index b4255d0..16bd2d0 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -18,23 +18,22 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR let args = Initialize::try_from_bytes(data)?; // Load accounts. - let [signer, bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info, bus_7_info, config_info, metadata_info, mint_info, treasury_info, treasury_tokens_info, system_program, token_program, associated_token_program, metadata_program, rent_sysvar] = + let [signer_info, bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info, bus_7_info, config_info, metadata_info, mint_info, treasury_info, treasury_tokens_info, system_program, token_program, associated_token_program, metadata_program, rent_sysvar] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_uninitialized_pda(bus_0_info, &[BUS, &[0]], args.bus_0_bump, &ore_api::id())?; - load_uninitialized_pda(bus_1_info, &[BUS, &[1]], args.bus_1_bump, &ore_api::id())?; - load_uninitialized_pda(bus_2_info, &[BUS, &[2]], args.bus_2_bump, &ore_api::id())?; - load_uninitialized_pda(bus_3_info, &[BUS, &[3]], args.bus_3_bump, &ore_api::id())?; - load_uninitialized_pda(bus_4_info, &[BUS, &[4]], args.bus_4_bump, &ore_api::id())?; - load_uninitialized_pda(bus_5_info, &[BUS, &[5]], args.bus_5_bump, &ore_api::id())?; - load_uninitialized_pda(bus_6_info, &[BUS, &[6]], args.bus_6_bump, &ore_api::id())?; - load_uninitialized_pda(bus_7_info, &[BUS, &[7]], args.bus_7_bump, &ore_api::id())?; - load_uninitialized_pda(config_info, &[CONFIG], args.config_bump, &ore_api::id())?; - load_uninitialized_pda( - metadata_info, + signer_info.is_signer()?.has_address(&INITIALIZER_ADDRESS)?; + bus_0_info.is_empty_pda(&[BUS, &[0]], args.bus_0_bump, &ore_api::ID)?; + bus_1_info.is_empty_pda(&[BUS, &[1]], args.bus_1_bump, &ore_api::ID)?; + bus_2_info.is_empty_pda(&[BUS, &[2]], args.bus_2_bump, &ore_api::ID)?; + bus_3_info.is_empty_pda(&[BUS, &[3]], args.bus_3_bump, &ore_api::ID)?; + bus_4_info.is_empty_pda(&[BUS, &[4]], args.bus_4_bump, &ore_api::ID)?; + bus_5_info.is_empty_pda(&[BUS, &[5]], args.bus_5_bump, &ore_api::ID)?; + bus_6_info.is_empty_pda(&[BUS, &[6]], args.bus_6_bump, &ore_api::ID)?; + bus_7_info.is_empty_pda(&[BUS, &[7]], args.bus_7_bump, &ore_api::ID)?; + config_info.is_empty_pda(&[CONFIG], args.config_bump, &ore_api::id())?; + metadata_info.is_empty_pda( &[ METADATA, mpl_token_metadata::ID.as_ref(), @@ -43,29 +42,14 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR args.metadata_bump, &mpl_token_metadata::ID, )?; - load_uninitialized_pda( - mint_info, - &[MINT, MINT_NOISE.as_slice()], - args.mint_bump, - &ore_api::id(), - )?; - load_uninitialized_pda( - treasury_info, - &[TREASURY], - args.treasury_bump, - &ore_api::id(), - )?; - load_system_account(treasury_tokens_info, true)?; - load_program(system_program, system_program::id())?; - load_program(token_program, spl_token::id())?; - load_program(associated_token_program, spl_associated_token_account::id())?; - load_program(metadata_program, mpl_token_metadata::ID)?; - load_sysvar(rent_sysvar, sysvar::rent::id())?; - - // Check signer. - if signer.key.ne(&INITIALIZER_ADDRESS) { - return Err(ProgramError::MissingRequiredSignature); - } + mint_info.is_empty_pda(&[MINT, MINT_NOISE.as_slice()], args.mint_bump, &ore_api::ID)?; + treasury_info.is_empty_pda(&[TREASURY], args.treasury_bump, &ore_api::ID)?; + treasury_tokens_info.is_empty()?; + system_program.is_program(&system_program::ID)?; + token_program.is_program(&spl_token::ID)?; + associated_token_program.is_program(&spl_associated_token_account::ID)?; + metadata_program.is_program(&mpl_token_metadata::ID)?; + rent_sysvar.is_sysvar(&sysvar::rent::ID)?; // Initialize bus accounts. let bus_infos = [ @@ -89,7 +73,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR 8 + size_of::(), &[BUS, &[i as u8], &[bus_bumps[i]]], system_program, - signer, + signer_info, )?; let mut bus_data = bus_infos[i].try_borrow_mut_data()?; bus_data[0] = Bus::discriminator() as u8; @@ -107,7 +91,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR 8 + size_of::(), &[CONFIG, &[args.config_bump]], system_program, - signer, + signer_info, )?; let mut config_data = config_info.data.borrow_mut(); config_data[0] = Config::discriminator() as u8; @@ -124,7 +108,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR 8 + size_of::(), &[TREASURY, &[args.treasury_bump]], system_program, - signer, + signer_info, )?; let mut treasury_data = treasury_info.data.borrow_mut(); treasury_data[0] = Treasury::discriminator() as u8; @@ -137,7 +121,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR Mint::LEN, &[MINT, MINT_NOISE.as_slice(), &[args.mint_bump]], system_program, - signer, + signer_info, )?; solana_program::program::invoke_signed( &spl_token::instruction::initialize_mint( @@ -162,8 +146,8 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR metadata: metadata_info, mint: mint_info, mint_authority: treasury_info, - payer: signer, - update_authority: (signer, true), + payer: signer_info, + update_authority: (signer_info, true), system_program, rent: Some(rent_sysvar), __args: mpl_token_metadata::instructions::CreateMetadataAccountV3InstructionArgs { @@ -184,7 +168,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR // Initialize treasury token account. create_ata( - signer, + signer_info, treasury_info, treasury_tokens_info, mint_info, diff --git a/program/src/mine.rs b/program/src/mine.rs index 40aa1ee..cf5cf2d 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -26,7 +26,7 @@ use solana_program::{ use steel::*; /// Mine validates hashes and increments a miner's collectable balance. -pub fn process_mine(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { +pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Parse args. let args = Mine::try_from_bytes(data)?; @@ -36,12 +36,12 @@ pub fn process_mine(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_any_bus(bus_info, true)?; - load_config(config_info, false)?; + signer.is_signer()?; + bus_info.is_type::()?.is_writable()?; + config_info.is_config()?; load_proof_with_miner(proof_info, signer.key, true)?; - load_sysvar(instructions_sysvar, sysvar::instructions::id())?; - load_sysvar(slot_hashes_sysvar, sysvar::slot_hashes::id())?; + instructions_sysvar.is_sysvar(&sysvar::instructions::ID)?; + slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?; // Authenticate the proof account. // diff --git a/program/src/open.rs b/program/src/open.rs index f914af8..e2c99e3 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -19,28 +19,25 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult let args = Open::try_from_bytes(data)?; // Load accounts. - let [signer, miner_info, payer_info, proof_info, system_program, slot_hashes_info] = accounts + let [signer_info, miner_info, payer_info, proof_info, system_program, slot_hashes_info] = + accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_any(miner_info, false)?; - load_signer(payer_info)?; - load_uninitialized_pda( - proof_info, - &[PROOF, signer.key.as_ref()], - args.bump, - &ore_api::id(), - )?; - load_program(system_program, system_program::id())?; - load_sysvar(slot_hashes_info, sysvar::slot_hashes::id())?; + signer_info.is_signer()?; + payer_info.is_signer()?; + proof_info + .is_empty_pda(&[PROOF, signer_info.key.as_ref()], args.bump, &ore_api::ID)? + .is_writable()?; + system_program.is_program(&system_program::ID)?; + slot_hashes_info.is_sysvar(&sysvar::slot_hashes::ID)?; // Initialize proof. create_pda( proof_info, &ore_api::id(), 8 + size_of::(), - &[PROOF, signer.key.as_ref(), &[args.bump]], + &[PROOF, signer_info.key.as_ref(), &[args.bump]], system_program, payer_info, )?; @@ -48,10 +45,10 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult let mut proof_data = proof_info.data.borrow_mut(); proof_data[0] = Proof::discriminator() as u8; let proof = Proof::try_from_bytes_mut(&mut proof_data)?; - proof.authority = *signer.key; + proof.authority = *signer_info.key; proof.balance = 0; proof.challenge = hashv(&[ - signer.key.as_ref(), + signer_info.key.as_ref(), &slot_hashes_info.data.borrow()[0..size_of::()], ]) .0; diff --git a/program/src/reset.rs b/program/src/reset.rs index a3abcfa..ffb282c 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -14,12 +14,12 @@ use steel::*; /// Reset tops up the bus balances, updates the base reward rate, and sets up the ORE program for the next epoch. pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { // Load accounts. - let [signer, bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info, bus_7_info, config_info, mint_info, treasury_info, treasury_tokens_info, token_program] = + let [signer_info, bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info, bus_7_info, config_info, mint_info, treasury_info, treasury_tokens_info, token_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; + signer_info.is_signer()?; load_bus(bus_0_info, 0, true)?; load_bus(bus_1_info, 1, true)?; load_bus(bus_2_info, 2, true)?; @@ -28,11 +28,11 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul load_bus(bus_5_info, 5, true)?; load_bus(bus_6_info, 6, true)?; load_bus(bus_7_info, 7, true)?; - load_config(config_info, true)?; + config_info.is_config()?.is_writable()?; load_mint(mint_info, MINT_ADDRESS, true)?; - load_treasury(treasury_info, true)?; + treasury_info.is_treasury()?.is_writable()?; load_treasury_tokens(treasury_tokens_info, true)?; - load_program(token_program, spl_token::id())?; + token_program.is_program(&spl_token::ID)?; let busses: [&AccountInfo; BUS_COUNT] = [ bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info, bus_7_info, diff --git a/program/src/stake.rs b/program/src/stake.rs index 08f33b5..94fef15 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -12,14 +12,15 @@ pub fn process_stake(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult let amount = u64::from_le_bytes(args.amount); // Load accounts. - let [signer, proof_info, sender_info, treasury_tokens_info, token_program] = accounts else { + let [signer_info, proof_info, sender_info, treasury_tokens_info, token_program] = accounts + else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_proof(proof_info, signer.key, true)?; - load_token_account(sender_info, Some(signer.key), &MINT_ADDRESS, true)?; + signer_info.is_signer()?; + load_proof(proof_info, signer_info.key, true)?; + load_token_account(sender_info, Some(signer_info.key), &MINT_ADDRESS, true)?; load_treasury_tokens(treasury_tokens_info, true)?; - load_program(token_program, spl_token::id())?; + token_program.is_program(&spl_token::ID)?; // Update the proof balance. let mut proof_data = proof_info.data.borrow_mut(); @@ -32,7 +33,7 @@ pub fn process_stake(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult // Transfer tokens from signer to treasury. transfer( - signer, + signer_info, sender_info, treasury_tokens_info, token_program, diff --git a/program/src/update.rs b/program/src/update.rs index 6ffdf3b..849eb1a 100644 --- a/program/src/update.rs +++ b/program/src/update.rs @@ -10,8 +10,8 @@ pub fn process_update(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResu let [signer, miner_info, proof_info] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_any(miner_info, false)?; + signer.is_signer()?; + // load_any(miner_info, false)?; load_proof(proof_info, signer.key, true)?; // Update the proof's miner authority. diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index 7530117..d3b2220 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -13,17 +13,22 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu let amount = u64::from_le_bytes(args.amount); // Load accounts - let [signer, beneficiary_info, mint_info, mint_v1_info, sender_info, treasury_info, token_program] = + let [signer_info, beneficiary_info, mint_info, mint_v1_info, sender_info, treasury_info, token_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - load_signer(signer)?; - load_token_account(beneficiary_info, Some(&signer.key), &MINT_ADDRESS, true)?; + signer_info.is_signer()?; + load_token_account( + beneficiary_info, + Some(&signer_info.key), + &MINT_ADDRESS, + true, + )?; load_mint(mint_info, MINT_ADDRESS, true)?; load_mint(mint_v1_info, MINT_V1_ADDRESS, true)?; - load_token_account(sender_info, Some(signer.key), &MINT_V1_ADDRESS, true)?; - load_program(token_program, spl_token::id())?; + load_token_account(sender_info, Some(signer_info.key), &MINT_V1_ADDRESS, true)?; + token_program.is_program(&spl_token::ID)?; // Burn v1 tokens solana_program::program::invoke( @@ -31,15 +36,15 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu &spl_token::id(), sender_info.key, mint_v1_info.key, - signer.key, - &[signer.key], + signer_info.key, + &[signer_info.key], amount, )?, &[ token_program.clone(), sender_info.clone(), mint_v1_info.clone(), - signer.clone(), + signer_info.clone(), ], )?; From be20034e576ceae074576ec1a8eb41fd617a28e4 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 00:22:32 +0000 Subject: [PATCH 05/46] continue migration --- Cargo.lock | 2 +- Cargo.toml | 2 +- api/src/error.rs | 2 - api/src/event.rs | 1 - api/src/loaders.rs | 211 ++------------------------------------ api/src/sdk.rs | 7 +- api/src/state/bus.rs | 28 ----- api/src/state/config.rs | 7 -- api/src/state/mod.rs | 24 ++++- api/src/state/proof.rs | 9 -- api/src/state/treasury.rs | 9 -- program/src/claim.rs | 15 +-- program/src/close.rs | 16 ++- program/src/initialize.rs | 64 ++++++++---- program/src/mine.rs | 21 ++-- program/src/open.rs | 3 +- program/src/reset.rs | 63 +++++++----- program/src/stake.rs | 14 ++- program/src/update.rs | 13 ++- program/src/upgrade.rs | 27 +++-- 20 files changed, 175 insertions(+), 363 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8758d26..19d48f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,7 +2211,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "steel" -version = "0.1.5" +version = "1.0.0" dependencies = [ "bytemuck", "num_enum", diff --git a/Cargo.toml b/Cargo.toml index 134951f..7ea337d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ solana-program = "^1.18" spl-token = { version = "^4", features = ["no-entrypoint"] } spl-associated-token-account = { version = "^2.3", features = [ "no-entrypoint" ] } static_assertions = "1.1.0" -steel = { features = ["spl"], version = "0.1.0" } +steel = { features = ["spl"], version = "1.0" } thiserror = "1.0.57" diff --git a/api/src/error.rs b/api/src/error.rs index 408681d..33fdb75 100644 --- a/api/src/error.rs +++ b/api/src/error.rs @@ -1,6 +1,4 @@ -use num_enum::IntoPrimitive; use steel::*; -use thiserror::Error; #[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] #[repr(u32)] diff --git a/api/src/event.rs b/api/src/event.rs index b7068b3..28b266d 100644 --- a/api/src/event.rs +++ b/api/src/event.rs @@ -1,4 +1,3 @@ -use bytemuck::{Pod, Zeroable}; use steel::*; #[repr(C)] diff --git a/api/src/loaders.rs b/api/src/loaders.rs index 77fa46a..ebc7383 100644 --- a/api/src/loaders.rs +++ b/api/src/loaders.rs @@ -1,223 +1,28 @@ -use solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}; use steel::*; use crate::{ consts::*, - state::{Bus, Config, Proof, Treasury}, + state::{Config, Treasury}, }; -/// Errors if: -/// - Owner is not Ore program. -/// - Address does not match the expected bus address. -/// - Data is empty. -/// - Data cannot deserialize into a bus account. -/// - Bus ID does not match the expected ID. -/// - Expected to be writable, but is not. -pub fn load_bus(info: &AccountInfo<'_>, id: u64, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.key.ne(&BUS_ADDRESSES[id as usize]) { - return Err(ProgramError::InvalidSeeds); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - let bus_data = info.data.borrow(); - let bus = Bus::try_from_bytes(&bus_data)?; - - if bus.id.ne(&id) { - return Err(ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not Ore program. -/// - Data is empty. -/// - Data cannot deserialize into a bus account. -/// - Bus ID is not in the expected range. -/// - Address is not in set of valid bus address. -/// - Expected to be writable, but is not. -pub fn load_any_bus(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - if info.data.borrow()[0].ne(&(Bus::discriminator() as u8)) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); - } - - if !BUS_ADDRESSES.contains(info.key) { - return Err(ProgramError::InvalidSeeds); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not Ore program. -/// - Address does not match the expected address. -/// - Data is empty. -/// - Data cannot deserialize into a config account. -/// - Expected to be writable, but is not. -pub fn load_config(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.key.ne(&CONFIG_ADDRESS) { - return Err(ProgramError::InvalidSeeds); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - if info.data.borrow()[0].ne(&(Config::discriminator() as u8)) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not Ore program. -/// - Data is empty. -/// - Data cannot deserialize into a proof account. -/// - Proof authority does not match the expected address. -/// - Expected to be writable, but is not. -pub fn load_proof( - info: &AccountInfo<'_>, - authority: &Pubkey, - is_writable: bool, -) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - let proof_data = info.data.borrow(); - let proof = Proof::try_from_bytes(&proof_data)?; - - if proof.authority.ne(&authority) { - return Err(ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not Ore program. -/// - Data is empty. -/// - Data cannot deserialize into a proof account. -/// - Proof miner does not match the expected address. -/// - Expected to be writable, but is not. -pub fn load_proof_with_miner( - info: &AccountInfo<'_>, - miner: &Pubkey, - is_writable: bool, -) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - let proof_data = info.data.borrow(); - let proof = Proof::try_from_bytes(&proof_data)?; - - if proof.miner.ne(&miner) { - return Err(ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - -/// Errors if: -/// - Owner is not Ore program. -/// - Data is empty. -/// - Data cannot deserialize into a proof account. -/// - Expected to be writable, but is not. -pub fn load_any_proof(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.owner.ne(&crate::id()) { - return Err(ProgramError::InvalidAccountOwner); - } - - if info.data_is_empty() { - return Err(ProgramError::UninitializedAccount); - } - - if info.data.borrow()[0].ne(&(Proof::discriminator() as u8)) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); - } - - if is_writable && !info.is_writable { - return Err(ProgramError::InvalidAccountData); - } - - Ok(()) -} - pub trait OreAccountInfoValidation { fn is_config(&self) -> Result<&Self, ProgramError>; fn is_treasury(&self) -> Result<&Self, ProgramError>; + fn is_treasury_tokens(&self) -> Result<&Self, ProgramError>; } -impl<'a> OreAccountInfoValidation for AccountInfo<'a> { +impl OreAccountInfoValidation for AccountInfo<'_> { fn is_config(&self) -> Result<&Self, ProgramError> { self.has_address(&CONFIG_ADDRESS)? - .has_owner(&crate::ID)? - .is_type::() + .is_type::(&crate::ID) } fn is_treasury(&self) -> Result<&Self, ProgramError> { self.has_address(&TREASURY_ADDRESS)? - .has_owner(&crate::ID)? - .is_type::() - } -} - -/// Errors if: -/// - Address does not match the expected treasury tokens address. -/// - Cannot load as a token account -pub fn load_treasury_tokens(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> { - if info.key.ne(&TREASURY_TOKENS_ADDRESS) { - return Err(ProgramError::InvalidSeeds); + .is_type::(&crate::ID) } - load_token_account(info, Some(&TREASURY_ADDRESS), &MINT_ADDRESS, is_writable) + fn is_treasury_tokens(&self) -> Result<&Self, ProgramError> { + self.has_address(&TREASURY_TOKENS_ADDRESS) + } } diff --git a/api/src/sdk.rs b/api/src/sdk.rs index 67793dc..602a4f6 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -1,9 +1,6 @@ use drillx::Solution; -use solana_program::{ - instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - system_program, sysvar, -}; +use solana_program::{system_program, sysvar}; +use steel::*; use crate::{ consts::*, diff --git a/api/src/state/bus.rs b/api/src/state/bus.rs index f92f715..bf32edc 100644 --- a/api/src/state/bus.rs +++ b/api/src/state/bus.rs @@ -1,7 +1,5 @@ use steel::*; -use crate::consts::BUS; - use super::OreAccount; /// Bus accounts are responsible for distributing mining rewards. There are 8 busses total @@ -23,30 +21,4 @@ pub struct Bus { pub top_balance: u64, } -/// Fetch the PDA of a bus account. -pub fn bus_pda(id: u8) -> (Pubkey, u8) { - Pubkey::find_program_address(&[BUS, &[id]], &crate::id()) -} - -impl<'a> From<&'a [u8]> for &'a Bus { - fn from(value: &'a [u8]) -> &'a Bus { - Bus::try_from_bytes(value).unwrap() - } -} - -impl<'a> From<*const u8> for &'a Bus { - fn from(value: *const u8) -> &'a Bus { - unsafe { - if Bus::discriminator().ne(&value.add(0).read()) { - panic!(""); - } - bytemuck::try_from_bytes::(std::slice::from_raw_parts( - value.add(8), - std::mem::size_of::(), - )) - .expect("") - } - } -} - account!(OreAccount, Bus); diff --git a/api/src/state/config.rs b/api/src/state/config.rs index 64bbf8c..52b21cc 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -1,7 +1,5 @@ use steel::*; -use crate::consts::CONFIG; - use super::OreAccount; /// Config is a singleton account which manages program global variables. @@ -21,9 +19,4 @@ pub struct Config { pub top_balance: u64, } -/// Derive the PDA of the config account. -pub fn config_pda() -> (Pubkey, u8) { - Pubkey::find_program_address(&[CONFIG], &crate::id()) -} - account!(OreAccount, Config); diff --git a/api/src/state/mod.rs b/api/src/state/mod.rs index 6803553..20baa13 100644 --- a/api/src/state/mod.rs +++ b/api/src/state/mod.rs @@ -8,7 +8,9 @@ pub use config::*; pub use proof::*; pub use treasury::*; -use num_enum::{IntoPrimitive, TryFromPrimitive}; +use steel::*; + +use crate::consts::*; #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] @@ -18,3 +20,23 @@ pub enum OreAccount { Proof = 102, Treasury = 103, } + +/// Fetch the PDA of a bus account. +pub fn bus_pda(id: u8) -> (Pubkey, u8) { + Pubkey::find_program_address(&[BUS, &[id]], &crate::id()) +} + +/// Derive the PDA of the config account. +pub fn config_pda() -> (Pubkey, u8) { + Pubkey::find_program_address(&[CONFIG], &crate::id()) +} + +/// Derive the PDA of a proof account. +pub fn proof_pda(authority: Pubkey) -> (Pubkey, u8) { + Pubkey::find_program_address(&[PROOF, authority.as_ref()], &crate::id()) +} + +/// Derive the PDA of the treasury account. +pub fn treasury_pda() -> (Pubkey, u8) { + Pubkey::find_program_address(&[TREASURY], &crate::id()) +} diff --git a/api/src/state/proof.rs b/api/src/state/proof.rs index 33c0f4a..733e115 100644 --- a/api/src/state/proof.rs +++ b/api/src/state/proof.rs @@ -1,9 +1,5 @@ -use bytemuck::{Pod, Zeroable}; -use solana_program::pubkey::Pubkey; use steel::*; -use crate::consts::PROOF; - use super::OreAccount; /// Proof accounts track a miner's current hash, claimable rewards, and lifetime stats. @@ -39,9 +35,4 @@ pub struct Proof { pub total_rewards: u64, } -/// Derive the PDA of a proof account. -pub fn proof_pda(authority: Pubkey) -> (Pubkey, u8) { - Pubkey::find_program_address(&[PROOF, authority.as_ref()], &crate::id()) -} - account!(OreAccount, Proof); diff --git a/api/src/state/treasury.rs b/api/src/state/treasury.rs index 289fc35..2268ae0 100644 --- a/api/src/state/treasury.rs +++ b/api/src/state/treasury.rs @@ -1,9 +1,5 @@ -use bytemuck::{Pod, Zeroable}; -use solana_program::pubkey::Pubkey; use steel::*; -use crate::consts::TREASURY; - use super::OreAccount; /// Treasury is a singleton account which is the mint authority for the ORE token and the authority of @@ -12,9 +8,4 @@ use super::OreAccount; #[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] pub struct Treasury {} -/// Derive the PDA of the treasury account. -pub fn treasury_pda() -> (Pubkey, u8) { - Pubkey::find_program_address(&[TREASURY], &crate::id()) -} - account!(OreAccount, Treasury); diff --git a/program/src/claim.rs b/program/src/claim.rs index 9f564b8..6e594fb 100644 --- a/program/src/claim.rs +++ b/program/src/claim.rs @@ -17,15 +17,18 @@ pub fn process_claim(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult return Err(ProgramError::NotEnoughAccountKeys); }; signer.is_signer()?; - load_token_account(beneficiary_info, None, &MINT_ADDRESS, true)?; - load_proof(proof_info, signer.key, true)?; + beneficiary_info + .is_writable()? + .to_token_account()? + .check(|t| t.mint.eq(&MINT_ADDRESS))?; + let proof = proof_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|p| p.authority == *signer.key)?; treasury_info.is_treasury()?; - load_treasury_tokens(treasury_tokens_info, true)?; - token_program.has_address(&spl_token::ID)?; + treasury_tokens_info.is_writable()?.is_treasury_tokens()?; + token_program.is_program(&spl_token::ID)?; // Update miner balance. - let mut proof_data = proof_info.data.borrow_mut(); - let proof = Proof::try_from_bytes_mut(&mut proof_data)?; proof.balance = proof .balance .checked_sub(amount) diff --git a/program/src/close.rs b/program/src/close.rs index 4201b5f..94e63e4 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -1,4 +1,4 @@ -use ore_api::{loaders::*, state::Proof}; +use ore_api::state::Proof; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, system_program, @@ -12,17 +12,13 @@ pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul return Err(ProgramError::NotEnoughAccountKeys); }; signer_info.is_signer()?; - load_proof(proof_info, signer_info.key, true)?; + proof_info + .is_writable()? + .to_account::(&ore_api::ID)? + .check(|p| p.authority == *signer_info.key)? + .check(|p| p.balance > 0)?; system_program.is_program(&system_program::ID)?; - // Validate balance is zero. - let proof_data = proof_info.data.borrow(); - let proof = Proof::try_from_bytes(&proof_data)?; - if proof.balance.gt(&0) { - return Err(ProgramError::InvalidAccountData); - } - drop(proof_data); - // Realloc data to zero. proof_info.realloc(0, true)?; diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 16bd2d0..d331c14 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -24,26 +24,50 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR return Err(ProgramError::NotEnoughAccountKeys); }; signer_info.is_signer()?.has_address(&INITIALIZER_ADDRESS)?; - bus_0_info.is_empty_pda(&[BUS, &[0]], args.bus_0_bump, &ore_api::ID)?; - bus_1_info.is_empty_pda(&[BUS, &[1]], args.bus_1_bump, &ore_api::ID)?; - bus_2_info.is_empty_pda(&[BUS, &[2]], args.bus_2_bump, &ore_api::ID)?; - bus_3_info.is_empty_pda(&[BUS, &[3]], args.bus_3_bump, &ore_api::ID)?; - bus_4_info.is_empty_pda(&[BUS, &[4]], args.bus_4_bump, &ore_api::ID)?; - bus_5_info.is_empty_pda(&[BUS, &[5]], args.bus_5_bump, &ore_api::ID)?; - bus_6_info.is_empty_pda(&[BUS, &[6]], args.bus_6_bump, &ore_api::ID)?; - bus_7_info.is_empty_pda(&[BUS, &[7]], args.bus_7_bump, &ore_api::ID)?; - config_info.is_empty_pda(&[CONFIG], args.config_bump, &ore_api::id())?; - metadata_info.is_empty_pda( - &[ - METADATA, - mpl_token_metadata::ID.as_ref(), - MINT_ADDRESS.as_ref(), - ], - args.metadata_bump, - &mpl_token_metadata::ID, - )?; - mint_info.is_empty_pda(&[MINT, MINT_NOISE.as_slice()], args.mint_bump, &ore_api::ID)?; - treasury_info.is_empty_pda(&[TREASURY], args.treasury_bump, &ore_api::ID)?; + bus_0_info + .has_seeds(&[BUS, &[0]], args.bus_0_bump, &ore_api::ID)? + .is_empty()?; + bus_1_info + .has_seeds(&[BUS, &[1]], args.bus_1_bump, &ore_api::ID)? + .is_empty()?; + bus_2_info + .has_seeds(&[BUS, &[2]], args.bus_2_bump, &ore_api::ID)? + .is_empty()?; + bus_3_info + .has_seeds(&[BUS, &[3]], args.bus_3_bump, &ore_api::ID)? + .is_empty()?; + bus_4_info + .has_seeds(&[BUS, &[4]], args.bus_4_bump, &ore_api::ID)? + .is_empty()?; + bus_5_info + .has_seeds(&[BUS, &[5]], args.bus_5_bump, &ore_api::ID)? + .is_empty()?; + bus_6_info + .has_seeds(&[BUS, &[6]], args.bus_6_bump, &ore_api::ID)? + .is_empty()?; + bus_7_info + .has_seeds(&[BUS, &[7]], args.bus_7_bump, &ore_api::ID)? + .is_empty()?; + config_info + .has_seeds(&[CONFIG], args.config_bump, &ore_api::ID)? + .is_empty()?; + metadata_info + .has_seeds( + &[ + METADATA, + mpl_token_metadata::ID.as_ref(), + MINT_ADDRESS.as_ref(), + ], + args.metadata_bump, + &mpl_token_metadata::ID, + )? + .is_empty()?; + mint_info + .has_seeds(&[MINT, MINT_NOISE.as_slice()], args.mint_bump, &ore_api::ID)? + .is_empty()?; + treasury_info + .has_seeds(&[TREASURY], args.treasury_bump, &ore_api::ID)? + .is_empty()?; treasury_tokens_info.is_empty()?; system_program.is_program(&system_program::ID)?; token_program.is_program(&spl_token::ID)?; diff --git a/program/src/mine.rs b/program/src/mine.rs index cf5cf2d..b5af8db 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -6,7 +6,6 @@ use ore_api::{ error::OreError, event::MineEvent, instruction::Mine, - loaders::*, state::{Bus, Config, Proof}, }; use solana_program::program::set_return_data; @@ -37,9 +36,11 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { return Err(ProgramError::NotEnoughAccountKeys); }; signer.is_signer()?; - bus_info.is_type::()?.is_writable()?; - config_info.is_config()?; - load_proof_with_miner(proof_info, signer.key, true)?; + let bus = bus_info.to_account_mut::(&ore_api::ID)?; + let config = config_info.to_account::(&ore_api::ID)?; + let proof = proof_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|p| p.authority.eq(signer.key))?; instructions_sysvar.is_sysvar(&sysvar::instructions::ID)?; slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?; @@ -50,8 +51,8 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { authenticate(&instructions_sysvar.data.borrow(), proof_info.key)?; // Validate epoch is active. - let config_data = config_info.data.borrow(); - let config = Config::try_from_bytes(&config_data)?; + // let config_data = config_info.data.borrow(); + // let config = Config::try_from_bytes(&config_data)?; let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; if config .last_reset_at @@ -65,8 +66,8 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // // Here we use drillx to validate the provided solution is a valid hash of the challenge. // If invalid, we return an error. - let mut proof_data = proof_info.data.borrow_mut(); - let proof = Proof::try_from_bytes_mut(&mut proof_data)?; + // let mut proof_data = proof_info.data.borrow_mut(); + // let proof = Proof::try_from_bytes_mut(&mut proof_data)?; let solution = Solution::new(args.digest, args.nonce); if !solution.is_valid(&proof.challenge) { return Err(OreError::HashInvalid.into()); @@ -110,8 +111,8 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. - let mut bus_data = bus_info.data.borrow_mut(); - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; + // let mut bus_data = bus_info.data.borrow_mut(); + // let bus = Bus::try_from_bytes_mut(&mut bus_data)?; if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { // Calculate staking reward. if config.top_balance.gt(&0) { diff --git a/program/src/open.rs b/program/src/open.rs index e2c99e3..a89dbea 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -27,7 +27,8 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult signer_info.is_signer()?; payer_info.is_signer()?; proof_info - .is_empty_pda(&[PROOF, signer_info.key.as_ref()], args.bump, &ore_api::ID)? + .has_seeds(&[PROOF, signer_info.key.as_ref()], args.bump, &ore_api::ID)? + .is_empty()? .is_writable()?; system_program.is_program(&system_program::ID)?; slot_hashes_info.is_sysvar(&sysvar::slot_hashes::ID)?; diff --git a/program/src/reset.rs b/program/src/reset.rs index ffb282c..fccb2f3 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -4,11 +4,7 @@ use ore_api::{ loaders::*, state::{Bus, Config}, }; -use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, - program_error::ProgramError, program_pack::Pack, sysvar::Sysvar, -}; -use spl_token::state::Mint; +use solana_program::clock::Clock; use steel::*; /// Reset tops up the bus balances, updates the base reward rate, and sets up the ORE program for the next epoch. @@ -20,27 +16,42 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul return Err(ProgramError::NotEnoughAccountKeys); }; signer_info.is_signer()?; - load_bus(bus_0_info, 0, true)?; - load_bus(bus_1_info, 1, true)?; - load_bus(bus_2_info, 2, true)?; - load_bus(bus_3_info, 3, true)?; - load_bus(bus_4_info, 4, true)?; - load_bus(bus_5_info, 5, true)?; - load_bus(bus_6_info, 6, true)?; - load_bus(bus_7_info, 7, true)?; - config_info.is_config()?.is_writable()?; - load_mint(mint_info, MINT_ADDRESS, true)?; + let bus_0 = bus_0_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 0)?; + let bus_1 = bus_1_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 1)?; + let bus_2 = bus_2_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 2)?; + let bus_3 = bus_3_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 3)?; + let bus_4 = bus_4_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 4)?; + let bus_5 = bus_5_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 5)?; + let bus_6 = bus_6_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 6)?; + let bus_7 = bus_7_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|b| b.id == 7)?; + let config = config_info.to_account_mut::(&ore_api::ID)?; + let mint = mint_info + .has_address(&MINT_ADDRESS)? + .is_writable()? + .to_mint()?; treasury_info.is_treasury()?.is_writable()?; - load_treasury_tokens(treasury_tokens_info, true)?; + treasury_tokens_info.is_treasury_tokens()?.is_writable()?; token_program.is_program(&spl_token::ID)?; - let busses: [&AccountInfo; BUS_COUNT] = [ - bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info, - bus_7_info, - ]; // Validate enough time has passed since the last reset. - let mut config_data = config_info.data.borrow_mut(); - let config = Config::try_from_bytes_mut(&mut config_data)?; + // let mut config_data = config_info.data.borrow_mut(); + // let config = Config::try_from_bytes_mut(&mut config_data)?; let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; if config .last_reset_at @@ -54,14 +65,11 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul config.last_reset_at = clock.unix_timestamp; // Reset bus accounts and calculate actual rewards mined since last reset. + let busses = [bus_0, bus_1, bus_2, bus_3, bus_4, bus_5, bus_6, bus_7]; let mut total_remaining_rewards = 0u64; let mut total_theoretical_rewards = 0u64; let mut top_balance = 0u64; - for i in 0..BUS_COUNT { - // Parse bus account. - let mut bus_data = busses[i].data.borrow_mut(); - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; - + for bus in busses { // Track top balance. if bus.top_balance.gt(&top_balance) { top_balance = bus.top_balance; @@ -99,7 +107,6 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul } // Max supply check. - let mint = Mint::unpack(&mint_info.data.borrow()).expect("Failed to parse mint"); if mint.supply.ge(&MAX_SUPPLY) { return Err(OreError::MaxSupply.into()); } diff --git a/program/src/stake.rs b/program/src/stake.rs index 94fef15..9a4ac41 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -17,14 +17,18 @@ pub fn process_stake(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult return Err(ProgramError::NotEnoughAccountKeys); }; signer_info.is_signer()?; - load_proof(proof_info, signer_info.key, true)?; - load_token_account(sender_info, Some(signer_info.key), &MINT_ADDRESS, true)?; - load_treasury_tokens(treasury_tokens_info, true)?; + let proof = proof_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|p| p.authority == *signer_info.key)?; + sender_info + .is_writable()? + .to_token_account()? + .check(|t| t.owner.eq(signer_info.key))? + .check(|t| t.mint.eq(&MINT_ADDRESS))?; + treasury_tokens_info.is_writable()?.is_treasury_tokens()?; token_program.is_program(&spl_token::ID)?; // Update the proof balance. - let mut proof_data = proof_info.data.borrow_mut(); - let proof = Proof::try_from_bytes_mut(&mut proof_data)?; proof.balance = proof.balance.checked_add(amount).unwrap(); // Update deposit timestamp. diff --git a/program/src/update.rs b/program/src/update.rs index 849eb1a..b101a3e 100644 --- a/program/src/update.rs +++ b/program/src/update.rs @@ -1,4 +1,4 @@ -use ore_api::{loaders::*, state::Proof}; +use ore_api::state::Proof; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, }; @@ -7,16 +7,15 @@ use steel::*; /// Update changes the miner authority on a proof account. pub fn process_update(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { // Load accounts. - let [signer, miner_info, proof_info] = accounts else { + let [signer_info, miner_info, proof_info] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - signer.is_signer()?; - // load_any(miner_info, false)?; - load_proof(proof_info, signer.key, true)?; + signer_info.is_signer()?; + let proof = proof_info + .to_account_mut::(&ore_api::ID)? + .check_mut(|p| p.authority == *signer_info.key)?; // Update the proof's miner authority. - let mut proof_data = proof_info.data.borrow_mut(); - let proof = Proof::try_from_bytes_mut(&mut proof_data)?; proof.miner = *miner_info.key; Ok(()) diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index d3b2220..f530d2b 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -19,15 +19,24 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu return Err(ProgramError::NotEnoughAccountKeys); }; signer_info.is_signer()?; - load_token_account( - beneficiary_info, - Some(&signer_info.key), - &MINT_ADDRESS, - true, - )?; - load_mint(mint_info, MINT_ADDRESS, true)?; - load_mint(mint_v1_info, MINT_V1_ADDRESS, true)?; - load_token_account(sender_info, Some(signer_info.key), &MINT_V1_ADDRESS, true)?; + beneficiary_info + .is_writable()? + .to_token_account()? + .check(|t| t.owner.eq(signer_info.key))? + .check(|t| t.mint.eq(&MINT_ADDRESS))?; + mint_info + .is_writable()? + .has_address(&MINT_ADDRESS)? + .to_mint()?; + mint_v1_info + .is_writable()? + .has_address(&MINT_V1_ADDRESS)? + .to_mint()?; + sender_info + .is_writable()? + .to_token_account()? + .check(|t| t.owner.eq(signer_info.key))? + .check(|t| t.mint.eq(&MINT_V1_ADDRESS))?; token_program.is_program(&spl_token::ID)?; // Burn v1 tokens From 4db7f970b226dffa5268b6b0a3c787f39b495555 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 01:26:26 +0000 Subject: [PATCH 06/46] cleanup --- Cargo.lock | 2 +- program/src/claim.rs | 8 ++++---- program/src/mine.rs | 6 +++--- program/src/upgrade.rs | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19d48f8..06734de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,7 +2211,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "steel" -version = "1.0.0" +version = "1.1.0" dependencies = [ "bytemuck", "num_enum", diff --git a/program/src/claim.rs b/program/src/claim.rs index 6e594fb..8668190 100644 --- a/program/src/claim.rs +++ b/program/src/claim.rs @@ -11,19 +11,19 @@ pub fn process_claim(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult let amount = u64::from_le_bytes(args.amount); // Load accounts. - let [signer, beneficiary_info, proof_info, treasury_info, treasury_tokens_info, token_program] = + let [signer_info, beneficiary_info, proof_info, treasury_info, treasury_tokens_info, token_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - signer.is_signer()?; + signer_info.is_signer()?; beneficiary_info .is_writable()? .to_token_account()? - .check(|t| t.mint.eq(&MINT_ADDRESS))?; + .check(|t| t.mint == MINT_ADDRESS)?; let proof = proof_info .to_account_mut::(&ore_api::ID)? - .check_mut(|p| p.authority == *signer.key)?; + .check_mut(|p| p.authority == *signer_info.key)?; treasury_info.is_treasury()?; treasury_tokens_info.is_writable()?.is_treasury_tokens()?; token_program.is_program(&spl_token::ID)?; diff --git a/program/src/mine.rs b/program/src/mine.rs index b5af8db..1fb35e6 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -30,17 +30,17 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { let args = Mine::try_from_bytes(data)?; // Load accounts. - let [signer, bus_info, config_info, proof_info, instructions_sysvar, slot_hashes_sysvar] = + let [signer_info, bus_info, config_info, proof_info, instructions_sysvar, slot_hashes_sysvar] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - signer.is_signer()?; + signer_info.is_signer()?; let bus = bus_info.to_account_mut::(&ore_api::ID)?; let config = config_info.to_account::(&ore_api::ID)?; let proof = proof_info .to_account_mut::(&ore_api::ID)? - .check_mut(|p| p.authority.eq(signer.key))?; + .check_mut(|p| p.miner == *signer_info.key)?; instructions_sysvar.is_sysvar(&sysvar::instructions::ID)?; slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?; diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index f530d2b..202eb53 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -22,8 +22,8 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu beneficiary_info .is_writable()? .to_token_account()? - .check(|t| t.owner.eq(signer_info.key))? - .check(|t| t.mint.eq(&MINT_ADDRESS))?; + .check(|t| t.owner == *signer_info.key)? + .check(|t| t.mint == MINT_ADDRESS)?; mint_info .is_writable()? .has_address(&MINT_ADDRESS)? @@ -35,8 +35,8 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu sender_info .is_writable()? .to_token_account()? - .check(|t| t.owner.eq(signer_info.key))? - .check(|t| t.mint.eq(&MINT_V1_ADDRESS))?; + .check(|t| t.owner == *signer_info.key)? + .check(|t| t.mint == MINT_V1_ADDRESS)?; token_program.is_program(&spl_token::ID)?; // Burn v1 tokens From a9e445ad36f28de520199a803656d91c9b78bc59 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 02:40:50 +0000 Subject: [PATCH 07/46] use const pubkey --- api/src/sdk.rs | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/api/src/sdk.rs b/api/src/sdk.rs index 602a4f6..e6ccd5d 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -20,10 +20,6 @@ pub fn auth(proof: Pubkey) -> Instruction { /// Builds a claim instruction. pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction { let proof = proof_pda(signer).0; - let treasury_tokens = spl_associated_token_account::get_associated_token_address( - &TREASURY_ADDRESS, - &MINT_ADDRESS, - ); Instruction { program_id: crate::id(), accounts: vec![ @@ -31,7 +27,7 @@ pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction { AccountMeta::new(beneficiary, false), AccountMeta::new(proof, false), AccountMeta::new_readonly(TREASURY_ADDRESS, false), - AccountMeta::new(treasury_tokens, false), + AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), AccountMeta::new_readonly(spl_token::id(), false), ], data: Claim { @@ -95,10 +91,6 @@ pub fn open(signer: Pubkey, miner: Pubkey, payer: Pubkey) -> Instruction { /// Builds a reset instruction. pub fn reset(signer: Pubkey) -> Instruction { - let treasury_tokens = spl_associated_token_account::get_associated_token_address( - &TREASURY_ADDRESS, - &MINT_ADDRESS, - ); Instruction { program_id: crate::id(), accounts: vec![ @@ -114,7 +106,7 @@ pub fn reset(signer: Pubkey) -> Instruction { AccountMeta::new(CONFIG_ADDRESS, false), AccountMeta::new(MINT_ADDRESS, false), AccountMeta::new(TREASURY_ADDRESS, false), - AccountMeta::new(treasury_tokens, false), + AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), AccountMeta::new_readonly(spl_token::id(), false), ], data: Reset {}.to_bytes(), @@ -124,17 +116,13 @@ pub fn reset(signer: Pubkey) -> Instruction { /// Build a stake instruction. pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction { let proof = proof_pda(signer).0; - let treasury_tokens = spl_associated_token_account::get_associated_token_address( - &TREASURY_ADDRESS, - &MINT_ADDRESS, - ); Instruction { program_id: crate::id(), accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(proof, false), AccountMeta::new(sender, false), - AccountMeta::new(treasury_tokens, false), + AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), AccountMeta::new_readonly(spl_token::id(), false), ], data: Stake { @@ -193,8 +181,6 @@ pub fn initialize(signer: Pubkey) -> Instruction { let config_pda = config_pda(); let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::id()); let treasury_pda = treasury_pda(); - let treasury_tokens = - spl_associated_token_account::get_associated_token_address(&treasury_pda.0, &mint_pda.0); let metadata_pda = Pubkey::find_program_address( &[ METADATA, @@ -219,7 +205,7 @@ pub fn initialize(signer: Pubkey) -> Instruction { AccountMeta::new(metadata_pda.0, false), AccountMeta::new(mint_pda.0, false), AccountMeta::new(treasury_pda.0, false), - AccountMeta::new(treasury_tokens, false), + AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(spl_associated_token_account::id(), false), From 799676863b631fb688fefe469450744bf405833f Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 04:42:00 +0000 Subject: [PATCH 08/46] bump steel verison --- Cargo.lock | 2 +- program/src/initialize.rs | 26 +++++++------------------- program/src/open.rs | 9 +++------ 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06734de..5ee7aae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,7 +2211,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "steel" -version = "1.1.0" +version = "1.2.0" dependencies = [ "bytemuck", "num_enum", diff --git a/program/src/initialize.rs b/program/src/initialize.rs index d331c14..b17a8eb 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -1,5 +1,3 @@ -use std::mem::size_of; - use ore_api::{ consts::*, instruction::*, @@ -91,17 +89,14 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR args.bus_7_bump, ]; for i in 0..BUS_COUNT { - create_pda( + create_account::( bus_infos[i], &ore_api::id(), - 8 + size_of::(), &[BUS, &[i as u8], &[bus_bumps[i]]], system_program, signer_info, )?; - let mut bus_data = bus_infos[i].try_borrow_mut_data()?; - bus_data[0] = Bus::discriminator() as u8; - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; + let bus = bus_infos[i].to_account_mut::(&ore_api::ID)?; bus.id = i as u64; bus.rewards = 0; bus.theoretical_rewards = 0; @@ -109,37 +104,30 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR } // Initialize config. - create_pda( + create_account::( config_info, &ore_api::id(), - 8 + size_of::(), &[CONFIG, &[args.config_bump]], system_program, signer_info, )?; - let mut config_data = config_info.data.borrow_mut(); - config_data[0] = Config::discriminator() as u8; - let config = Config::try_from_bytes_mut(&mut config_data)?; + let config = config_info.to_account_mut::(&ore_api::ID)?; config.base_reward_rate = INITIAL_BASE_REWARD_RATE; config.last_reset_at = 0; config.min_difficulty = INITIAL_MIN_DIFFICULTY as u64; config.top_balance = 0; // Initialize treasury. - create_pda( + create_account::( treasury_info, &ore_api::id(), - 8 + size_of::(), &[TREASURY, &[args.treasury_bump]], system_program, signer_info, )?; - let mut treasury_data = treasury_info.data.borrow_mut(); - treasury_data[0] = Treasury::discriminator() as u8; - drop(treasury_data); // Initialize mint. - create_pda( + allocate_account( mint_info, &spl_token::id(), Mint::LEN, @@ -191,7 +179,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR .invoke_signed(&[&[TREASURY, &[args.treasury_bump]]])?; // Initialize treasury token account. - create_ata( + create_associated_token_account( signer_info, treasury_info, treasury_tokens_info, diff --git a/program/src/open.rs b/program/src/open.rs index a89dbea..ceee168 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -34,18 +34,15 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult slot_hashes_info.is_sysvar(&sysvar::slot_hashes::ID)?; // Initialize proof. - create_pda( + create_account::( proof_info, - &ore_api::id(), - 8 + size_of::(), + &ore_api::ID, &[PROOF, signer_info.key.as_ref(), &[args.bump]], system_program, payer_info, )?; let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; - let mut proof_data = proof_info.data.borrow_mut(); - proof_data[0] = Proof::discriminator() as u8; - let proof = Proof::try_from_bytes_mut(&mut proof_data)?; + let proof = proof_info.to_account_mut::(&ore_api::ID)?; proof.authority = *signer_info.key; proof.balance = 0; proof.challenge = hashv(&[ From 5bd4a467d69330454cdf3626817a151b320e4529 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:04:29 +0000 Subject: [PATCH 09/46] cleanup imports --- program/src/claim.rs | 3 --- program/src/close.rs | 5 +---- program/src/mine.rs | 5 ----- program/src/open.rs | 4 ---- program/src/reset.rs | 1 - program/src/stake.rs | 4 ---- program/src/update.rs | 3 --- program/src/upgrade.rs | 10 +--------- 8 files changed, 2 insertions(+), 33 deletions(-) diff --git a/program/src/claim.rs b/program/src/claim.rs index 8668190..7fa8c48 100644 --- a/program/src/claim.rs +++ b/program/src/claim.rs @@ -1,7 +1,4 @@ use ore_api::{consts::*, error::OreError, instruction::*, loaders::*, state::Proof}; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, -}; use steel::*; /// Claim distributes claimable ORE from the treasury to a miner. diff --git a/program/src/close.rs b/program/src/close.rs index 94e63e4..6737ade 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -1,8 +1,5 @@ use ore_api::state::Proof; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - system_program, -}; +use solana_program::system_program; use steel::*; /// Close closes a proof account and returns the rent to the owner. diff --git a/program/src/mine.rs b/program/src/mine.rs index 1fb35e6..1cdadb7 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -11,12 +11,7 @@ use ore_api::{ use solana_program::program::set_return_data; #[allow(deprecated)] use solana_program::{ - account_info::AccountInfo, - clock::Clock, - entrypoint::ProgramResult, keccak::hashv, - program_error::ProgramError, - pubkey::Pubkey, sanitize::SanitizeError, serialize_utils::{read_pubkey, read_u16}, slot_hashes::SlotHash, diff --git a/program/src/open.rs b/program/src/open.rs index ceee168..94c7dec 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -2,11 +2,7 @@ use std::mem::size_of; use ore_api::{consts::*, instruction::Open, state::Proof}; use solana_program::{ - account_info::AccountInfo, - clock::Clock, - entrypoint::ProgramResult, keccak::hashv, - program_error::ProgramError, slot_hashes::SlotHash, system_program, sysvar::{self, Sysvar}, diff --git a/program/src/reset.rs b/program/src/reset.rs index fccb2f3..2800139 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -4,7 +4,6 @@ use ore_api::{ loaders::*, state::{Bus, Config}, }; -use solana_program::clock::Clock; use steel::*; /// Reset tops up the bus balances, updates the base reward rate, and sets up the ORE program for the next epoch. diff --git a/program/src/stake.rs b/program/src/stake.rs index 9a4ac41..1e495dd 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -1,8 +1,4 @@ use ore_api::{consts::*, instruction::Stake, loaders::*, state::Proof}; -use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, - program_error::ProgramError, sysvar::Sysvar, -}; use steel::*; /// Stake deposits ORE into a proof account to earn multiplier. diff --git a/program/src/update.rs b/program/src/update.rs index b101a3e..6bf6f74 100644 --- a/program/src/update.rs +++ b/program/src/update.rs @@ -1,7 +1,4 @@ use ore_api::state::Proof; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, -}; use steel::*; /// Update changes the miner authority on a proof account. diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index 202eb53..058c400 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -1,9 +1,4 @@ use ore_api::{consts::*, error::OreError, instruction::Stake}; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - program_pack::Pack, -}; -use spl_token::state::Mint; use steel::*; /// Upgrade allows a user to migrate a v1 token to a v2 token at a 1:1 exchange rate. @@ -24,7 +19,7 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu .to_token_account()? .check(|t| t.owner == *signer_info.key)? .check(|t| t.mint == MINT_ADDRESS)?; - mint_info + let mint = mint_info .is_writable()? .has_address(&MINT_ADDRESS)? .to_mint()?; @@ -62,14 +57,11 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu let amount_to_mint = amount.saturating_mul(100); // Cap at max supply. - let mint_data = mint_info.data.borrow(); - let mint = Mint::unpack(&mint_data)?; if mint.supply.saturating_add(amount_to_mint).gt(&MAX_SUPPLY) { return Err(OreError::MaxSupply.into()); } // Mint to the beneficiary account - drop(mint_data); mint_to_signed( mint_info, beneficiary_info, From d41c07c999f9d7081e4021b5d3c33066e8895b66 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:07:21 +0000 Subject: [PATCH 10/46] close condition --- program/src/close.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/src/close.rs b/program/src/close.rs index 6737ade..4be47c0 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -13,7 +13,7 @@ pub fn process_close(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul .is_writable()? .to_account::(&ore_api::ID)? .check(|p| p.authority == *signer_info.key)? - .check(|p| p.balance > 0)?; + .check(|p| p.balance == 0)?; system_program.is_program(&system_program::ID)?; // Realloc data to zero. From dc401ed86c9d6e09e77a46fb87a8a0efd4aa5d36 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:09:28 +0000 Subject: [PATCH 11/46] clenaup --- program/src/initialize.rs | 68 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/program/src/initialize.rs b/program/src/initialize.rs index b17a8eb..99bc7d1 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -23,49 +23,49 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR }; signer_info.is_signer()?.has_address(&INITIALIZER_ADDRESS)?; bus_0_info - .has_seeds(&[BUS, &[0]], args.bus_0_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[0]], args.bus_0_bump, &ore_api::ID)?; bus_1_info - .has_seeds(&[BUS, &[1]], args.bus_1_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[1]], args.bus_1_bump, &ore_api::ID)?; bus_2_info - .has_seeds(&[BUS, &[2]], args.bus_2_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[2]], args.bus_2_bump, &ore_api::ID)?; bus_3_info - .has_seeds(&[BUS, &[3]], args.bus_3_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[3]], args.bus_3_bump, &ore_api::ID)?; bus_4_info - .has_seeds(&[BUS, &[4]], args.bus_4_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[4]], args.bus_4_bump, &ore_api::ID)?; bus_5_info - .has_seeds(&[BUS, &[5]], args.bus_5_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[5]], args.bus_5_bump, &ore_api::ID)?; bus_6_info - .has_seeds(&[BUS, &[6]], args.bus_6_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[6]], args.bus_6_bump, &ore_api::ID)?; bus_7_info - .has_seeds(&[BUS, &[7]], args.bus_7_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[BUS, &[7]], args.bus_7_bump, &ore_api::ID)?; config_info - .has_seeds(&[CONFIG], args.config_bump, &ore_api::ID)? - .is_empty()?; - metadata_info - .has_seeds( - &[ - METADATA, - mpl_token_metadata::ID.as_ref(), - MINT_ADDRESS.as_ref(), - ], - args.metadata_bump, - &mpl_token_metadata::ID, - )? - .is_empty()?; - mint_info - .has_seeds(&[MINT, MINT_NOISE.as_slice()], args.mint_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[CONFIG], args.config_bump, &ore_api::ID)?; + metadata_info.is_empty()?.has_seeds( + &[ + METADATA, + mpl_token_metadata::ID.as_ref(), + MINT_ADDRESS.as_ref(), + ], + args.metadata_bump, + &mpl_token_metadata::ID, + )?; + mint_info.is_empty()?.has_seeds( + &[MINT, MINT_NOISE.as_slice()], + args.mint_bump, + &ore_api::ID, + )?; treasury_info - .has_seeds(&[TREASURY], args.treasury_bump, &ore_api::ID)? - .is_empty()?; + .is_empty()? + .has_seeds(&[TREASURY], args.treasury_bump, &ore_api::ID)?; treasury_tokens_info.is_empty()?; system_program.is_program(&system_program::ID)?; token_program.is_program(&spl_token::ID)?; From 1448e2b793033229131003047f74fca8febd474b Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:14:23 +0000 Subject: [PATCH 12/46] cleanup --- program/src/initialize.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 99bc7d1..48ed85f 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -24,32 +24,41 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR signer_info.is_signer()?.has_address(&INITIALIZER_ADDRESS)?; bus_0_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[0]], args.bus_0_bump, &ore_api::ID)?; bus_1_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[1]], args.bus_1_bump, &ore_api::ID)?; bus_2_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[2]], args.bus_2_bump, &ore_api::ID)?; bus_3_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[3]], args.bus_3_bump, &ore_api::ID)?; bus_4_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[4]], args.bus_4_bump, &ore_api::ID)?; bus_5_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[5]], args.bus_5_bump, &ore_api::ID)?; bus_6_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[6]], args.bus_6_bump, &ore_api::ID)?; bus_7_info .is_empty()? + .is_writable()? .has_seeds(&[BUS, &[7]], args.bus_7_bump, &ore_api::ID)?; config_info .is_empty()? + .is_writable()? .has_seeds(&[CONFIG], args.config_bump, &ore_api::ID)?; - metadata_info.is_empty()?.has_seeds( + metadata_info.is_empty()?.is_writable()?.has_seeds( &[ METADATA, mpl_token_metadata::ID.as_ref(), @@ -58,15 +67,17 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR args.metadata_bump, &mpl_token_metadata::ID, )?; - mint_info.is_empty()?.has_seeds( + mint_info.is_empty()?.is_writable()?.has_seeds( &[MINT, MINT_NOISE.as_slice()], args.mint_bump, &ore_api::ID, )?; - treasury_info - .is_empty()? - .has_seeds(&[TREASURY], args.treasury_bump, &ore_api::ID)?; - treasury_tokens_info.is_empty()?; + treasury_info.is_empty()?.is_writable()?.has_seeds( + &[TREASURY], + args.treasury_bump, + &ore_api::ID, + )?; + treasury_tokens_info.is_empty()?.is_writable()?; system_program.is_program(&system_program::ID)?; token_program.is_program(&spl_token::ID)?; associated_token_program.is_program(&spl_associated_token_account::ID)?; From 79e1c5fbdbb851fe2c2599cfcfad13975407d479 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:25:46 +0000 Subject: [PATCH 13/46] cleanup entrypoint --- program/src/lib.rs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/program/src/lib.rs b/program/src/lib.rs index 0bb046f..1523004 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -19,27 +19,16 @@ use update::*; use upgrade::*; use ore_api::instruction::*; -use solana_program::{ - self, account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - pubkey::Pubkey, -}; - -solana_program::entrypoint!(process_instruction); +use steel::*; pub fn process_instruction( program_id: &Pubkey, accounts: &[AccountInfo], data: &[u8], ) -> ProgramResult { - if program_id.ne(&ore_api::id()) { - return Err(ProgramError::IncorrectProgramId); - } + let (ix, data) = parse_instruction(&ore_api::ID, program_id, data)?; - let (tag, data) = data - .split_first() - .ok_or(ProgramError::InvalidInstructionData)?; - - match OreInstruction::try_from(*tag).or(Err(ProgramError::InvalidInstructionData))? { + match ix { OreInstruction::Claim => process_claim(accounts, data)?, OreInstruction::Close => process_close(accounts, data)?, OreInstruction::Mine => process_mine(accounts, data)?, @@ -53,3 +42,5 @@ pub fn process_instruction( Ok(()) } + +entrypoint!(process_instruction); From 4f35fb23c6fcba5f387a30ed990cef23c24f4e32 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:31:51 +0000 Subject: [PATCH 14/46] cleanup loaders --- program/src/open.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/program/src/open.rs b/program/src/open.rs index 94c7dec..93df2ad 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -22,10 +22,11 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult }; signer_info.is_signer()?; payer_info.is_signer()?; - proof_info - .has_seeds(&[PROOF, signer_info.key.as_ref()], args.bump, &ore_api::ID)? - .is_empty()? - .is_writable()?; + proof_info.is_empty()?.is_writable()?.has_seeds( + &[PROOF, signer_info.key.as_ref()], + args.bump, + &ore_api::ID, + )?; system_program.is_program(&system_program::ID)?; slot_hashes_info.is_sysvar(&sysvar::slot_hashes::ID)?; From 8b095c23363b0b9bf7a4158e7926cf897883e55d Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:41:48 +0000 Subject: [PATCH 15/46] account validation checks --- program/src/mine.rs | 5 ++++- program/src/reset.rs | 4 +++- program/src/upgrade.rs | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 1cdadb7..14683a1 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -6,6 +6,7 @@ use ore_api::{ error::OreError, event::MineEvent, instruction::Mine, + loaders::OreAccountInfoValidation, state::{Bus, Config, Proof}, }; use solana_program::program::set_return_data; @@ -32,7 +33,9 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { }; signer_info.is_signer()?; let bus = bus_info.to_account_mut::(&ore_api::ID)?; - let config = config_info.to_account::(&ore_api::ID)?; + let config = config_info + .is_config()? + .to_account::(&ore_api::ID)?; let proof = proof_info .to_account_mut::(&ore_api::ID)? .check_mut(|p| p.miner == *signer_info.key)?; diff --git a/program/src/reset.rs b/program/src/reset.rs index 2800139..6625f6d 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -39,7 +39,9 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul let bus_7 = bus_7_info .to_account_mut::(&ore_api::ID)? .check_mut(|b| b.id == 7)?; - let config = config_info.to_account_mut::(&ore_api::ID)?; + let config = config_info + .is_config()? + .to_account_mut::(&ore_api::ID)?; let mint = mint_info .has_address(&MINT_ADDRESS)? .is_writable()? diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index 058c400..140a499 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -1,4 +1,4 @@ -use ore_api::{consts::*, error::OreError, instruction::Stake}; +use ore_api::{consts::*, error::OreError, instruction::Stake, loaders::OreAccountInfoValidation}; use steel::*; /// Upgrade allows a user to migrate a v1 token to a v2 token at a 1:1 exchange rate. @@ -32,6 +32,7 @@ pub fn process_upgrade(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResu .to_token_account()? .check(|t| t.owner == *signer_info.key)? .check(|t| t.mint == MINT_V1_ADDRESS)?; + treasury_info.is_treasury()?; token_program.is_program(&spl_token::ID)?; // Burn v1 tokens From 466d69676597847e4fa3ec1b4e5d37bc90f5f2a7 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:45:00 +0000 Subject: [PATCH 16/46] account checks --- program/src/stake.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/src/stake.rs b/program/src/stake.rs index 1e495dd..ecddd0c 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -19,8 +19,8 @@ pub fn process_stake(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult sender_info .is_writable()? .to_token_account()? - .check(|t| t.owner.eq(signer_info.key))? - .check(|t| t.mint.eq(&MINT_ADDRESS))?; + .check(|t| t.owner == *signer_info.key)? + .check(|t| t.mint == MINT_ADDRESS)?; treasury_tokens_info.is_writable()?.is_treasury_tokens()?; token_program.is_program(&spl_token::ID)?; From ec505541b1280cfa0d02e42a329a42a1adae30f8 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 07:59:17 +0000 Subject: [PATCH 17/46] cleanup --- program/src/close.rs | 1 - program/src/initialize.rs | 5 +---- program/src/mine.rs | 3 +-- program/src/open.rs | 9 ++------- program/src/reset.rs | 2 +- program/src/stake.rs | 2 +- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/program/src/close.rs b/program/src/close.rs index 4be47c0..8e7b85d 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -1,5 +1,4 @@ use ore_api::state::Proof; -use solana_program::system_program; use steel::*; /// Close closes a proof account and returns the rent to the owner. diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 48ed85f..298e5c0 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -3,10 +3,7 @@ use ore_api::{ instruction::*, state::{Bus, Config, Treasury}, }; -use solana_program::{ - self, account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - program_pack::Pack, system_program, sysvar, -}; +use solana_program::program_pack::Pack; use spl_token::state::Mint; use steel::*; diff --git a/program/src/mine.rs b/program/src/mine.rs index 14683a1..655bb2d 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -16,7 +16,6 @@ use solana_program::{ sanitize::SanitizeError, serialize_utils::{read_pubkey, read_u16}, slot_hashes::SlotHash, - sysvar::{self, Sysvar}, }; use steel::*; @@ -51,7 +50,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Validate epoch is active. // let config_data = config_info.data.borrow(); // let config = Config::try_from_bytes(&config_data)?; - let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; + let clock = Clock::get()?; if config .last_reset_at .saturating_add(EPOCH_DURATION) diff --git a/program/src/open.rs b/program/src/open.rs index 93df2ad..2e82bd0 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -1,12 +1,7 @@ use std::mem::size_of; use ore_api::{consts::*, instruction::Open, state::Proof}; -use solana_program::{ - keccak::hashv, - slot_hashes::SlotHash, - system_program, - sysvar::{self, Sysvar}, -}; +use solana_program::{keccak::hashv, slot_hashes::SlotHash}; use steel::*; /// Open creates a new proof account to track a miner's state. @@ -38,7 +33,7 @@ pub fn process_open(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult system_program, payer_info, )?; - let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; + let clock = Clock::get()?; let proof = proof_info.to_account_mut::(&ore_api::ID)?; proof.authority = *signer_info.key; proof.balance = 0; diff --git a/program/src/reset.rs b/program/src/reset.rs index 6625f6d..e59d7f3 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -53,7 +53,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul // Validate enough time has passed since the last reset. // let mut config_data = config_info.data.borrow_mut(); // let config = Config::try_from_bytes_mut(&mut config_data)?; - let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; + let clock = Clock::get()?; if config .last_reset_at .saturating_add(EPOCH_DURATION) diff --git a/program/src/stake.rs b/program/src/stake.rs index ecddd0c..48ba171 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -28,7 +28,7 @@ pub fn process_stake(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult proof.balance = proof.balance.checked_add(amount).unwrap(); // Update deposit timestamp. - let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; + let clock = Clock::get()?; proof.last_stake_at = clock.unix_timestamp; // Transfer tokens from signer to treasury. From 6cb5f18628ca837803d112cce41b22c825ab27d5 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 08:05:48 +0000 Subject: [PATCH 18/46] cleanup imports --- api/src/instruction.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 923b2c5..141df9a 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -1,5 +1,3 @@ -use bytemuck::{Pod, Zeroable}; -use num_enum::TryFromPrimitive; use steel::*; #[repr(u8)] From f0b0274372fa75624ef1f2a383094c219a66b842 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 08:10:46 +0000 Subject: [PATCH 19/46] cleanup imports --- api/src/sdk.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/sdk.rs b/api/src/sdk.rs index e6ccd5d..0c5d797 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -1,5 +1,4 @@ use drillx::Solution; -use solana_program::{system_program, sysvar}; use steel::*; use crate::{ From 13bd94df90181d918513779caa5a58d6fb095cfb Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 27 Sep 2024 08:15:05 +0000 Subject: [PATCH 20/46] ore_api prelude module --- api/src/lib.rs | 12 +++++++++++- program/src/claim.rs | 2 +- program/src/close.rs | 2 +- program/src/initialize.rs | 6 +----- program/src/mine.rs | 9 +-------- program/src/open.rs | 2 +- program/src/reset.rs | 7 +------ program/src/stake.rs | 2 +- program/src/update.rs | 2 +- program/src/upgrade.rs | 2 +- 10 files changed, 20 insertions(+), 26 deletions(-) diff --git a/api/src/lib.rs b/api/src/lib.rs index 75b6aba..c0e78a6 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -6,6 +6,16 @@ pub mod loaders; pub mod sdk; pub mod state; -use solana_program::declare_id; +pub mod prelude { + pub use crate::consts::*; + pub use crate::error::*; + pub use crate::event::*; + pub use crate::instruction::*; + pub use crate::loaders::*; + pub use crate::sdk::*; + pub use crate::state::*; +} + +use steel::*; declare_id!("oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ"); diff --git a/program/src/claim.rs b/program/src/claim.rs index 7fa8c48..c4a9201 100644 --- a/program/src/claim.rs +++ b/program/src/claim.rs @@ -1,4 +1,4 @@ -use ore_api::{consts::*, error::OreError, instruction::*, loaders::*, state::Proof}; +use ore_api::prelude::*; use steel::*; /// Claim distributes claimable ORE from the treasury to a miner. diff --git a/program/src/close.rs b/program/src/close.rs index 8e7b85d..dd58ead 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -1,4 +1,4 @@ -use ore_api::state::Proof; +use ore_api::prelude::*; use steel::*; /// Close closes a proof account and returns the rent to the owner. diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 298e5c0..23cc57e 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -1,8 +1,4 @@ -use ore_api::{ - consts::*, - instruction::*, - state::{Bus, Config, Treasury}, -}; +use ore_api::prelude::*; use solana_program::program_pack::Pack; use spl_token::state::Mint; use steel::*; diff --git a/program/src/mine.rs b/program/src/mine.rs index 655bb2d..eb8e37b 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -1,14 +1,7 @@ use std::mem::size_of; use drillx::Solution; -use ore_api::{ - consts::*, - error::OreError, - event::MineEvent, - instruction::Mine, - loaders::OreAccountInfoValidation, - state::{Bus, Config, Proof}, -}; +use ore_api::prelude::*; use solana_program::program::set_return_data; #[allow(deprecated)] use solana_program::{ diff --git a/program/src/open.rs b/program/src/open.rs index 2e82bd0..bc9c9f3 100644 --- a/program/src/open.rs +++ b/program/src/open.rs @@ -1,6 +1,6 @@ use std::mem::size_of; -use ore_api::{consts::*, instruction::Open, state::Proof}; +use ore_api::prelude::*; use solana_program::{keccak::hashv, slot_hashes::SlotHash}; use steel::*; diff --git a/program/src/reset.rs b/program/src/reset.rs index e59d7f3..b00a6ba 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -1,9 +1,4 @@ -use ore_api::{ - consts::*, - error::OreError, - loaders::*, - state::{Bus, Config}, -}; +use ore_api::prelude::*; use steel::*; /// Reset tops up the bus balances, updates the base reward rate, and sets up the ORE program for the next epoch. diff --git a/program/src/stake.rs b/program/src/stake.rs index 48ba171..7a42d80 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -1,4 +1,4 @@ -use ore_api::{consts::*, instruction::Stake, loaders::*, state::Proof}; +use ore_api::prelude::*; use steel::*; /// Stake deposits ORE into a proof account to earn multiplier. diff --git a/program/src/update.rs b/program/src/update.rs index 6bf6f74..4f153a6 100644 --- a/program/src/update.rs +++ b/program/src/update.rs @@ -1,4 +1,4 @@ -use ore_api::state::Proof; +use ore_api::prelude::*; use steel::*; /// Update changes the miner authority on a proof account. diff --git a/program/src/upgrade.rs b/program/src/upgrade.rs index 140a499..74090d0 100644 --- a/program/src/upgrade.rs +++ b/program/src/upgrade.rs @@ -1,4 +1,4 @@ -use ore_api::{consts::*, error::OreError, instruction::Stake, loaders::OreAccountInfoValidation}; +use ore_api::prelude::*; use steel::*; /// Upgrade allows a user to migrate a v1 token to a v2 token at a 1:1 exchange rate. From 21862a31425e2a09b6b32325f135c1c559fda50e Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sun, 29 Sep 2024 08:40:41 +0000 Subject: [PATCH 21/46] id style --- Cargo.lock | 2 +- program/src/initialize.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ee7aae..e81be82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,7 +2211,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "steel" -version = "1.2.0" +version = "1.3.0" dependencies = [ "bytemuck", "num_enum", diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 23cc57e..4d7d8b3 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -95,7 +95,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR for i in 0..BUS_COUNT { create_account::( bus_infos[i], - &ore_api::id(), + &ore_api::ID, &[BUS, &[i as u8], &[bus_bumps[i]]], system_program, signer_info, @@ -110,7 +110,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR // Initialize config. create_account::( config_info, - &ore_api::id(), + &ore_api::ID, &[CONFIG, &[args.config_bump]], system_program, signer_info, @@ -124,7 +124,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR // Initialize treasury. create_account::( treasury_info, - &ore_api::id(), + &ore_api::ID, &[TREASURY, &[args.treasury_bump]], system_program, signer_info, @@ -133,7 +133,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR // Initialize mint. allocate_account( mint_info, - &spl_token::id(), + &spl_token::ID, Mint::LEN, &[MINT, MINT_NOISE.as_slice(), &[args.mint_bump]], system_program, @@ -141,7 +141,7 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramR )?; solana_program::program::invoke_signed( &spl_token::instruction::initialize_mint( - &spl_token::id(), + &spl_token::ID, mint_info.key, treasury_info.key, None, From 021140cb637712462f64e70c09147af2fb361947 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Mon, 7 Oct 2024 16:53:05 +0000 Subject: [PATCH 22/46] remove patch --- Cargo.lock | 2 ++ Cargo.toml | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e81be82..96cbe96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2212,6 +2212,8 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "steel" version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88c610ca9fd5e4e51bdb6e9964114133a42f006713fe38aff37266fac91e1be" dependencies = [ "bytemuck", "num_enum", diff --git a/Cargo.toml b/Cargo.toml index 7ea337d..d77adcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,3 @@ spl-associated-token-account = { version = "^2.3", features = [ "no-entrypoint" static_assertions = "1.1.0" steel = { features = ["spl"], version = "1.0" } thiserror = "1.0.57" - - -[patch.crates-io] -steel = { path = "../steel/lib" } From 1cc3d9c20292c2fe4e73911064ee93a56539ac3c Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sat, 24 Aug 2024 13:57:00 +0000 Subject: [PATCH 23/46] scaffolding boosts --- Cargo.lock | 339 ++++++++++++++++++++++---------------------- Cargo.toml | 1 + api/src/event.rs | 8 ++ program/Cargo.toml | 1 + program/src/mine.rs | 57 +++++++- 5 files changed, 237 insertions(+), 169 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96cbe96..e6baaec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "ark-bn254" @@ -201,15 +201,15 @@ checksum = "8bcb85e548c05d407fa6faff46b750ba287714ef32afc0f5e15b4641ffd6affb" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert_matches" @@ -230,9 +230,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base64" @@ -339,11 +339,11 @@ dependencies = [ [[package]] name = "borsh" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" dependencies = [ - "borsh-derive 0.10.3", + "borsh-derive 0.10.4", "hashbrown 0.13.2", ] @@ -372,12 +372,12 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" dependencies = [ - "borsh-derive-internal 0.10.3", - "borsh-schema-derive-internal 0.10.3", + "borsh-derive-internal 0.10.4", + "borsh-schema-derive-internal 0.10.4", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", @@ -390,10 +390,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", "syn_derive", ] @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "borsh-derive-internal" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" dependencies = [ "proc-macro2", "quote", @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "borsh-schema-derive-internal" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" dependencies = [ "proc-macro2", "quote", @@ -465,22 +465,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.16.3" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -491,12 +491,13 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.1.7" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -561,15 +562,15 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -669,7 +670,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -680,7 +681,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -722,9 +723,9 @@ dependencies = [ [[package]] name = "drillx" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c5fd3a8f11a6420d6efb1952c8c2e788627cb2c9e834537dc4b6bd036461646" +checksum = "9f1b6097a8aeb360dc83cad60047b42cfabf54a56b81a75e254f5854211a7475" dependencies = [ "equix", "serde", @@ -822,9 +823,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "equix" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced5aa2974d730a3bbe65dcb62ad8fbb0ae44d4aeed1093808a855d922b931ee" +checksum = "b3e45c3367b4177f7b3512daf285f19cb3f0eed6d4c1e5d9bc37e4c1026c5644" dependencies = [ "arrayvec", "hashx", @@ -908,9 +909,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hashx" @@ -1008,12 +1009,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", ] [[package]] @@ -1042,9 +1043,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -1072,9 +1073,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libsecp256k1" @@ -1194,7 +1195,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caf0f61b553e424a6234af1268456972ee66c2222e1da89079242251fa7479e5" dependencies = [ - "borsh 0.10.3", + "borsh 0.10.4", "num-derive 0.3.3", "num-traits", "solana-program", @@ -1230,7 +1231,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1266,17 +1267,17 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -1302,6 +1303,22 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ore-boost-api" +version = "0.1.0" +dependencies = [ + "array-const-fn-init", + "bytemuck", + "const-crypto", + "num_enum", + "solana-program", + "spl-associated-token-account", + "spl-token", + "static_assertions", + "steel", + "thiserror", +] + [[package]] name = "ore-program" version = "2.1.9" @@ -1309,6 +1326,7 @@ dependencies = [ "drillx", "mpl-token-metadata", "ore-api", + "ore-boost-api", "rand 0.8.5", "solana-program", "spl-associated-token-account", @@ -1383,11 +1401,11 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy 0.6.6", + "zerocopy", ] [[package]] @@ -1401,9 +1419,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ "toml_edit", ] @@ -1434,9 +1452,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -1458,14 +1476,14 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1572,18 +1590,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1593,9 +1611,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1604,9 +1622,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-hash" @@ -1616,9 +1634,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -1649,9 +1667,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1667,20 +1685,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -1707,7 +1725,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1762,6 +1780,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signature" version = "1.6.4" @@ -1792,9 +1816,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "solana-frozen-abi" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0c52f25d28a1b5af57d5de3802e49883f68792a343101a9daf9817d8dfffff" +checksum = "45478bad85abd8cc291775463e15bc1031fdbf973d48e2568e8defee3d842a3a" dependencies = [ "block-buffer 0.10.4", "bs58", @@ -1817,21 +1841,21 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7d0abca44a21c83305e8650341f67ccc919a1a9dd698ddafc86e78b74b9296" +checksum = "c5cb05f9051446226cd26ea17f6fbe5e28e922ad6a846166db7fb17865090fcb" dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "solana-logger" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5bc0644a410b8bff84ad18541a176f27776062b1ad116cb315c6f5f14b94fed" +checksum = "4cbcde62a32962c3f80aebe0047476dcb2b693b5d47110071af0d23561c3aa0c" dependencies = [ "env_logger", "lazy_static", @@ -1840,9 +1864,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a99c3bc26fda40f42db98494271bda4906b0d7ab55f3ea7755fa5f110f58b5" +checksum = "a52f4c424433a18b57ae88a35b677c548879a9c4ca1e27e108d1597ff12b95ac" dependencies = [ "ark-bn254", "ark-ec", @@ -1852,7 +1876,7 @@ dependencies = [ "bincode", "bitflags 2.6.0", "blake3", - "borsh 0.10.3", + "borsh 0.10.4", "borsh 0.9.3", "borsh 1.5.1", "bs58", @@ -1895,9 +1919,9 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a8affb5b3acd43f7164368b88243bf091e46eccff9bea5b743e4691d7c2600" +checksum = "02bfb6b467e755620f4d3f8eefd1e5bdfb812ec7076d237e0280d7c988f16f02" dependencies = [ "assert_matches", "base64 0.21.7", @@ -1950,15 +1974,15 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2ac8d7ef471476164edb2ed105bcf26071835a15f0e74703929d4ec913676b" +checksum = "9ed90de8086a0e114ab63454a9d066e0f08eb2c9c8aea149ff60e8a492f165fc" dependencies = [ "bs58", "proc-macro2", "quote", "rustversion", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1969,9 +1993,9 @@ checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" [[package]] name = "solana-zk-token-sdk" -version = "1.18.20" +version = "1.18.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf73fd7e430bf3269539c2fb1d05af0df26fc3b7bc090172ceda5cd4340657c" +checksum = "7569e85e3b1c8abc089ec06153b4ded577bc94bf383f607d5017082497f53665" dependencies = [ "aes-gcm-siv", "base64 0.21.7", @@ -2003,7 +2027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" dependencies = [ "assert_matches", - "borsh 0.10.3", + "borsh 0.10.4", "num-derive 0.4.2", "num-traits", "solana-program", @@ -2031,7 +2055,7 @@ checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2043,7 +2067,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.72", + "syn 2.0.79", "thiserror", ] @@ -2062,7 +2086,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" dependencies = [ - "borsh 0.10.3", + "borsh 0.10.4", "bytemuck", "solana-program", "solana-zk-token-sdk", @@ -2091,7 +2115,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2166,7 +2190,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" dependencies = [ - "borsh 0.10.3", + "borsh 0.10.4", "solana-program", "spl-discriminator", "spl-pod", @@ -2248,7 +2272,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2270,9 +2294,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -2288,7 +2312,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2302,22 +2326,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2371,9 +2395,9 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "toml_datetime", @@ -2388,15 +2412,15 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -2429,13 +2453,13 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "visibility" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3fd98999db9227cf28e59d83e1f120f42bc233d4b152e8fab9bc87d5bb1e0f8" +checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2452,34 +2476,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2487,28 +2512,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -2532,9 +2557,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys", ] @@ -2547,9 +2572,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] @@ -2620,41 +2645,21 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] -[[package]] -name = "zerocopy" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" -dependencies = [ - "byteorder", - "zerocopy-derive 0.6.6", -] - [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy-derive" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", + "byteorder", + "zerocopy-derive", ] [[package]] @@ -2665,7 +2670,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2685,5 +2690,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] diff --git a/Cargo.toml b/Cargo.toml index d77adcd..060e836 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ drillx = { version = "2.0.0", features = ["solana"] } mpl-token-metadata = "4.1.2" num_enum = "0.7.2" ore-api = { path = "api", version = "2.1.9" } +ore-boost-api = { path = "../ore-boost/api", version = "0.1.0" } solana-program = "^1.18" spl-token = { version = "^4", features = ["no-entrypoint"] } spl-associated-token-account = { version = "^2.3", features = [ "no-entrypoint" ] } diff --git a/api/src/event.rs b/api/src/event.rs index 28b266d..3dbb467 100644 --- a/api/src/event.rs +++ b/api/src/event.rs @@ -8,4 +8,12 @@ pub struct MineEvent { pub timing: i64, } +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] +pub struct BoostEvent { + pub mint: Pubkey, + pub reward: u64, +} + event!(MineEvent); +event!(BoostEvent); diff --git a/program/Cargo.toml b/program/Cargo.toml index 1bf4718..0118d8d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -21,6 +21,7 @@ default = [] drillx.workspace = true mpl-token-metadata.workspace = true ore-api.workspace = true +ore-boost-api.workspace = true solana-program.workspace = true spl-token.workspace = true spl-associated-token-account.workspace = true diff --git a/program/src/mine.rs b/program/src/mine.rs index eb8e37b..2c2cd6d 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -2,7 +2,7 @@ use std::mem::size_of; use drillx::Solution; use ore_api::prelude::*; -use solana_program::program::set_return_data; +use ore_boost_api::state::{Boost, Stake}; #[allow(deprecated)] use solana_program::{ keccak::hashv, @@ -10,6 +10,10 @@ use solana_program::{ serialize_utils::{read_pubkey, read_u16}, slot_hashes::SlotHash, }; +use solana_program::{ + log::{sol_log, sol_log_data}, + program::set_return_data, +}; use steel::*; /// Mine validates hashes and increments a miner's collectable balance. @@ -18,8 +22,9 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { let args = Mine::try_from_bytes(data)?; // Load accounts. + let (required_accounts, optional_accounts) = accounts.split_at(6); let [signer_info, bus_info, config_info, proof_info, instructions_sysvar, slot_hashes_sysvar] = - accounts + required_accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; @@ -120,6 +125,54 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { } } + // Apply boosts. + // + // Boosts are incentives that can multiply a miner's rewards by staking tokens in the ORE Boosts program. + // Up to 3 boosts can be applied on any given mine operation. + sol_log(&format!("Base: {}", reward)); + let mut applied_boosts = [Pubkey::new_from_array([0; 32]); 3]; + sol_log(optional_accounts.len().to_string().as_str()); + for i in 0..3 { + sol_log(i.to_string().as_str()); + if optional_accounts.len().gt(&(i * 2)) { + sol_log("booooost"); + // Load optional accounts. + let boost_info = optional_accounts[i * 2].clone(); + let stake_info = optional_accounts[i * 2 + 1].clone(); + let boost = boost_info.to_account::(&ore_boost_api::ID)?; + let stake = stake_info + .to_account::(&ore_boost_api::ID)? + .check(|s| s.authority == proof.authority)? + .check(|s| s.boost == *boost_info.key)?; + + // Skip if boost is applied twice. + if applied_boosts.contains(boost_info.key) { + continue; + } + + // Record this boost has been used. + applied_boosts[i] = *boost_info.key; + + // Apply multiplier if boost is not expired and last stake at was more than one minute ago. + if boost.expires_at.gt(&t) && stake.last_stake_at.saturating_add(ONE_MINUTE).le(&t) { + let multiplier = boost.multiplier.checked_sub(1).unwrap(); + let boost_reward = (reward as u128) + .checked_mul(multiplier as u128) + .unwrap() + .checked_mul(stake.balance as u128) + .unwrap() + .checked_div(boost.total_stake as u128) + .unwrap() as u64; + reward = reward.checked_add(boost_reward).unwrap(); + sol_log_data(&[(BoostEvent { + mint: boost.mint, + reward: boost_reward, + }) + .to_bytes()]); + } + } + } + // Apply liveness penalty. // // The liveness penalty exists to ensure there is no "invisible" hashpower on the network. It From 31fa660f6de6d271695ba3207898b426a13ab2bf Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sun, 25 Aug 2024 12:01:53 +0000 Subject: [PATCH 24/46] reset update --- program/src/reset.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/src/reset.rs b/program/src/reset.rs index b00a6ba..dd3db79 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -67,9 +67,9 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul let mut top_balance = 0u64; for bus in busses { // Track top balance. - if bus.top_balance.gt(&top_balance) { - top_balance = bus.top_balance; - } + // if bus.top_balance.gt(&top_balance) { + // top_balance = bus.top_balance; + // } // Track accumulators. total_remaining_rewards = total_remaining_rewards.saturating_add(bus.rewards); From 862c639343b57452316dd1b4b78d7d0e88f19bff Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sun, 25 Aug 2024 12:32:26 +0000 Subject: [PATCH 25/46] update boosts --- program/src/mine.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 2c2cd6d..65d71c9 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -101,7 +101,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); - // Apply staking multiplier. + // Apply boosts. // // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active @@ -205,6 +205,8 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // // Busses are limited to distributing 1 ORE per epoch. This is also the maximum amount that will be paid out // for any given hash. + let mut bus_data = bus_info.data.borrow_mut(); + let bus = Bus::try_from_bytes_mut(&mut bus_data)?; let reward_actual = reward.min(bus.rewards).min(ONE_ORE); // Update balances. From 21041c7a8ba1523a9bba47eef25ea2c2e15deb93 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sun, 25 Aug 2024 12:44:19 +0000 Subject: [PATCH 26/46] todo --- program/src/mine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 65d71c9..91090bc 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -135,7 +135,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { for i in 0..3 { sol_log(i.to_string().as_str()); if optional_accounts.len().gt(&(i * 2)) { - sol_log("booooost"); // Load optional accounts. let boost_info = optional_accounts[i * 2].clone(); let stake_info = optional_accounts[i * 2 + 1].clone(); From d3fb384eaeb67616e5930aadc139a0f151e9c5b7 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Mon, 26 Aug 2024 21:58:42 +0000 Subject: [PATCH 27/46] implement three boost system --- api/src/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/src/error.rs b/api/src/error.rs index 33fdb75..a020481 100644 --- a/api/src/error.rs +++ b/api/src/error.rs @@ -19,6 +19,8 @@ pub enum OreError { MaxSupply = 6, #[error("The proof does not match the expected account")] AuthFailed = 7, + #[error("The same boost cannot be applied twice")] + DuplicateBoost = 8, } error!(OreError); From 7ddcf82ae62482faeba8c56f48f1a409a2550907 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 27 Aug 2024 15:02:13 +0000 Subject: [PATCH 28/46] comment out unused var --- program/src/reset.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/src/reset.rs b/program/src/reset.rs index dd3db79..b00a6ba 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -67,9 +67,9 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul let mut top_balance = 0u64; for bus in busses { // Track top balance. - // if bus.top_balance.gt(&top_balance) { - // top_balance = bus.top_balance; - // } + if bus.top_balance.gt(&top_balance) { + top_balance = bus.top_balance; + } // Track accumulators. total_remaining_rewards = total_remaining_rewards.saturating_add(bus.rewards); From eb8ce05049ef9c3fb7e104669031f4b1d8fd00ad Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Wed, 28 Aug 2024 16:37:56 +0000 Subject: [PATCH 29/46] fix overflow issue --- program/src/mine.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 91090bc..e5e5dde 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -96,10 +96,11 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { let normalized_difficulty = difficulty .checked_sub(config.min_difficulty as u32) .unwrap(); - let mut reward = config + let base_reward = config .base_reward_rate .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); + let mut reward = base_reward; // Apply boosts. // @@ -155,7 +156,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Apply multiplier if boost is not expired and last stake at was more than one minute ago. if boost.expires_at.gt(&t) && stake.last_stake_at.saturating_add(ONE_MINUTE).le(&t) { let multiplier = boost.multiplier.checked_sub(1).unwrap(); - let boost_reward = (reward as u128) + let boost_reward = (base_reward as u128) .checked_mul(multiplier as u128) .unwrap() .checked_mul(stake.balance as u128) @@ -163,6 +164,8 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { .checked_div(boost.total_stake as u128) .unwrap() as u64; reward = reward.checked_add(boost_reward).unwrap(); + + // Log event sol_log_data(&[(BoostEvent { mint: boost.mint, reward: boost_reward, From e6f01e88bc9d28bc1b3f950dda579d328f27b60b Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 10 Sep 2024 05:01:08 +0000 Subject: [PATCH 30/46] boost expires at --- program/src/mine.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index e5e5dde..14b5f66 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -96,11 +96,10 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { let normalized_difficulty = difficulty .checked_sub(config.min_difficulty as u32) .unwrap(); - let base_reward = config + let mut reward = config .base_reward_rate .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); - let mut reward = base_reward; // Apply boosts. // @@ -156,7 +155,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Apply multiplier if boost is not expired and last stake at was more than one minute ago. if boost.expires_at.gt(&t) && stake.last_stake_at.saturating_add(ONE_MINUTE).le(&t) { let multiplier = boost.multiplier.checked_sub(1).unwrap(); - let boost_reward = (base_reward as u128) + let boost_reward = (reward as u128) .checked_mul(multiplier as u128) .unwrap() .checked_mul(stake.balance as u128) From 01e3f8f81e59c90e7d02cddff329ee2c9ec38d32 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 24 Sep 2024 05:28:14 +0000 Subject: [PATCH 31/46] reimplement staking multiplier --- program/src/mine.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/program/src/mine.rs b/program/src/mine.rs index 14b5f66..b201f66 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -101,6 +101,30 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); + // Apply staking multiplier. + // + // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. + // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active + // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. + let mut bus_data = bus_info.data.borrow_mut(); + let bus = Bus::try_from_bytes_mut(&mut bus_data)?; + if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { + // Calculate staking reward. + if config.top_balance.gt(&0) { + let staking_reward = (reward as u128) + .checked_mul(proof.balance.min(config.top_balance) as u128) + .unwrap() + .checked_div(config.top_balance as u128) + .unwrap() as u64; + reward = reward.checked_add(staking_reward).unwrap(); + } + + // Update bus stake tracker. + if proof.balance.gt(&bus.top_balance) { + bus.top_balance = proof.balance; + } + } + // Apply boosts. // // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. From 7d05132d9d7f7e80503c4d341d688732b5042c8d Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 24 Sep 2024 05:33:25 +0000 Subject: [PATCH 32/46] remove unneeded data borrow --- program/src/mine.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index b201f66..0c0968a 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -230,8 +230,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // // Busses are limited to distributing 1 ORE per epoch. This is also the maximum amount that will be paid out // for any given hash. - let mut bus_data = bus_info.data.borrow_mut(); - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; let reward_actual = reward.min(bus.rewards).min(ONE_ORE); // Update balances. From 0f6909454d47733fa379423f3bb6766d098fa9ff Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sat, 24 Aug 2024 13:57:00 +0000 Subject: [PATCH 33/46] scaffolding boosts --- program/src/mine.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 0c0968a..3184559 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -106,8 +106,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. - let mut bus_data = bus_info.data.borrow_mut(); - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { // Calculate staking reward. if config.top_balance.gt(&0) { From 5bfb62301131d0a10d55817ce92dd2458b097244 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sun, 25 Aug 2024 12:01:53 +0000 Subject: [PATCH 34/46] reset update --- program/src/reset.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/src/reset.rs b/program/src/reset.rs index b00a6ba..dd3db79 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -67,9 +67,9 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul let mut top_balance = 0u64; for bus in busses { // Track top balance. - if bus.top_balance.gt(&top_balance) { - top_balance = bus.top_balance; - } + // if bus.top_balance.gt(&top_balance) { + // top_balance = bus.top_balance; + // } // Track accumulators. total_remaining_rewards = total_remaining_rewards.saturating_add(bus.rewards); From b5f42e251aa2991e20dd5711eb8bb71c3b9e2823 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sun, 25 Aug 2024 12:32:26 +0000 Subject: [PATCH 35/46] update boosts --- program/src/mine.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 3184559..5c05b8a 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -101,7 +101,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); - // Apply staking multiplier. + // Apply boosts. // // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active @@ -228,6 +228,8 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // // Busses are limited to distributing 1 ORE per epoch. This is also the maximum amount that will be paid out // for any given hash. + let mut bus_data = bus_info.data.borrow_mut(); + let bus = Bus::try_from_bytes_mut(&mut bus_data)?; let reward_actual = reward.min(bus.rewards).min(ONE_ORE); // Update balances. From 1b30a0fd8dc8c33cc2f2713c4a4df26a7ecc90d1 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 27 Aug 2024 15:02:13 +0000 Subject: [PATCH 36/46] comment out unused var --- program/src/reset.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/src/reset.rs b/program/src/reset.rs index dd3db79..b00a6ba 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -67,9 +67,9 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul let mut top_balance = 0u64; for bus in busses { // Track top balance. - // if bus.top_balance.gt(&top_balance) { - // top_balance = bus.top_balance; - // } + if bus.top_balance.gt(&top_balance) { + top_balance = bus.top_balance; + } // Track accumulators. total_remaining_rewards = total_remaining_rewards.saturating_add(bus.rewards); From 1584fc5cbf985b77042913a62ee3029e09573080 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Wed, 28 Aug 2024 16:37:56 +0000 Subject: [PATCH 37/46] fix overflow issue --- program/src/mine.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 5c05b8a..849b27b 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -96,10 +96,11 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { let normalized_difficulty = difficulty .checked_sub(config.min_difficulty as u32) .unwrap(); - let mut reward = config + let base_reward = config .base_reward_rate .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); + let mut reward = base_reward; // Apply boosts. // @@ -177,7 +178,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Apply multiplier if boost is not expired and last stake at was more than one minute ago. if boost.expires_at.gt(&t) && stake.last_stake_at.saturating_add(ONE_MINUTE).le(&t) { let multiplier = boost.multiplier.checked_sub(1).unwrap(); - let boost_reward = (reward as u128) + let boost_reward = (base_reward as u128) .checked_mul(multiplier as u128) .unwrap() .checked_mul(stake.balance as u128) From b4fdfe1166763930d7838a34bdfef8f373f753ce Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 10 Sep 2024 05:01:08 +0000 Subject: [PATCH 38/46] boost expires at --- program/src/mine.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 849b27b..5c05b8a 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -96,11 +96,10 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { let normalized_difficulty = difficulty .checked_sub(config.min_difficulty as u32) .unwrap(); - let base_reward = config + let mut reward = config .base_reward_rate .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); - let mut reward = base_reward; // Apply boosts. // @@ -178,7 +177,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Apply multiplier if boost is not expired and last stake at was more than one minute ago. if boost.expires_at.gt(&t) && stake.last_stake_at.saturating_add(ONE_MINUTE).le(&t) { let multiplier = boost.multiplier.checked_sub(1).unwrap(); - let boost_reward = (base_reward as u128) + let boost_reward = (reward as u128) .checked_mul(multiplier as u128) .unwrap() .checked_mul(stake.balance as u128) From 74c8a1a073471bedc15f5508624f81f9b910eade Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 24 Sep 2024 05:28:14 +0000 Subject: [PATCH 39/46] reimplement staking multiplier --- program/src/mine.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/program/src/mine.rs b/program/src/mine.rs index 5c05b8a..c6a0907 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -101,6 +101,30 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { .checked_mul(2u64.checked_pow(normalized_difficulty).unwrap()) .unwrap(); + // Apply staking multiplier. + // + // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. + // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active + // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. + let mut bus_data = bus_info.data.borrow_mut(); + let bus = Bus::try_from_bytes_mut(&mut bus_data)?; + if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { + // Calculate staking reward. + if config.top_balance.gt(&0) { + let staking_reward = (reward as u128) + .checked_mul(proof.balance.min(config.top_balance) as u128) + .unwrap() + .checked_div(config.top_balance as u128) + .unwrap() as u64; + reward = reward.checked_add(staking_reward).unwrap(); + } + + // Update bus stake tracker. + if proof.balance.gt(&bus.top_balance) { + bus.top_balance = proof.balance; + } + } + // Apply boosts. // // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. From 85d9baf09764d999fc7a2de3bfdebceaafabdc36 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 24 Sep 2024 05:33:25 +0000 Subject: [PATCH 40/46] remove unneeded data borrow --- program/src/mine.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index c6a0907..665614e 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -252,8 +252,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // // Busses are limited to distributing 1 ORE per epoch. This is also the maximum amount that will be paid out // for any given hash. - let mut bus_data = bus_info.data.borrow_mut(); - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; let reward_actual = reward.min(bus.rewards).min(ONE_ORE); // Update balances. From 58e27c1274d2da221559a07603b3ded49404e170 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 24 Sep 2024 05:55:15 +0000 Subject: [PATCH 41/46] skip duplicate boost --- api/src/error.rs | 2 -- program/src/mine.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/api/src/error.rs b/api/src/error.rs index a020481..33fdb75 100644 --- a/api/src/error.rs +++ b/api/src/error.rs @@ -19,8 +19,6 @@ pub enum OreError { MaxSupply = 6, #[error("The proof does not match the expected account")] AuthFailed = 7, - #[error("The same boost cannot be applied twice")] - DuplicateBoost = 8, } error!(OreError); diff --git a/program/src/mine.rs b/program/src/mine.rs index 665614e..7e1ee25 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -106,8 +106,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. - let mut bus_data = bus_info.data.borrow_mut(); - let bus = Bus::try_from_bytes_mut(&mut bus_data)?; if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { // Calculate staking reward. if config.top_balance.gt(&0) { From 6ae1ac53b3d893884a219072e4d10edba6817e2f Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 23 Sep 2024 23:54:24 -0700 Subject: [PATCH 42/46] rebased --- program/src/mine.rs | 50 --------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 7e1ee25..2e4b1d0 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -46,8 +46,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { authenticate(&instructions_sysvar.data.borrow(), proof_info.key)?; // Validate epoch is active. - // let config_data = config_info.data.borrow(); - // let config = Config::try_from_bytes(&config_data)?; let clock = Clock::get()?; if config .last_reset_at @@ -61,8 +59,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // // Here we use drillx to validate the provided solution is a valid hash of the challenge. // If invalid, we return an error. - // let mut proof_data = proof_info.data.borrow_mut(); - // let proof = Proof::try_from_bytes_mut(&mut proof_data)?; let solution = Solution::new(args.digest, args.nonce); if !solution.is_valid(&proof.challenge) { return Err(OreError::HashInvalid.into()); @@ -123,52 +119,6 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { } } - // Apply boosts. - // - // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. - // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active - // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. - if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { - // Calculate staking reward. - if config.top_balance.gt(&0) { - let staking_reward = (reward as u128) - .checked_mul(proof.balance.min(config.top_balance) as u128) - .unwrap() - .checked_div(config.top_balance as u128) - .unwrap() as u64; - reward = reward.checked_add(staking_reward).unwrap(); - } - - // Update bus stake tracker. - if proof.balance.gt(&bus.top_balance) { - bus.top_balance = proof.balance; - } - } - - // Apply boosts. - // - // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. - // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active - // if the miner's last stake deposit was more than one minute ago to protect against flash loan attacks. - // let mut bus_data = bus_info.data.borrow_mut(); - // let bus = Bus::try_from_bytes_mut(&mut bus_data)?; - if proof.balance.gt(&0) && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { - // Calculate staking reward. - if config.top_balance.gt(&0) { - let staking_reward = (reward as u128) - .checked_mul(proof.balance.min(config.top_balance) as u128) - .unwrap() - .checked_div(config.top_balance as u128) - .unwrap() as u64; - reward = reward.checked_add(staking_reward).unwrap(); - } - - // Update bus stake tracker. - if proof.balance.gt(&bus.top_balance) { - bus.top_balance = proof.balance; - } - } - // Apply boosts. // // Boosts are incentives that can multiply a miner's rewards by staking tokens in the ORE Boosts program. From 49418e94c785b16e60bd277ce7fea8ecd44d934c Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Mon, 7 Oct 2024 16:46:37 +0000 Subject: [PATCH 43/46] add sdk --- api/src/sdk.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/api/src/sdk.rs b/api/src/sdk.rs index 0c5d797..8c9cb11 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -51,18 +51,29 @@ pub fn close(signer: Pubkey) -> Instruction { } /// Builds a mine instruction. -pub fn mine(signer: Pubkey, authority: Pubkey, bus: Pubkey, solution: Solution) -> Instruction { +pub fn mine( + signer: Pubkey, + authority: Pubkey, + bus: Pubkey, + solution: Solution, + boost_accounts: Vec, +) -> Instruction { let proof = proof_pda(authority).0; + let required_accounts = vec![ + AccountMeta::new(signer, true), + AccountMeta::new(bus, false), + AccountMeta::new_readonly(CONFIG_ADDRESS, false), + AccountMeta::new(proof, false), + AccountMeta::new_readonly(sysvar::instructions::id(), false), + AccountMeta::new_readonly(sysvar::slot_hashes::id(), false), + ]; + let optional_accounts = boost_accounts + .into_iter() + .map(|pk| AccountMeta::new_readonly(pk, false)) + .collect(); Instruction { program_id: crate::id(), - accounts: vec![ - AccountMeta::new(signer, true), - AccountMeta::new(bus, false), - AccountMeta::new_readonly(CONFIG_ADDRESS, false), - AccountMeta::new(proof, false), - AccountMeta::new_readonly(sysvar::instructions::id(), false), - AccountMeta::new_readonly(sysvar::slot_hashes::id(), false), - ], + accounts: [required_accounts, optional_accounts].concat(), data: Mine { digest: solution.d, nonce: solution.n, From f356139484f81ef6beb047173a8538d754c1d462 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Mon, 7 Oct 2024 18:55:44 +0000 Subject: [PATCH 44/46] id shortcut --- api/src/sdk.rs | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/api/src/sdk.rs b/api/src/sdk.rs index 8c9cb11..e9d20eb 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -20,14 +20,14 @@ pub fn auth(proof: Pubkey) -> Instruction { pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction { let proof = proof_pda(signer).0; Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(beneficiary, false), AccountMeta::new(proof, false), AccountMeta::new_readonly(TREASURY_ADDRESS, false), AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), - AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(spl_token::ID, false), ], data: Claim { amount: amount.to_le_bytes(), @@ -40,11 +40,11 @@ pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction { pub fn close(signer: Pubkey) -> Instruction { let proof = proof_pda(signer).0; Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(proof, false), - AccountMeta::new_readonly(solana_program::system_program::id(), false), + AccountMeta::new_readonly(solana_program::system_program::ID, false), ], data: Close {}.to_bytes(), } @@ -64,15 +64,15 @@ pub fn mine( AccountMeta::new(bus, false), AccountMeta::new_readonly(CONFIG_ADDRESS, false), AccountMeta::new(proof, false), - AccountMeta::new_readonly(sysvar::instructions::id(), false), - AccountMeta::new_readonly(sysvar::slot_hashes::id(), false), + AccountMeta::new_readonly(sysvar::instructions::ID, false), + AccountMeta::new_readonly(sysvar::slot_hashes::ID, false), ]; let optional_accounts = boost_accounts .into_iter() .map(|pk| AccountMeta::new_readonly(pk, false)) .collect(); Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: [required_accounts, optional_accounts].concat(), data: Mine { digest: solution.d, @@ -86,14 +86,14 @@ pub fn mine( pub fn open(signer: Pubkey, miner: Pubkey, payer: Pubkey) -> Instruction { let proof_pda = proof_pda(signer); Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new_readonly(miner, false), AccountMeta::new(payer, true), AccountMeta::new(proof_pda.0, false), - AccountMeta::new_readonly(solana_program::system_program::id(), false), - AccountMeta::new_readonly(sysvar::slot_hashes::id(), false), + AccountMeta::new_readonly(solana_program::system_program::ID, false), + AccountMeta::new_readonly(sysvar::slot_hashes::ID, false), ], data: Open { bump: proof_pda.1 }.to_bytes(), } @@ -102,7 +102,7 @@ pub fn open(signer: Pubkey, miner: Pubkey, payer: Pubkey) -> Instruction { /// Builds a reset instruction. pub fn reset(signer: Pubkey) -> Instruction { Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(BUS_ADDRESSES[0], false), @@ -117,7 +117,7 @@ pub fn reset(signer: Pubkey) -> Instruction { AccountMeta::new(MINT_ADDRESS, false), AccountMeta::new(TREASURY_ADDRESS, false), AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), - AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(spl_token::ID, false), ], data: Reset {}.to_bytes(), } @@ -127,13 +127,13 @@ pub fn reset(signer: Pubkey) -> Instruction { pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction { let proof = proof_pda(signer).0; Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(proof, false), AccountMeta::new(sender, false), AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), - AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(spl_token::ID, false), ], data: Stake { amount: amount.to_le_bytes(), @@ -146,7 +146,7 @@ pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction { pub fn update(signer: Pubkey, miner: Pubkey) -> Instruction { let proof = proof_pda(signer).0; Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new_readonly(miner, false), @@ -159,7 +159,7 @@ pub fn update(signer: Pubkey, miner: Pubkey) -> Instruction { // Build an upgrade instruction. pub fn upgrade(signer: Pubkey, beneficiary: Pubkey, sender: Pubkey, amount: u64) -> Instruction { Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(beneficiary, false), @@ -167,7 +167,7 @@ pub fn upgrade(signer: Pubkey, beneficiary: Pubkey, sender: Pubkey, amount: u64) AccountMeta::new(MINT_V1_ADDRESS, false), AccountMeta::new(sender, false), AccountMeta::new(TREASURY_ADDRESS, false), - AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(spl_token::ID, false), ], data: Upgrade { amount: amount.to_le_bytes(), @@ -189,7 +189,7 @@ pub fn initialize(signer: Pubkey) -> Instruction { bus_pda(7), ]; let config_pda = config_pda(); - let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::id()); + let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::ID); let treasury_pda = treasury_pda(); let metadata_pda = Pubkey::find_program_address( &[ @@ -200,7 +200,7 @@ pub fn initialize(signer: Pubkey) -> Instruction { &mpl_token_metadata::ID, ); Instruction { - program_id: crate::id(), + program_id: crate::ID, accounts: vec![ AccountMeta::new(signer, true), AccountMeta::new(bus_pdas[0].0, false), @@ -216,11 +216,11 @@ pub fn initialize(signer: Pubkey) -> Instruction { AccountMeta::new(mint_pda.0, false), AccountMeta::new(treasury_pda.0, false), AccountMeta::new(TREASURY_TOKENS_ADDRESS, false), - AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(spl_token::id(), false), - AccountMeta::new_readonly(spl_associated_token_account::id(), false), + AccountMeta::new_readonly(system_program::ID, false), + AccountMeta::new_readonly(spl_token::ID, false), + AccountMeta::new_readonly(spl_associated_token_account::ID, false), AccountMeta::new_readonly(mpl_token_metadata::ID, false), - AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(sysvar::rent::ID, false), ], data: Initialize { bus_0_bump: bus_pdas[0].1, From e873fbb0dd94af5fc202cbc2be315d8c4b06dc64 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Mon, 7 Oct 2024 20:10:08 +0000 Subject: [PATCH 45/46] fix total rewards calculus --- program/src/mine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/src/mine.rs b/program/src/mine.rs index 2e4b1d0..9597030 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -226,7 +226,7 @@ pub fn process_mine(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult { // Update lifetime stats. proof.total_hashes = proof.total_hashes.saturating_add(1); - proof.total_rewards = proof.total_rewards.saturating_add(reward); + proof.total_rewards = proof.total_rewards.saturating_add(reward_actual); // Log the mined rewards. // From 2fde727359f071a7669a8b0e36b9c6bcc1d6bbcd Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Mon, 7 Oct 2024 20:10:17 +0000 Subject: [PATCH 46/46] removed dead code --- program/src/reset.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/program/src/reset.rs b/program/src/reset.rs index b00a6ba..28a736c 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -46,8 +46,6 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul token_program.is_program(&spl_token::ID)?; // Validate enough time has passed since the last reset. - // let mut config_data = config_info.data.borrow_mut(); - // let config = Config::try_from_bytes_mut(&mut config_data)?; let clock = Clock::get()?; if config .last_reset_at