mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-15 07:26:45 +00:00
security fixes
This commit is contained in:
@@ -39,6 +39,7 @@ pub fn process_claim<'a, 'info>(
|
||||
load_signer(signer)?;
|
||||
load_token_account(beneficiary_info, None, mint_info.key, true)?;
|
||||
load_mint(mint_info, true)?;
|
||||
load_proof(proof_info, signer.key, true)?;
|
||||
load_treasury(treasury_info, true)?;
|
||||
load_token_account(
|
||||
treasury_tokens_info,
|
||||
@@ -48,15 +49,13 @@ pub fn process_claim<'a, 'info>(
|
||||
)?;
|
||||
load_program(token_program, spl_token::id())?;
|
||||
|
||||
// Validate claim amout
|
||||
// Update claimable amount
|
||||
let mut proof_data = proof_info.data.borrow_mut();
|
||||
let proof = Proof::try_from_bytes_mut(&mut proof_data)?;
|
||||
if proof.claimable_rewards.lt(&amount) {
|
||||
return Err(OreError::ClaimTooLarge.into());
|
||||
}
|
||||
|
||||
// Update claimable amount
|
||||
proof.claimable_rewards = proof.claimable_rewards.saturating_sub(amount);
|
||||
proof.claimable_rewards = proof
|
||||
.claimable_rewards
|
||||
.checked_sub(amount)
|
||||
.ok_or(OreError::ClaimTooLarge)?;
|
||||
|
||||
// Update lifetime status
|
||||
let mut treasury_data = treasury_info.data.borrow_mut();
|
||||
|
||||
@@ -55,34 +55,31 @@ pub fn process_initialize<'a, 'info>(
|
||||
return Err(ProgramError::NotEnoughAccountKeys);
|
||||
};
|
||||
load_signer(signer)?;
|
||||
load_uninitialized_pda(bus_0_info, &[BUS, &[0], &[args.bus_0_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_1_info, &[BUS, &[1], &[args.bus_1_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_2_info, &[BUS, &[2], &[args.bus_2_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_3_info, &[BUS, &[3], &[args.bus_3_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_4_info, &[BUS, &[4], &[args.bus_4_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_5_info, &[BUS, &[5], &[args.bus_5_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_6_info, &[BUS, &[6], &[args.bus_6_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_7_info, &[BUS, &[7], &[args.bus_7_bump]], &crate::id())?;
|
||||
load_uninitialized_pda(bus_0_info, &[BUS, &[0]], args.bus_0_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_1_info, &[BUS, &[1]], args.bus_1_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_2_info, &[BUS, &[2]], args.bus_2_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_3_info, &[BUS, &[3]], args.bus_3_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_4_info, &[BUS, &[4]], args.bus_4_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_5_info, &[BUS, &[5]], args.bus_5_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_6_info, &[BUS, &[6]], args.bus_6_bump, &crate::id())?;
|
||||
load_uninitialized_pda(bus_7_info, &[BUS, &[7]], args.bus_7_bump, &crate::id())?;
|
||||
load_uninitialized_pda(
|
||||
metadata_info,
|
||||
&[
|
||||
METADATA,
|
||||
mpl_token_metadata::ID.as_ref(),
|
||||
MINT_ADDRESS.as_ref(),
|
||||
&[args.metadata_bump],
|
||||
],
|
||||
args.metadata_bump,
|
||||
&mpl_token_metadata::ID,
|
||||
)?;
|
||||
load_uninitialized_pda(
|
||||
mint_info,
|
||||
&[MINT, MINT_NOISE.as_slice(), &[args.mint_bump]],
|
||||
&crate::id(),
|
||||
)?;
|
||||
load_uninitialized_pda(
|
||||
treasury_info,
|
||||
&[TREASURY, &[args.treasury_bump]],
|
||||
&[MINT, MINT_NOISE.as_slice()],
|
||||
args.mint_bump,
|
||||
&crate::id(),
|
||||
)?;
|
||||
load_uninitialized_pda(treasury_info, &[TREASURY], args.treasury_bump, &crate::id())?;
|
||||
load_uninitialized_account(treasury_tokens_info)?;
|
||||
load_program(system_program, system_program::id())?;
|
||||
load_program(token_program, spl_token::id())?;
|
||||
@@ -90,17 +87,6 @@ pub fn process_initialize<'a, 'info>(
|
||||
load_program(metadata_program, mpl_token_metadata::ID)?;
|
||||
load_sysvar(rent_sysvar, sysvar::rent::id())?;
|
||||
|
||||
// Verify keys
|
||||
if metadata_info.key.ne(&METADATA_ADDRESS) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
if mint_info.key.ne(&MINT_ADDRESS) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
if treasury_info.key.ne(&TREASURY_ADDRESS) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
// Initialize bus accounts
|
||||
let bus_infos = [
|
||||
bus_0_info, bus_1_info, bus_2_info, bus_3_info, bus_4_info, bus_5_info, bus_6_info,
|
||||
@@ -136,6 +122,9 @@ pub fn process_initialize<'a, 'info>(
|
||||
}
|
||||
|
||||
// Initialize treasury
|
||||
if treasury_info.key.ne(&TREASURY_ADDRESS) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
create_pda(
|
||||
treasury_info,
|
||||
&crate::id(),
|
||||
@@ -156,6 +145,9 @@ pub fn process_initialize<'a, 'info>(
|
||||
drop(treasury_data);
|
||||
|
||||
// Initialize mint
|
||||
if mint_info.key.ne(&MINT_ADDRESS) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
create_pda(
|
||||
mint_info,
|
||||
&spl_token::id(),
|
||||
@@ -182,6 +174,9 @@ pub fn process_initialize<'a, 'info>(
|
||||
)?;
|
||||
|
||||
// Initialize mint metadata
|
||||
if metadata_info.key.ne(&METADATA_ADDRESS) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
mpl_token_metadata::instructions::CreateMetadataAccountV3Cpi {
|
||||
__program: metadata_program,
|
||||
metadata: metadata_info,
|
||||
|
||||
@@ -47,7 +47,7 @@ pub fn process_mine<'a, 'info>(
|
||||
return Err(ProgramError::NotEnoughAccountKeys);
|
||||
};
|
||||
load_signer(signer)?;
|
||||
load_bus(bus_info, true)?;
|
||||
load_any_bus(bus_info, true)?;
|
||||
load_proof(proof_info, signer.key, true)?;
|
||||
load_treasury(treasury_info, false)?;
|
||||
load_sysvar(slot_hashes_info, sysvar::slot_hashes::id())?;
|
||||
@@ -80,10 +80,10 @@ pub fn process_mine<'a, 'info>(
|
||||
// Update claimable rewards
|
||||
let mut bus_data = bus_info.data.borrow_mut();
|
||||
let bus = Bus::try_from_bytes_mut(&mut bus_data)?;
|
||||
if bus.rewards.lt(&treasury.reward_rate) {
|
||||
return Err(OreError::BusRewardsInsufficient.into());
|
||||
}
|
||||
bus.rewards = bus.rewards.saturating_sub(treasury.reward_rate);
|
||||
bus.rewards = bus
|
||||
.rewards
|
||||
.checked_sub(treasury.reward_rate)
|
||||
.ok_or(OreError::BusRewardsInsufficient)?;
|
||||
proof.claimable_rewards = proof.claimable_rewards.saturating_add(treasury.reward_rate);
|
||||
|
||||
// Hash recent slot hash into the next challenge to prevent pre-mining attacks
|
||||
|
||||
@@ -38,7 +38,8 @@ pub fn process_register<'a, 'info>(
|
||||
load_signer(signer)?;
|
||||
load_uninitialized_pda(
|
||||
proof_info,
|
||||
&[PROOF, signer.key.as_ref(), &[args.bump]],
|
||||
&[PROOF, signer.key.as_ref()],
|
||||
args.bump,
|
||||
&crate::id(),
|
||||
)?;
|
||||
load_program(system_program, system_program::id())?;
|
||||
|
||||
@@ -39,14 +39,14 @@ pub fn process_reset<'a, 'info>(
|
||||
return Err(ProgramError::NotEnoughAccountKeys);
|
||||
};
|
||||
load_signer(signer)?;
|
||||
load_bus(bus_0_info, true)?;
|
||||
load_bus(bus_1_info, true)?;
|
||||
load_bus(bus_2_info, true)?;
|
||||
load_bus(bus_3_info, true)?;
|
||||
load_bus(bus_4_info, true)?;
|
||||
load_bus(bus_5_info, true)?;
|
||||
load_bus(bus_6_info, true)?;
|
||||
load_bus(bus_7_info, true)?;
|
||||
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)?;
|
||||
load_mint(mint_info, true)?;
|
||||
load_treasury(treasury_info, true)?;
|
||||
load_token_account(
|
||||
@@ -55,7 +55,7 @@ pub fn process_reset<'a, 'info>(
|
||||
mint_info.key,
|
||||
true,
|
||||
)?;
|
||||
load_sysvar(token_program, spl_token::id())?;
|
||||
load_program(token_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,
|
||||
@@ -127,9 +127,9 @@ pub(crate) fn calculate_new_reward_rate(current_rate: u64, epoch_rewards: u64) -
|
||||
}
|
||||
|
||||
// Calculate new reward rate.
|
||||
let new_rate = (current_rate as u128)
|
||||
.saturating_mul(TARGET_EPOCH_REWARDS as u128)
|
||||
.saturating_div(epoch_rewards as u128) as u64;
|
||||
let new_rate = (current_rate)
|
||||
.saturating_mul(TARGET_EPOCH_REWARDS)
|
||||
.saturating_div(epoch_rewards) 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);
|
||||
@@ -218,4 +218,16 @@ mod tests {
|
||||
let new_rate = calculate_new_reward_rate(current_rate, u64::MAX);
|
||||
assert!(new_rate.eq(¤t_rate.saturating_div(SMOOTHING_FACTOR)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_calculate_new_reward_rate_max_inputs() {
|
||||
let new_rate = calculate_new_reward_rate(BUS_EPOCH_REWARDS, MAX_EPOCH_REWARDS);
|
||||
assert!(new_rate.eq(&BUS_EPOCH_REWARDS.saturating_div(SMOOTHING_FACTOR)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_calculate_new_reward_rate_min_inputs() {
|
||||
let new_rate = calculate_new_reward_rate(1, 1);
|
||||
assert!(new_rate.eq(&1u64.saturating_mul(SMOOTHING_FACTOR)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ pub fn process_update_admin<'a, 'info>(
|
||||
load_signer(signer)?;
|
||||
load_treasury(treasury_info, true)?;
|
||||
|
||||
// Validate admin signer
|
||||
// Validate signer is admin
|
||||
let mut treasury_data = treasury_info.data.borrow_mut();
|
||||
let treasury = Treasury::try_from_bytes_mut(&mut treasury_data)?;
|
||||
if treasury.admin.ne(&signer.key) {
|
||||
|
||||
@@ -41,7 +41,7 @@ pub fn process_update_difficulty<'a, 'info>(
|
||||
load_signer(signer)?;
|
||||
load_treasury(treasury_info, true)?;
|
||||
|
||||
// Validate admin signer
|
||||
// Validate signer is admin
|
||||
let mut treasury_data = treasury_info.data.borrow_mut();
|
||||
let treasury = Treasury::try_from_bytes_mut(&mut treasury_data)?;
|
||||
if treasury.admin.ne(&signer.key) {
|
||||
|
||||
Reference in New Issue
Block a user