Skip to main content

tengu_api/state/
treasury.rs

1use super::DojosAccount;
2use steel::*;
3
4#[repr(C)]
5#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
6pub struct Treasury {
7    /// Treasury SOL balance (lamports) for buybacks.
8    pub balance: u64,
9    /// Total Spirit Power of all assigned shoguns (for % display).
10    pub total_spirit_power: u64,
11    /// Total in-game soft currency burned (dine, upgrades, shop). Not raw SPL-only transfers.
12    pub total_shards_burned: u64,
13    /// Total $DOJO minted to players from `claim_shards` (cumulative).
14    pub total_refined: u64,
15    /// Last slot at which emission was run (keeper / gameplay). Used to compute next emission.
16    pub last_emission_slot: u64,
17    /// Sum of each dojo's **dojo-wide** effective SP: `effective_spirit_power_with_scene(sum_raw, scene)`.
18    /// Must match how `claim_shards` weights users (one flat/pct bonus per dojo, not per shogun).
19    pub total_effective_spirit_power: u64,
20    /// SOL (lamports) earmarked for XP reward claims (subset of `balance` accounting).
21    pub xp_reward_pool: u64,
22    /// Sum of all dojos' `dojo.xp` (stake + activity reward points). Weight for `claim_xp_rewards` SOL share.
23    pub total_xp: u64,
24}
25
26account!(DojosAccount, Treasury);
27
28impl Treasury {
29    /// Credits `balance` and `xp_reward_pool` together when lamports arrive from the standard
30    /// protocol SOL split (`to_treasury`, or `to_staking` when routed to treasury with no stakers).
31    pub fn credit_sol_from_protocol_revenue(&mut self, lamports: u64) {
32        self.balance = self.balance.saturating_add(lamports);
33        self.xp_reward_pool = self.xp_reward_pool.saturating_add(lamports);
34    }
35
36    /// Effective SP for pool-split: (raw_sp + flat_bonus) * (1 + pct_bps/10000).
37    /// Used so scene bonuses shift share without increasing total emissions.
38    pub fn effective_spirit_power_with_scene(raw_sp: u64, scene_id: u64) -> u64 {
39        let (flat, pct_bps) = crate::utils::scene_bonus(scene_id);
40        let base = raw_sp.saturating_add(flat);
41        if pct_bps == 0 {
42            base
43        } else {
44            base.saturating_mul(10000 + pct_bps) / 10000
45        }
46    }
47}