From 54bd0a025c3ac9df064434038bcf0baf30163717 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Tue, 30 Apr 2024 18:17:06 +0000 Subject: [PATCH] consts --- src/consts.rs | 13 ++++++++----- src/processor/initialize.rs | 6 ++---- src/processor/mine.rs | 24 +++++++++--------------- src/processor/pause.rs | 2 +- src/processor/reset.rs | 6 +++--- src/state/config.rs | 7 +------ 6 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 8c7e73c..71a12a9 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -5,20 +5,23 @@ use solana_program::{pubkey, pubkey::Pubkey}; /// The reward rate to intialize the program with. pub const INITIAL_BASE_REWARD_RATE: u64 = 10u64.pow(3u32); -/// The minimum difficulty to initialize the program with. -pub const INITIAL_MIN_DIFFICULTY: u32 = 12; - /// The spam/liveness tolerance to initialize the program with. pub const INITIAL_TOLERANCE: i64 = 5; +/// The minimum difficulty required of all submitted hashes. +pub const MIN_DIFFICULTY: u32 = 12; + /// The decimal precision of the ORE token. pub const TOKEN_DECIMALS: u8 = 11; /// One ORE token, denominated in indivisible units. pub const ONE_ORE: u64 = 10u64.pow(TOKEN_DECIMALS as u32); -/// The duration of an epoch, in units of seconds. -pub const EPOCH_DURATION: i64 = 60; +/// The duration of one minute, in seconds. +pub const ONE_MINUTE: i64 = 60; + +/// The duration of two years, in minutes. +pub const TWO_YEARS: u64 = 60 * 24 * 365 * 2; /// The target quantity of ORE to be mined per epoch. /// Inflation rate ≈ 1 ORE / epoch (min 0, max 2) diff --git a/src/processor/initialize.rs b/src/processor/initialize.rs index 022c04a..85c424a 100644 --- a/src/processor/initialize.rs +++ b/src/processor/initialize.rs @@ -17,9 +17,8 @@ use crate::{ utils::create_pda, utils::AccountDeserialize, utils::Discriminator, - BUS, BUS_COUNT, CONFIG, INITIAL_BASE_REWARD_RATE, INITIAL_MIN_DIFFICULTY, INITIAL_TOLERANCE, - METADATA, METADATA_NAME, METADATA_SYMBOL, METADATA_URI, MINT, MINT_ADDRESS, MINT_NOISE, - TOKEN_DECIMALS, TREASURY, + BUS, BUS_COUNT, CONFIG, INITIAL_BASE_REWARD_RATE, INITIAL_TOLERANCE, METADATA, MINT, + MINT_ADDRESS, MINT_NOISE, TOKEN_DECIMALS, TREASURY, }; /// Initialize sets up the Ore program. Its responsibilities include: @@ -135,7 +134,6 @@ pub fn process_initialize<'a, 'info>( config.admin = *signer.key; config.base_reward_rate = INITIAL_BASE_REWARD_RATE; config.last_reset_at = 0; - config.min_difficulty = INITIAL_MIN_DIFFICULTY; config.paused = 0; config.tolerance_liveness = INITIAL_TOLERANCE; config.tolerance_spam = INITIAL_TOLERANCE; diff --git a/src/processor/mine.rs b/src/processor/mine.rs index a7cc6f0..0ce5c83 100644 --- a/src/processor/mine.rs +++ b/src/processor/mine.rs @@ -18,7 +18,7 @@ use crate::{ loaders::*, state::{Bus, Config, Proof}, utils::AccountDeserialize, - EPOCH_DURATION, + MIN_DIFFICULTY, ONE_MINUTE, TWO_YEARS, }; // TODO Look into tx introspection to require 1 hash per tx @@ -72,7 +72,7 @@ pub fn process_mine<'a, 'info>( // TODO Validate epoch is active // let treasury_data = treasury_info.data.borrow(); // let treasury = Treasury::try_from_bytes(&treasury_data)?; - // let threshold = treasury.last_reset_at.saturating_add(EPOCH_DURATION); + // let threshold = treasury.last_reset_at.saturating_add(ONE_MINUTE); // if clock.unix_timestamp.ge(&threshold) { // return Err(OreError::NeedsReset.into()); // } @@ -83,27 +83,21 @@ pub fn process_mine<'a, 'info>( // Validate hash satisfies the minimnum difficulty let difficulty = drillx::difficulty(hx); sol_log(&format!("Diff {}", difficulty)); - if difficulty.le(&config.min_difficulty) { + if difficulty.lt(&MIN_DIFFICULTY) { return Err(OreError::HashTooEasy.into()); } // Calculate base reward rate - let difficulty = difficulty.saturating_sub(config.min_difficulty); + let difficulty = difficulty.saturating_sub(MIN_DIFFICULTY); let mut reward = config .base_reward_rate .saturating_mul(2u64.saturating_pow(difficulty)); sol_log(&format!("Base {}", reward)); - // Apply staking multiplier + // Apply staking multiplier, only if last deposit was at least 1 block ago to prevent flash loan attacks if clock.slot.gt(&proof.last_deposit_slot) { - // Only apply if last deposit was at least 1 block ago to prevent flash loan attacks. - // TODO Cleanup math with a const here (unnecessary cus) - // TODO Move const into config - let max_stake = reward - .saturating_mul(60) // min/hour - .saturating_mul(24) // hour/day - .saturating_mul(365) // day/year - .saturating_mul(2); // year + // TODO Move staking requirement into config? Admin adjustable? + let max_stake = reward.saturating_mul(TWO_YEARS); let staking_reward = proof .balance .min(max_stake) @@ -115,7 +109,7 @@ pub fn process_mine<'a, 'info>( // Apply spam/liveness penalty let t = clock.unix_timestamp; - let t_target = proof.last_hash_at.saturating_add(EPOCH_DURATION); + let t_target = proof.last_hash_at.saturating_add(ONE_MINUTE); let t_spam = t_target.saturating_sub(config.tolerance_spam); let t_liveness = t_target.saturating_add(config.tolerance_liveness); if t.lt(&t_spam) { @@ -127,7 +121,7 @@ pub fn process_mine<'a, 'info>( .saturating_mul(t.saturating_sub(t_liveness) as u64) .saturating_div( t_target - .saturating_add(EPOCH_DURATION) + .saturating_add(ONE_MINUTE) .saturating_sub(t_liveness) as u64, ), ); diff --git a/src/processor/pause.rs b/src/processor/pause.rs index be2cbb9..4970c6e 100644 --- a/src/processor/pause.rs +++ b/src/processor/pause.rs @@ -28,7 +28,7 @@ pub fn process_pause<'a, 'info>( } // Update paused - config.paused = args.paused as u32; + config.paused = args.paused as u64; Ok(()) } diff --git a/src/processor/reset.rs b/src/processor/reset.rs index 2b27b6f..95627fd 100644 --- a/src/processor/reset.rs +++ b/src/processor/reset.rs @@ -11,8 +11,8 @@ use crate::{ }, state::{Bus, Config}, utils::AccountDeserialize, - BUS_COUNT, BUS_EPOCH_REWARDS, EPOCH_DURATION, MAX_EPOCH_REWARDS, MINT_ADDRESS, - SMOOTHING_FACTOR, TARGET_EPOCH_REWARDS, TREASURY, TREASURY_BUMP, + BUS_COUNT, BUS_EPOCH_REWARDS, MAX_EPOCH_REWARDS, MINT_ADDRESS, ONE_MINUTE, SMOOTHING_FACTOR, + TARGET_EPOCH_REWARDS, TREASURY, TREASURY_BUMP, }; /// Reset sets up the Ore program for the next epoch. Its responsibilities include: @@ -78,7 +78,7 @@ pub fn process_reset<'a, 'info>( // Validate enough time has passed since last reset let clock = Clock::get().or(Err(ProgramError::InvalidAccountData))?; - let threshold = config.last_reset_at.saturating_add(EPOCH_DURATION); + let threshold = config.last_reset_at.saturating_add(ONE_MINUTE); if clock.unix_timestamp.lt(&threshold) { return Ok(()); } diff --git a/src/state/config.rs b/src/state/config.rs index 725d8c3..ea15408 100644 --- a/src/state/config.rs +++ b/src/state/config.rs @@ -2,8 +2,6 @@ use bytemuck::{Pod, Zeroable}; use shank::ShankAccount; use solana_program::pubkey::Pubkey; -// TODO next_min_difficulty: Option, update on reset - use crate::{ impl_account_from_bytes, impl_to_bytes, utils::{AccountDiscriminator, Discriminator}, @@ -22,11 +20,8 @@ pub struct Config { /// The timestamp of the last reset pub last_reset_at: i64, - /// The minimum accepted difficulty. - pub min_difficulty: u32, - /// Is mining paused. - pub paused: u32, + pub paused: u64, /// Seconds prior to a miner's target time during which their hashes will not be penalized. pub tolerance_spam: i64,