mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-13 15:09:57 +00:00
93 lines
2.8 KiB
Rust
93 lines
2.8 KiB
Rust
use steel::*;
|
|
|
|
use crate::state::{stake_pda, Treasury};
|
|
|
|
use super::OreAccount;
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
|
|
pub struct Stake {
|
|
/// The authority of this miner account.
|
|
pub authority: Pubkey,
|
|
|
|
/// The balance of this stake account.
|
|
pub balance: u64,
|
|
|
|
/// The timestamp of last claim.
|
|
pub last_claim_at: i64,
|
|
|
|
/// The timestamp the last time this staker deposited.
|
|
pub last_deposit_at: i64,
|
|
|
|
/// The timestamp the last time this staker withdrew.
|
|
pub last_withdraw_at: i64,
|
|
|
|
/// The rewards factor last time rewards were updated on this stake account.
|
|
pub rewards_factor: Numeric,
|
|
|
|
/// The amount of ORE this staker can claim.
|
|
pub rewards: u64,
|
|
|
|
/// The total amount of ORE this staker has earned over its lifetime.
|
|
pub lifetime_rewards: u64,
|
|
|
|
/// Flag indicating whether this staker is associated with a Solana Seeker.
|
|
pub is_seeker: u64,
|
|
}
|
|
|
|
impl Stake {
|
|
pub fn pda(&self) -> (Pubkey, u8) {
|
|
stake_pda(self.authority)
|
|
}
|
|
|
|
pub fn claim(&mut self, amount: u64, clock: &Clock, treasury: &Treasury) -> u64 {
|
|
self.update_rewards(treasury);
|
|
let amount = self.rewards.min(amount);
|
|
self.rewards -= amount;
|
|
self.last_claim_at = clock.unix_timestamp;
|
|
amount
|
|
}
|
|
|
|
pub fn deposit(
|
|
&mut self,
|
|
amount: u64,
|
|
clock: &Clock,
|
|
treasury: &mut Treasury,
|
|
sender: &TokenAccount,
|
|
) -> u64 {
|
|
self.update_rewards(treasury);
|
|
let amount = sender.amount().min(amount);
|
|
self.balance += amount;
|
|
self.last_deposit_at = clock.unix_timestamp;
|
|
treasury.total_staked += amount;
|
|
amount
|
|
}
|
|
|
|
pub fn withdraw(&mut self, amount: u64, clock: &Clock, treasury: &mut Treasury) -> u64 {
|
|
self.update_rewards(treasury);
|
|
let amount = self.balance.min(amount);
|
|
self.balance -= amount;
|
|
self.last_withdraw_at = clock.unix_timestamp;
|
|
treasury.total_staked -= amount;
|
|
amount
|
|
}
|
|
|
|
pub fn update_rewards(&mut self, treasury: &Treasury) {
|
|
// Accumulate rewards, weighted by stake balance.
|
|
if treasury.rewards_factor > self.rewards_factor {
|
|
let accumulated_rewards = treasury.rewards_factor - self.rewards_factor;
|
|
if accumulated_rewards < Numeric::ZERO {
|
|
panic!("Accumulated rewards is negative");
|
|
}
|
|
let personal_rewards = accumulated_rewards * Numeric::from_u64(self.balance);
|
|
self.rewards += personal_rewards.to_u64();
|
|
self.lifetime_rewards += personal_rewards.to_u64();
|
|
}
|
|
|
|
// Update this stake account's last seen rewards factor.
|
|
self.rewards_factor = treasury.rewards_factor;
|
|
}
|
|
}
|
|
|
|
account!(OreAccount, Stake);
|