From d1c903ec48d509b19dabaf23fa38934d740de711 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 3 May 2024 02:59:34 +0000 Subject: [PATCH] add max supply --- src/consts.rs | 7 +++++-- src/error.rs | 2 ++ src/processor/reset.rs | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 71a12a9..3aa7b38 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -11,10 +11,10 @@ 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. +/// The decimal precision of the Ore token (100 billion indivisible units per Ore). pub const TOKEN_DECIMALS: u8 = 11; -/// One ORE token, denominated in indivisible units. +/// One Ore token, denominated in indivisible units. pub const ONE_ORE: u64 = 10u64.pow(TOKEN_DECIMALS as u32); /// The duration of one minute, in seconds. @@ -23,6 +23,9 @@ pub const ONE_MINUTE: i64 = 60; /// The duration of two years, in minutes. pub const TWO_YEARS: u64 = 60 * 24 * 365 * 2; +/// The maximum token supply (100 million). +pub const MAX_SUPPLY: u64 = ONE_ORE.saturating_mul(100_000_000); + /// The target quantity of ORE to be mined per epoch. /// Inflation rate ≈ 1 ORE / epoch (min 0, max 2) pub const TARGET_EPOCH_REWARDS: u64 = ONE_ORE; diff --git a/src/error.rs b/src/error.rs index fe711ec..0956ad3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -19,6 +19,8 @@ pub enum OreError { TransactionInvalid = 5, #[error("The tolerance cannot exceed i64 max value")] ToleranceOverflow = 6, + #[error("The maximum supply has been reached")] + MaxSupply = 7, } impl From for ProgramError { diff --git a/src/processor/reset.rs b/src/processor/reset.rs index 95627fd..f204504 100644 --- a/src/processor/reset.rs +++ b/src/processor/reset.rs @@ -1,7 +1,8 @@ use solana_program::{ account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, - program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, + program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, sysvar::Sysvar, }; +use spl_token::state::Mint; use crate::{ error::OreError, @@ -11,8 +12,8 @@ use crate::{ }, state::{Bus, Config}, utils::AccountDeserialize, - BUS_COUNT, BUS_EPOCH_REWARDS, MAX_EPOCH_REWARDS, MINT_ADDRESS, ONE_MINUTE, SMOOTHING_FACTOR, - TARGET_EPOCH_REWARDS, TREASURY, TREASURY_BUMP, + BUS_COUNT, BUS_EPOCH_REWARDS, MAX_EPOCH_REWARDS, MAX_SUPPLY, 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: @@ -104,6 +105,15 @@ pub fn process_reset<'a, 'info>( config.base_reward_rate = calculate_new_reward_rate(config.base_reward_rate, total_theoretical_rewards); + // Load mint + let mint = Mint::unpack(&mint_info.data.borrow()).expect("Failed to parse mint"); + let amount = MAX_SUPPLY + .saturating_sub(mint.supply) + .min(total_epoch_rewards); + if amount.eq(&0) { + return Err(OreError::MaxSupply.into()); + } + // Fund treasury token account solana_program::program::invoke_signed( &spl_token::instruction::mint_to( @@ -112,7 +122,7 @@ pub fn process_reset<'a, 'info>( treasury_tokens_info.key, treasury_info.key, &[treasury_info.key], - total_epoch_rewards, + amount, )?, &[ token_program.clone(),