checkpoint

This commit is contained in:
Hardhat Chad
2025-10-01 12:05:13 -07:00
parent a8ba556a13
commit 94a5d67dcf
4 changed files with 75 additions and 24 deletions

View File

@@ -8,7 +8,8 @@ use steel::*;
pub fn process_checkpoint(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
// Load accounts.
let clock = Clock::get()?;
let [signer_info, board_info, miner_info, round_info, treasury_info, system_program] = accounts
let [signer_info, automation_info, board_info, miner_info, round_info, treasury_info, system_program] =
accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};
@@ -39,6 +40,32 @@ pub fn process_checkpoint(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
return Ok(());
}
// Calculate bot fee permissions.
let mut bot_fee = 0;
if clock.unix_timestamp > round.expires_at - ONE_DAY {
// We are in the last day before the round expires.
// Anyone is allowed to checkpoint and may collect the bot fee.
bot_fee = miner.checkpoint_fee;
miner.checkpoint_fee = 0;
} else {
// There is still time before the round expires. Bots may not yet checkpoint this account.
automation_info.has_seeds(&[AUTOMATION, &miner.authority.to_bytes()], &ore_api::ID)?;
if !automation_info.data_is_empty() {
let automation = automation_info
.as_account::<Automation>(&ore_api::ID)?
.assert(|a| a.authority == miner.authority)?;
assert!(
*signer_info.key == miner.authority || *signer_info.key == automation.executor,
"Only the miner or automation executor can checkpoint this account"
);
} else {
assert!(
*signer_info.key == miner.authority,
"Only the miner can checkpoint this account"
);
}
}
// Calculate miner rewards.
let mut rewards_sol = 0;
let mut rewards_ore = 0;
@@ -84,6 +111,9 @@ pub fn process_checkpoint(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
if rewards_sol > 0 {
round_info.send(rewards_sol, &miner_info);
}
if bot_fee > 0 {
miner_info.send(bot_fee, &signer_info);
}
// Assert round has sufficient funds for rent.
let account_size = 8 + std::mem::size_of::<Round>();
@@ -93,5 +123,12 @@ pub fn process_checkpoint(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
"Round does not have sufficient funds for rent"
);
let account_size = 8 + std::mem::size_of::<Miner>();
let required_rent = Rent::get()?.minimum_balance(account_size);
assert!(
miner_info.lamports() >= required_rent,
"Miner does not have sufficient funds for rent"
);
Ok(())
}

View File

@@ -165,6 +165,12 @@ pub fn process_deploy(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul
}
}
// Pay checkpoint fee.
if miner.checkpoint_fee == 0 {
miner.checkpoint_fee = CHECKPOINT_FEE;
miner_info.collect(CHECKPOINT_FEE, &signer_info)?;
}
// Transfer SOL.
if let Some(automation) = automation {
automation.balance -= total_amount + automation.fee;

View File

@@ -44,33 +44,35 @@ pub fn process_instruction(
accounts: &[AccountInfo],
data: &[u8],
) -> ProgramResult {
// let (ix, data) = parse_instruction(&ore_api::ID, program_id, data)?;
let (ix, data) = parse_instruction(&ore_api::ID, program_id, data)?;
// match ix {
// // Miner
// OreInstruction::Automate => process_automate(accounts, data)?,
// OreInstruction::Boost => process_boost(accounts, data)?,
// OreInstruction::ClaimSOL => process_claim_sol(accounts, data)?,
// OreInstruction::ClaimORE => process_claim_ore(accounts, data)?,
// OreInstruction::Deploy => process_deploy(accounts, data)?,
// OreInstruction::Log => process_log(accounts, data)?,
// OreInstruction::Initialize => process_initialize(accounts, data)?,
// OreInstruction::Reset => process_reset(accounts, data)?,
match ix {
// Miner
OreInstruction::Automate => process_automate(accounts, data)?,
OreInstruction::Boost => process_boost(accounts, data)?,
OreInstruction::Checkpoint => process_checkpoint(accounts, data)?,
OreInstruction::ClaimSOL => process_claim_sol(accounts, data)?,
OreInstruction::ClaimORE => process_claim_ore(accounts, data)?,
OreInstruction::Deploy => process_deploy(accounts, data)?,
OreInstruction::Log => process_log(accounts, data)?,
// OreInstruction::Initialize => process_initialize(accounts, data)?,
OreInstruction::Reset => process_reset(accounts, data)?,
// // Staker
// OreInstruction::Deposit => process_deposit(accounts, data)?,
// OreInstruction::Withdraw => process_withdraw(accounts, data)?,
// OreInstruction::ClaimYield => process_claim_yield(accounts, data)?,
// Staker
OreInstruction::Deposit => process_deposit(accounts, data)?,
OreInstruction::Withdraw => process_withdraw(accounts, data)?,
OreInstruction::ClaimYield => process_claim_yield(accounts, data)?,
// // Admin
// OreInstruction::Bury => process_bury(accounts, data)?,
// OreInstruction::Wrap => process_wrap(accounts, data)?,
// OreInstruction::SetAdmin => process_set_admin(accounts, data)?,
// OreInstruction::SetFeeCollector => process_set_fee_collector(accounts, data)?,
// Admin
OreInstruction::Bury => process_bury(accounts, data)?,
OreInstruction::Wrap => process_wrap(accounts, data)?,
OreInstruction::SetAdmin => process_set_admin(accounts, data)?,
OreInstruction::SetFeeCollector => process_set_fee_collector(accounts, data)?,
// // Seeker
// OreInstruction::ClaimSeeker => process_claim_seeker(accounts, data)?,
// }
// Seeker
OreInstruction::ClaimSeeker => process_claim_seeker(accounts, data)?,
_ => return Err(ProgramError::InvalidInstructionData),
}
Ok(())
}