On-Chain Reference
Account Structures

Account Structures

Every piece of state in Sandbox GHI is stored in one of three account types. All are owned by the sandbox_ghi program.


MiningPool

Global singleton. Stores protocol-level state including the current halving epoch and total emissions.

PDA seeds: ["mining_pool"]

#[account]
pub struct MiningPool {
    pub authority: Pubkey,       // program upgrade authority
    pub ghi_mint: Pubkey,        // $GHI SPL token mint
    pub ghi_vault: Pubkey,       // token account holding mining rewards
    pub total_staked: u32,       // total NFTs currently staked
    pub epoch_start: i64,        // unix timestamp of contract deployment
    pub total_distributed: u64,  // cumulative $GHI distributed (u64, 6 decimals)
    pub bump: u8,
}
// Discriminator: 8 bytes
// Total size: 8 + 32 + 32 + 32 + 4 + 8 + 8 + 1 = 125 bytes

Halving epoch is derived at read time:

let year = (Clock::get()?.unix_timestamp - pool.epoch_start) / (86_400 * 365);

StakeAccount

Created per staked NFT. Tracks when the NFT was staked and when rewards were last claimed.

PDA seeds: ["stake", nft_mint.key(), owner.key()]

#[account]
pub struct StakeAccount {
    pub owner: Pubkey,       // wallet that staked the NFT
    pub nft_mint: Pubkey,    // mint address of the staked Agent NFT
    pub tier: Tier,          // Common | Rare | Legendary
    pub staked_at: i64,      // unix timestamp of initial stake
    pub last_claimed: i64,   // unix timestamp of last claim (= staked_at at creation)
    pub bump: u8,
}
// Total size: 8 + 32 + 32 + 1 + 8 + 8 + 1 = 90 bytes
 
#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq)]
pub enum Tier {
    Common,     // base_rate = 32 $GHI/day
    Rare,       // base_rate = 80 $GHI/day
    Legendary,  // base_rate = 320 $GHI/day
}

Reward Calculation

Rewards are calculated lazily — never stored, always computed on-chain at claim/unstake time:

pub fn calculate_rewards(stake: &StakeAccount, pool: &MiningPool, now: i64) -> u64 {
    let elapsed_seconds = now - stake.last_claimed;
    let elapsed_days = elapsed_seconds as u64 / 86_400;
 
    // halving: year 0 = full rate, year 1 = half, year 2 = quarter...
    let year = (now - pool.epoch_start) / (86_400 * 365);
    let base_rate = match stake.tier {
        Tier::Common    => 32_000_000,  // 32 $GHI (6 decimals)
        Tier::Rare      => 80_000_000,  // 80 $GHI
        Tier::Legendary => 320_000_000, // 320 $GHI
    };
 
    let current_rate = base_rate >> year; // bitshift = halving
    elapsed_days * current_rate
}

$GHI uses 6 decimal places — consistent with most Solana SPL tokens. All amounts in the program are in raw units (e.g., 32_000_000 = 32 $GHI).


AgentAccount

Created when a user deploys an Agent Forge agent. Stores agent configuration, $GHI budget, and reputation.

PDA seeds: ["agent", nft_mint.key(), owner.key()]

#[account]
pub struct AgentAccount {
    pub owner: Pubkey,         // NFT owner / agent controller
    pub nft_mint: Pubkey,      // Agent NFT that backs this agent
    pub task_type: TaskType,   // Monitor | Trader | Optimizer | Custom
    pub ghi_budget: u64,       // remaining $GHI budget for task execution
    pub reputation: u64,       // cumulative reputation score
    pub tasks_completed: u32,  // total tasks completed
    pub deployed_at: i64,      // unix timestamp of deployment
    pub is_active: bool,       // false when paused or closed
    pub bump: u8,
}
// Total size: 8 + 32 + 32 + 1 + 8 + 8 + 4 + 8 + 1 + 1 = 103 bytes
 
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub enum TaskType {
    Monitor,    // watches on-chain conditions, triggers actions
    Trader,     // executes trades by configurable strategy
    Optimizer,  // manages LP positions / portfolio rebalancing
    Custom,     // user-defined task logic
}

Reputation Formula

reputation += task_weight * completion_bonus;
// task_weight: set per task type by protocol (1–10)
// completion_bonus: 100 for on-time, 50 for late, 0 for failed

Token Accounts (SPL)

Sandbox GHI uses standard SPL token accounts — no custom token logic:

AccountDescription
GHI VaultPDA-owned ATA holding all mining reserve
User ATAAssociated Token Account created at first claim
Agent ATAAgent's own ATA — can hold and spend $GHI autonomously