11 decimals

This commit is contained in:
Hardhat Chad
2024-04-30 17:43:04 +00:00
parent 43a01003a3
commit 8ab3c27492
8 changed files with 49 additions and 39 deletions

View File

@@ -17,8 +17,9 @@ use crate::{
utils::create_pda,
utils::AccountDeserialize,
utils::Discriminator,
BUS, BUS_COUNT, CONFIG, INITIAL_BASE_REWARD_RATE, METADATA, METADATA_NAME, METADATA_SYMBOL,
METADATA_URI, MINT, MINT_ADDRESS, MINT_NOISE, TOKEN_DECIMALS, TREASURY,
BUS, BUS_COUNT, CONFIG, INITIAL_BASE_REWARD_RATE, INITIAL_MIN_DIFFICULTY, METADATA,
METADATA_NAME, METADATA_SYMBOL, METADATA_URI, MINT, MINT_ADDRESS, MINT_NOISE, TOKEN_DECIMALS,
TREASURY,
};
/// Initialize sets up the Ore program. Its responsibilities include:
@@ -134,7 +135,7 @@ 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 = 8;
config.min_difficulty = INITIAL_MIN_DIFFICULTY;
config.paused = 0;
// Initialize treasury

View File

@@ -18,7 +18,7 @@ use crate::{
loaders::*,
state::{Bus, Config, Proof},
utils::AccountDeserialize,
BUS_EPOCH_REWARDS, EPOCH_DURATION,
EPOCH_DURATION,
};
// TODO Look into tx introspection to require 1 hash per tx
@@ -69,7 +69,7 @@ pub fn process_mine<'a, 'info>(
return Err(OreError::ClockInvalid.into());
}
// Validate epoch is active
// 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);
@@ -84,7 +84,7 @@ pub fn process_mine<'a, 'info>(
let difficulty = drillx::difficulty(hx);
sol_log(&format!("Diff {}", difficulty));
if difficulty.le(&config.min_difficulty) {
return Err(OreError::DifficultyInsufficient.into());
return Err(OreError::HashTooEasy.into());
}
// Calculate base reward rate
@@ -143,16 +143,17 @@ pub fn process_mine<'a, 'info>(
// Set upper bound to whatever is left in the bus
let mut bus_data = bus_info.data.borrow_mut();
let bus = Bus::try_from_bytes_mut(&mut bus_data)?;
reward = reward.min(bus.rewards);
let actual_reward = reward.min(bus.rewards);
// Update balances
sol_log(&format!("Total {}", reward));
sol_log(&format!("Bus {}", bus.rewards));
bus.theoretical_rewards = bus.theoretical_rewards.saturating_add(reward);
bus.rewards = bus
.rewards
.checked_sub(reward)
.ok_or(OreError::BusRewardsInsufficient)?;
proof.balance = proof.balance.saturating_add(reward);
.checked_sub(actual_reward)
.expect("This should not happen");
proof.balance = proof.balance.saturating_add(actual_reward);
// Hash recent slot hash into the next challenge to prevent pre-mining attacks
proof.challenge = hashv(&[

View File

@@ -18,7 +18,7 @@ use crate::{
/// Reset sets up the Ore program for the next epoch. Its responsibilities include:
/// 1. Reset bus account rewards counters.
/// 2. Adjust the reward rate to stabilize inflation.
/// 3. Top up the treasury token account to backup claims.
/// 3. Top up the treasury token account to fund claims.
///
/// Safety requirements:
/// - Reset is a permissionless instruction and can be invoked by any signer.
@@ -29,8 +29,11 @@ use crate::{
/// Discussion:
/// - It is important that `reset` can only be invoked once per 60 second period to ensure the supply growth rate
/// stays within the guaranteed bounds of 0 ≤ R ≤ 2 ORE/min.
/// - The reward rate is dynamically adjusted based on last epoch's actual reward rate (proxy for hashpower) to
/// target an average supply growth rate of 1 ORE/min.
/// - The reward rate is dynamically adjusted based on last epoch's theoretical reward rate to target an average
/// supply growth rate of 1 ORE/min.
/// - The "theoretical" reward rate refers to the amount that would have been paid out if rewards were not capped by
/// the bus limits. It's necessary to use this value to ensure the reward rate update calculation accurately
/// accounts for the difficulty of submitted hashes.
pub fn process_reset<'a, 'info>(
_program_id: &Pubkey,
accounts: &'a [AccountInfo<'info>],
@@ -85,17 +88,21 @@ pub fn process_reset<'a, 'info>(
// Reset bus accounts and calculate actual rewards mined since last reset
let mut total_remaining_rewards = 0u64;
let mut total_theoretical_rewards = 0u64;
for i in 0..BUS_COUNT {
let mut bus_data = busses[i].data.borrow_mut();
let bus = Bus::try_from_bytes_mut(&mut bus_data)?;
total_remaining_rewards = total_remaining_rewards.saturating_add(bus.rewards);
total_theoretical_rewards =
total_theoretical_rewards.saturating_add(bus.theoretical_rewards);
bus.rewards = BUS_EPOCH_REWARDS;
bus.theoretical_rewards = 0;
}
let total_epoch_rewards = MAX_EPOCH_REWARDS.saturating_sub(total_remaining_rewards);
// Update base reward rate for next epoch
config.base_reward_rate =
calculate_new_reward_rate(config.base_reward_rate, total_epoch_rewards);
calculate_new_reward_rate(config.base_reward_rate, total_theoretical_rewards);
// Fund treasury token account
solana_program::program::invoke_signed(
@@ -135,9 +142,9 @@ pub(crate) fn calculate_new_reward_rate(current_rate: u64, epoch_rewards: u64) -
}
// Calculate new reward rate.
let new_rate = (current_rate)
.saturating_mul(TARGET_EPOCH_REWARDS)
.saturating_div(epoch_rewards) as u64;
let new_rate = (current_rate as u128)
.saturating_mul(TARGET_EPOCH_REWARDS as u128)
.saturating_div(epoch_rewards as u128) as u64;
// Smooth reward rate so it cannot change by more than a constant factor from one epoch to the next.
let new_rate_min = current_rate.saturating_div(SMOOTHING_FACTOR);

View File

@@ -53,8 +53,11 @@ pub fn process_upgrade<'a, 'info>(
],
)?;
// Account for decimals change.
// v1 token has 9 decimals. v2 token has 11.
let amount_to_mint = amount.saturating_mul(100);
// Mint to the beneficiary account
// TODO Account for decimals change!
let treasury_data = treasury_info.data.borrow();
let treasury = Treasury::try_from_bytes(&treasury_data)?;
let treasury_bump = treasury.bump as u8;
@@ -66,7 +69,7 @@ pub fn process_upgrade<'a, 'info>(
beneficiary_info.key,
treasury_info.key,
&[treasury_info.key],
amount,
amount_to_mint,
)?,
&[
token_program.clone(),