mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-13 23:16:52 +00:00
kick and refund
This commit is contained in:
@@ -14,6 +14,7 @@ pub struct Config {
|
||||
pub last_boost: i64,
|
||||
|
||||
// The minimum amount of SOL that can be deploy.
|
||||
#[deprecated(since = "1.0.0", note = "Unused")]
|
||||
pub min_deploy_amount: u64,
|
||||
|
||||
// The address that receives fees.
|
||||
|
||||
@@ -17,6 +17,9 @@ pub struct Miner {
|
||||
#[deprecated(note = "Use automation executor instead")]
|
||||
pub executor: Pubkey,
|
||||
|
||||
/// The amount of SOL this miner has had refunded and may claim.
|
||||
pub refund_sol: u64,
|
||||
|
||||
/// The amount of SOL this miner can claim.
|
||||
pub rewards_sol: u64,
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ pub struct Square {
|
||||
/// The count of miners on this square.
|
||||
pub count: [u64; 25],
|
||||
|
||||
/// The deployments of all players.
|
||||
pub deployed: [[u64; 16]; 25],
|
||||
|
||||
/// The miners in each square.
|
||||
pub miners: [[Pubkey; 16]; 25],
|
||||
}
|
||||
|
||||
@@ -13,8 +13,9 @@ pub fn process_deploy(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul
|
||||
|
||||
// Load accounts.
|
||||
let clock = Clock::get()?;
|
||||
let (required_accounts, miner_accounts) = accounts.split_at(9);
|
||||
let [signer_info, authority_info, automation_info, board_info, config_info, fee_collector_info, miner_info, square_info, system_program] =
|
||||
accounts
|
||||
required_accounts
|
||||
else {
|
||||
return Err(ProgramError::NotEnoughAccountKeys);
|
||||
};
|
||||
@@ -80,11 +81,6 @@ pub fn process_deploy(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul
|
||||
}
|
||||
}
|
||||
|
||||
// Check minimum amount.
|
||||
if amount < config.min_deploy_amount {
|
||||
return Err(trace("Amount too small", OreError::AmountTooSmall.into()));
|
||||
}
|
||||
|
||||
// Log
|
||||
sol_log(
|
||||
&format!(
|
||||
@@ -156,29 +152,118 @@ pub fn process_deploy(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul
|
||||
let amount = amount - fee;
|
||||
|
||||
// Calculate all deployments.
|
||||
let mut refund_amounts = [0; 25];
|
||||
let mut refund_miner_infos = [None; 25];
|
||||
let mut total_fee = 0;
|
||||
let mut total_amount = 0;
|
||||
for (square_id, &should_deploy) in squares.iter().enumerate() {
|
||||
'deploy: for (square_id, &should_deploy) in squares.iter().enumerate() {
|
||||
// Skip if square index is out of bounds.
|
||||
if square_id > 24 {
|
||||
break;
|
||||
}
|
||||
if should_deploy {
|
||||
total_fee += fee;
|
||||
total_amount += amount;
|
||||
|
||||
// Update miner
|
||||
let is_first_move = miner.deployed[square_id] == 0;
|
||||
miner.deployed[square_id] += amount;
|
||||
// Skip if square is not deployed to.
|
||||
if !should_deploy {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update square
|
||||
if is_first_move {
|
||||
square.miners[square_id][square.count[square_id] as usize] = miner.authority;
|
||||
square.count[square_id] += 1;
|
||||
// Get deployment metadata.
|
||||
let is_first_move = miner.deployed[square_id] == 0;
|
||||
let mut idx = if is_first_move {
|
||||
// Insert at end of the list.
|
||||
square.count[square_id] as usize
|
||||
} else {
|
||||
// Find the miner's index in the list.
|
||||
let mut idx = 0;
|
||||
for i in 0..16 {
|
||||
if square.miners[square_id][i] == miner.authority {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
idx
|
||||
};
|
||||
|
||||
// If the square is full, refund the miner with the smallest deployment and kick them off the square.
|
||||
if idx == 16 {
|
||||
// Find miner with the smallest deployment.
|
||||
let mut smallest_miner = Pubkey::default();
|
||||
let mut smallest_deployment = u64::MAX;
|
||||
for i in 0..16 {
|
||||
if square.deployed[square_id][i] < smallest_deployment {
|
||||
smallest_deployment = square.deployed[square_id][i];
|
||||
smallest_miner = square.miners[square_id][i];
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Update board
|
||||
board.deployed[square_id] += amount;
|
||||
board.total_deployed += amount;
|
||||
// Safety check.
|
||||
// This should never happen.
|
||||
assert!(smallest_miner != Pubkey::default());
|
||||
|
||||
// If deploy amount is less than smallest deployment, skip this square.
|
||||
if amount < smallest_deployment {
|
||||
continue 'deploy;
|
||||
}
|
||||
|
||||
// Refund the smallest miner and kick them off the square.
|
||||
for miner_info in miner_accounts {
|
||||
if *miner_info.key == miner_pda(smallest_miner).0 {
|
||||
let smallest_miner = miner_info
|
||||
.as_account_mut::<Miner>(&ore_api::ID)?
|
||||
.assert_mut(|m| m.authority == smallest_miner)?;
|
||||
smallest_miner.refund_sol += smallest_deployment;
|
||||
smallest_miner.deployed[square_id] -= smallest_deployment;
|
||||
refund_amounts[square_id] = smallest_deployment;
|
||||
refund_miner_infos[square_id] = Some(miner_info);
|
||||
|
||||
// Remove smallest miner from square
|
||||
board.deployed[square_id] -= smallest_deployment;
|
||||
board.total_deployed -= smallest_deployment;
|
||||
square.deployed[square_id][idx] -= smallest_deployment;
|
||||
square.miners[square_id][idx] = Pubkey::default();
|
||||
square.count[square_id] -= 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Safety check.
|
||||
// This should never happen.
|
||||
assert!(idx < 16);
|
||||
|
||||
// Safety check.
|
||||
// Skip if square count is >= 16. This can only happen if the signer didn't provide a miner account to refund.
|
||||
if square.count[square_id] >= 16 {
|
||||
continue 'deploy;
|
||||
}
|
||||
|
||||
// Update miner
|
||||
miner.deployed[square_id] += amount;
|
||||
|
||||
// Update square
|
||||
if is_first_move {
|
||||
square.miners[square_id][idx] = miner.authority;
|
||||
square.count[square_id] += 1;
|
||||
}
|
||||
|
||||
// Update board
|
||||
board.deployed[square_id] += amount;
|
||||
board.total_deployed += amount;
|
||||
|
||||
// Update square deployed
|
||||
square.deployed[square_id][idx] += amount;
|
||||
|
||||
// Update total fee and amount
|
||||
total_fee += fee;
|
||||
total_amount += amount;
|
||||
}
|
||||
|
||||
// Transfer SOL refunds.
|
||||
for (square_id, refund_amount) in refund_amounts.iter().enumerate() {
|
||||
if let Some(refund_miner_info) = refund_miner_infos[square_id] {
|
||||
board_info.send(*refund_amount, &refund_miner_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
|
||||
.as_account_mut::<Board>(&ore_api::ID)?
|
||||
.assert_mut(|b| b.slot_hash == [0; 32])?
|
||||
.assert_mut(|b| clock.slot > b.end_slot)?;
|
||||
let config = config_info.as_account_mut::<Config>(&ore_api::ID)?;
|
||||
config_info.as_account::<Config>(&ore_api::ID)?;
|
||||
let mint = mint_info.has_address(&MINT_ADDRESS)?.as_mint()?;
|
||||
let square = square_info.as_account_mut::<Square>(&ore_api::ID)?;
|
||||
let treasury = treasury_info.as_account_mut::<Treasury>(&ore_api::ID)?;
|
||||
@@ -141,25 +141,6 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
|
||||
// Update board.
|
||||
board.total_winnings = winnings;
|
||||
|
||||
// Update min deploy amount.
|
||||
let capacity: u64 = 16 * 25;
|
||||
let threshold = (capacity * 3) / 4;
|
||||
let mut occupancy = 0;
|
||||
for i in 0..25 {
|
||||
occupancy += square.count[i];
|
||||
}
|
||||
if occupancy == capacity {
|
||||
// If board is full, double the minimum deploy amount.
|
||||
config.min_deploy_amount = 1u64.max(config.min_deploy_amount * 2);
|
||||
} else if occupancy < threshold {
|
||||
// If board is less than 75% full, reduce minimum deploy amount linearly.
|
||||
let availability = capacity.saturating_sub(occupancy);
|
||||
let pct = (availability * 100) / capacity;
|
||||
let chg = (pct.saturating_sub(25) * 100) / 75;
|
||||
let dif = (config.min_deploy_amount * chg) / 100;
|
||||
config.min_deploy_amount = config.min_deploy_amount.saturating_sub(dif);
|
||||
}
|
||||
|
||||
// Emit event.
|
||||
program_log(
|
||||
&[board_info.clone(), ore_program.clone()],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use solana_program::pubkey;
|
||||
use steel::*;
|
||||
|
||||
pub const AUTHORIZED_ACCOUNTS: [Pubkey; 280] = [
|
||||
pub const AUTHORIZED_ACCOUNTS: [Pubkey; 264] = [
|
||||
pubkey!("pqspJ298ryBjazPAr95J9sULCVpZe3HbZTWkbC1zrkS"),
|
||||
pubkey!("HNWhK5f8RMWBqcA7mXJPaxdTPGrha3rrqUrri7HSKb3T"),
|
||||
pubkey!("6B9PjpHfbhPcSakS5UQ7ZctgbPujfsryVRpDecskGLiz"),
|
||||
@@ -248,22 +248,22 @@ pub const AUTHORIZED_ACCOUNTS: [Pubkey; 280] = [
|
||||
pubkey!("6Fg49wV8MGW5PeTTF1LoFRR8FzUGiMZXC3gWZiagAWzg"),
|
||||
pubkey!("BwCwfRRe2y6Rxv6SQZMRQ499TTakKnKEDbPofN8JQ7p"),
|
||||
pubkey!("5D1oAw6sE14YvdSPwGWGbFCj7SVTbivnTxWXxbvNrur6"),
|
||||
pubkey!("CqJ5a1XB3c2SLcAcxAvZQ4hzYmLTSAtMA6RBy8ovWmeY"),
|
||||
pubkey!("273HADhxAy3NWKdRiTTZQG6WukHz9TiJZeiQjnSe2pxG"),
|
||||
pubkey!("2JVo9kDtAn77vQC9KLrPBmJ2hnCnjaPpgQym6sCKnGRj"),
|
||||
pubkey!("DW9ugDkNyPxNz5egzBVV4EBdWMKv5hUbLgadA7TZysyg"),
|
||||
pubkey!("9W3B4bKyqBrGjaJKEjLStuRmLTf42fbSqCEiML7LHaoe"),
|
||||
pubkey!("9g4VpomWV3HoX6AgsjAVumysrLzMn49SxSbHm5xP8SUJ"),
|
||||
pubkey!("6ptnvnBHhR7bjgLK5ZimxKFhhHzNWeEdeNB8oZiCeaLM"),
|
||||
pubkey!("AGruT4qWZf3FNQEQewLw5NfFpMrMjDhgB8H8UGKQPwms"),
|
||||
pubkey!("7p2vJUJPG9pfRrzVans3zmYe1oDZdzS5YjYM8dP3L4EZ"),
|
||||
pubkey!("5SwFSBuYTmGcHvLbL9tQjZRKNgGNijzrCMVoQrrjXUSg"),
|
||||
pubkey!("CZdNF9Hz9ayGdDhVDvK4KhKCX2PS7BNkEp7cwJggAkvi"),
|
||||
pubkey!("8F18uJ2JaTGq38pL7qsdyP6TJkyxeSXQd1LcHmg8FpEZ"),
|
||||
pubkey!("9vMYgsTUpGSHnqjrgkQekzFq23eRpENnUESyZ3B9BzVT"),
|
||||
pubkey!("CXcLK7roVYsEZnN66fWq7h2DKSkfLmWaM3P9CvqfeQRh"),
|
||||
pubkey!("HPK2t9HkM4g2cVn4yaHz7tWwYLp9KwJFM4DTZkyBrwg5"),
|
||||
pubkey!("RX71VvEgsKh4fePR1XjywC3Nr9hmjSiBgcskCDMoGoH"),
|
||||
// pubkey!("CqJ5a1XB3c2SLcAcxAvZQ4hzYmLTSAtMA6RBy8ovWmeY"),
|
||||
// pubkey!("273HADhxAy3NWKdRiTTZQG6WukHz9TiJZeiQjnSe2pxG"),
|
||||
// pubkey!("2JVo9kDtAn77vQC9KLrPBmJ2hnCnjaPpgQym6sCKnGRj"),
|
||||
// pubkey!("DW9ugDkNyPxNz5egzBVV4EBdWMKv5hUbLgadA7TZysyg"),
|
||||
// pubkey!("9W3B4bKyqBrGjaJKEjLStuRmLTf42fbSqCEiML7LHaoe"),
|
||||
// pubkey!("9g4VpomWV3HoX6AgsjAVumysrLzMn49SxSbHm5xP8SUJ"),
|
||||
// pubkey!("6ptnvnBHhR7bjgLK5ZimxKFhhHzNWeEdeNB8oZiCeaLM"),
|
||||
// pubkey!("AGruT4qWZf3FNQEQewLw5NfFpMrMjDhgB8H8UGKQPwms"),
|
||||
// pubkey!("7p2vJUJPG9pfRrzVans3zmYe1oDZdzS5YjYM8dP3L4EZ"),
|
||||
// pubkey!("5SwFSBuYTmGcHvLbL9tQjZRKNgGNijzrCMVoQrrjXUSg"),
|
||||
// pubkey!("CZdNF9Hz9ayGdDhVDvK4KhKCX2PS7BNkEp7cwJggAkvi"),
|
||||
// pubkey!("8F18uJ2JaTGq38pL7qsdyP6TJkyxeSXQd1LcHmg8FpEZ"),
|
||||
// pubkey!("9vMYgsTUpGSHnqjrgkQekzFq23eRpENnUESyZ3B9BzVT"),
|
||||
// pubkey!("CXcLK7roVYsEZnN66fWq7h2DKSkfLmWaM3P9CvqfeQRh"),
|
||||
// pubkey!("HPK2t9HkM4g2cVn4yaHz7tWwYLp9KwJFM4DTZkyBrwg5"),
|
||||
// pubkey!("RX71VvEgsKh4fePR1XjywC3Nr9hmjSiBgcskCDMoGoH"),
|
||||
pubkey!("E8x8J8nJMNWrQXQF1BdBSY9QA12S9qmUycJPPjQhvz9H"),
|
||||
pubkey!("5EFvY7HwqUh5vfkcDtQAbQoNCdiEWL6eqG1zuiRihzk5"),
|
||||
pubkey!("BgVtFam2Xvj5vte1a5efvMC47uVdNugx6bqGzDLkBo6i"),
|
||||
|
||||
Reference in New Issue
Block a user