diff --git a/program/src/claim.rs b/program/src/claim.rs
index 009188b..b6b809a 100644
--- a/program/src/claim.rs
+++ b/program/src/claim.rs
@@ -6,14 +6,7 @@ use solana_program::{
use crate::utils::AccountDeserialize;
-/// Claim distributes Ore from the treasury to a miner. Its responsibilies include:
-/// 1. Decrement the miner's claimable balance.
-/// 2. Transfer tokens from the treasury to the miner.
-///
-/// Safety requirements:
-/// - Claim is a permissionless instruction and can be called by any user.
-/// - Can only succeed if the claimed amount is less than or equal to the miner's claimable rewards.
-/// - The provided beneficiary, token account, treasury, treasury token account, and token program must be valid.
+/// Claim distributes ORE from the treasury to a miner.
pub fn process_claim<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8]) -> ProgramResult {
// Parse args
let args = ClaimArgs::try_from_bytes(data)?;
diff --git a/program/src/close.rs b/program/src/close.rs
index 6898c7d..b266329 100644
--- a/program/src/close.rs
+++ b/program/src/close.rs
@@ -6,14 +6,7 @@ use solana_program::{
use crate::utils::AccountDeserialize;
-/// Close closes a proof account and returns the rent to the owner. Its responsibilities include:
-/// 1. Realloc proof account size to 0.
-/// 2. Transfer lamports to the owner.
-///
-/// Safety requirements:
-/// - Deregister is a permissionless instruction and can be invoked by any singer.
-/// - Can only succeed if the provided proof acount PDA is valid (associated with the signer).
-/// - The provided system program must be valid.
+/// Close closes a proof account and returns the rent to the owner.
pub fn process_close<'a, 'info>(accounts: &'a [AccountInfo<'info>], _data: &[u8]) -> ProgramResult {
// Load accounts
let [signer, proof_info, system_program] = accounts else {
diff --git a/program/src/initialize.rs b/program/src/initialize.rs
index 3ce4bf6..a1ac336 100644
--- a/program/src/initialize.rs
+++ b/program/src/initialize.rs
@@ -18,24 +18,7 @@ use spl_token::state::Mint;
use crate::utils::{create_pda, AccountDeserialize, Discriminator};
-/// Initialize sets up the Ore program. Its responsibilities include:
-/// 1. Initialize the 8 bus accounts.
-/// 2. Initialize the treasury account.
-/// 3. Initialize the Ore mint account.
-/// 4. Initialize the mint metadata account.
-/// 5. Initialize the treasury token account.
-/// 6. Set the signer as the program admin.
-///
-/// Safety requirements:
-/// - Initialize is a permissionless instruction and can be called by anyone.
-/// - Can only succeed once for the entire lifetime of the program.
-/// - Can only succeed if all provided PDAs match their expected values.
-/// - Can only succeed if provided system program, token program,
-/// associated token program, metadata program, and rent sysvar are valid.
-///
-/// Discussion
-/// - The signer of this instruction is set as the program admin and the
-/// upgrade authority of the mint metadata account.
+/// Initialize sets up the ORE program to begin mining.
pub fn process_initialize<'a, 'info>(
accounts: &'a [AccountInfo<'info>],
data: &[u8],
diff --git a/program/src/mine.rs b/program/src/mine.rs
index 74c5f11..6de4314 100644
--- a/program/src/mine.rs
+++ b/program/src/mine.rs
@@ -16,7 +16,6 @@ use solana_program::{
blake3::hashv,
clock::Clock,
entrypoint::ProgramResult,
- log::sol_log,
program_error::ProgramError,
pubkey::Pubkey,
sanitize::SanitizeError,
@@ -27,20 +26,7 @@ use solana_program::{
use crate::utils::AccountDeserialize;
-/// Mine is the primary workhorse instruction of the Ore program. Its responsibilities include:
-/// 1. Calculate the hash from the provided nonce.
-/// 2. Payout rewards based on difficulty, staking multiplier, and liveness penalty.
-/// 3. Generate a new challenge for the miner.
-/// 4. Update the miner's lifetime stats.
-///
-/// Safety requirements:
-/// - Mine is a permissionless instruction and can be called by any signer.
-/// - Can only succeed if mining is not paused.
-/// - Can only succeed if the last reset was less than 60 seconds ago.
-/// - Can only succeed if the provided hash satisfies the minimum difficulty requirement.
-/// - Can only succeed if the miners proof pubkey matches the declared proof pubkey.
-/// - The provided proof account must be associated with the signer.
-/// - The provided bus, config, noise, stake, and slot hash sysvar must be valid.
+/// Mine validates hashes and increments a miner's collectable balance.
pub fn process_mine<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8]) -> ProgramResult {
// Parse args
let args = MineArgs::try_from_bytes(data)?;
@@ -59,13 +45,7 @@ pub fn process_mine<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8])
load_sysvar(slot_hashes_sysvar, sysvar::slot_hashes::id())?;
// Authenticate the proof account
- if let Ok(Some(auth_address)) = authenticate(&instructions_sysvar.data.borrow()) {
- if auth_address.ne(proof_info.key) {
- return Err(OreError::AuthFailed.into());
- }
- } else {
- return Err(OreError::AuthFailed.into());
- }
+ authenticate(&instructions_sysvar.data.borrow(), proof_info.key)?;
// Validate epoch is active.
let config_data = config_info.data.borrow();
@@ -110,7 +90,6 @@ pub fn process_mine<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8])
.base_reward_rate
.checked_mul(2u64.checked_pow(normalized_difficulty).unwrap())
.unwrap();
- sol_log(&format!("Diff {}", difficulty));
// Apply staking multiplier.
// If user has greater than or equal to the max stake on the network, they receive 2x multiplier.
@@ -183,24 +162,29 @@ pub fn process_mine<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8])
Ok(())
}
-/// Get the authenticated pubkey.
+/// Authenticate the proof account.
///
-/// The intent here is to disincentivize sybil. If a user can fit multiple hashes into a single
-/// transaction, there is a financial incentive to sybil multiple keypairs and pack as many hashes
-/// as possible into each transaction to minimize fee / hash.
+/// This process is necessary to prevent sybil attacks. If a user can pack multiple hashes into a single
+/// transaction, then there is a financial incentive to mine across multiple keypairs and submit as many hashes
+/// as possible in each transaction to minimize fee / hash.
///
-/// If each transaction is limited to one hash only, then a user will minimize their fee / hash
-/// by allocating all their hashpower to finding the single most difficult hash they can.
-///
-/// We solve this by "authenticating" the proof account on every mine instruction. That is,
-/// every transaction with a `mine` instruction needs to include an `auth` instruction that
-/// specifies the proof account that will be used. The `auth` instruction must be first ORE
-/// instruction in the transaction. The `mine` instruction should error out if the provided proof
-/// account doesn't match the authenticated address.
-///
-/// Errors if:
-/// - Fails to find and parse an authentication address.
-fn authenticate(data: &[u8]) -> Result