Upgrade core contract to new WASM code (admin-only)
Note: Named upgrade_core to avoid export name collision with token's upgrade.
fn upgrade_core(env: soroban_sdk::Env, new_wasm_hash: soroban_sdk::BytesN<32>)
Reset instance storage (admin-only)
CRITICAL: This clears instance configuration. Contract will be unusable until re-initialized. Use with extreme caution during upgrades only when you need to change core parameters.
Clears: Admin, Treasury, HitzToken, XlmToken, BaseFee, Oracle settings, Emission settings Preserves: Persistent data (entries, stakes, rewards, TotalMinted, EntryCount)
After calling this, you MUST call init() again to restore functionality.
fn reset_instance(env: soroban_sdk::Env)
Admin-only: remove entries in chunks to stay under footprint limits. Removes entries at indexes [start, start+limit) using EntryAt(i).
fn reset_entries_chunk(env: soroban_sdk::Env, start: u32, limit: u32)
Helper to introspect entry count before chunking.
fn entry_count(env: soroban_sdk::Env) -> u32
Admin-only: remove one entry by its position (EntryAt(i)) and related keys.
fn reset_entry_by_pos(env: soroban_sdk::Env, i: u32)
Initialize the contract (one-time only)
admin - Admin address with privileged rightstreasury - Treasury address receiving all XLM fees (also the oracle updater)hitz_token - HITZ token contract address (OpenZeppelin token)xlm_token - XLM token contract address (SAC)base_fee - Base fee per difficulty unit in stroops (default 100,000 = 0.01 XLM)fn init(
env: soroban_sdk::Env,
admin: soroban_sdk::Address,
treasury: soroban_sdk::Address,
hitz_token: soroban_sdk::Address,
xlm_token: soroban_sdk::Address,
base_fee: i128,
)
Update base fee (admin-only)
new_base_fee - New base fee per difficulty unit in stroops (e.g., 100,000 = 0.01 XLM)fn set_base_fee(env: soroban_sdk::Env, new_base_fee: i128)
Transfer all contract XLM balance to treasury (admin-only)
Used to recover XLM that may be locked in the contract after upgrade/reset. Transfers the entire XLM balance of the contract to the treasury address.
The amount of XLM transferred in stroops
fn withdraw_xlm_to_treasury(env: soroban_sdk::Env) -> i128
Update oracle price (treasury-only)
Treasury bot calls this after fetching current market price from DEX. This price is used for dynamic emission rate calculations.
caller - Treasury address (must be the configured Treasury)new_price - New HITZ/XLM price in stroops (e.g., 100,000 = 0.01 XLM per HITZ)fn update_oracle_price(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
new_price: i128,
)
Get oracle data (price and last update timestamp)
Returns (price_in_stroops, last_update_timestamp)
fn get_oracle_data(env: soroban_sdk::Env) -> (i128, u64)
Get current base fee
fn get_base_fee(env: soroban_sdk::Env) -> i128
Get total HITZ supply minted so far Returns the total amount of HITZ tokens minted by this contract in stroops
fn get_total_supply(env: soroban_sdk::Env) -> i128
Get remaining HITZ tokens that can be minted Returns the amount of HITZ remaining before hitting the 21M cap, in stroops
fn get_remaining_supply(env: soroban_sdk::Env) -> i128
Create a new entry (admin-only) SECURITY: Limited to MAX_ENTRIES to prevent DOS
fn create_entry(env: soroban_sdk::Env, entry_id: soroban_sdk::String)
Record a user action (main entrypoint)
Handles fee transfer, reward calculation, and optional auto-staking For invest action, amount_xlm specifies the investment (min 0.3 XLM), ignored for other actions
fn record_action(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
entry_id: soroban_sdk::String,
kind: soroban_sdk::Symbol,
amount_xlm: Option,
)
Get entry data
fn get_entry(env: soroban_sdk::Env, entry_id: soroban_sdk::String) -> Option
List entry IDs with pagination
fn list_entries(
env: soroban_sdk::Env,
start: u32,
limit: u32,
) -> soroban_sdk::Vec
Get user's stake for an entry
fn get_stake(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
owner: soroban_sdk::Address,
) -> i128
Get total stake for an entry
fn get_stake_total(env: soroban_sdk::Env, entry_id: soroban_sdk::String) -> i128
Contract version Distribute HITZ rewards proportionally based on escrow performance
Treasury bot calls this after buying HITZ with accumulated XLM fees. Contract automatically distributes to entries based on their escrow_xlm.
caller - Treasury address that holds the HITZhitz_amount - Total HITZ to distribute across all entriesOptimized to single loop - O(n) where n = number of entries SECURITY: Limited to 1000 entries to prevent DOS
fn distribute_rewards(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
hitz_amount: i128,
)
Calculate total escrow in batches (Phase 1 of 3-phase distribution)
caller - Treasury addressstart_index - Starting entry index for this batchbatch_size - Number of entries to process (max 40 for read-only)(u32, i128) - (next_start_index, running_total_escrow)Call repeatedly with increasing start_index until next_start_index >= entry_count
fn calculate_total_escrow_batch(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
start_index: u32,
batch_size: u32,
) -> (u32, i128)
Initialize distribution with HITZ transfer (Phase 2 of 3-phase distribution)
Call this AFTER calculate_total_escrow_batch is complete
caller - Treasury address that holds the HITZhitz_amount - Total HITZ to distributefn initialize_distribution(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
hitz_amount: i128,
)
Distribute HITZ rewards in batches (Phase 3 of 3-phase distribution)
Call this AFTER initialize_distribution
caller - Treasury addressstart_index - Starting entry index for this batchbatch_size - Number of entries to process in this batch (max 15)u32 - Next start_index to use, or entry_count if completefn distribute_rewards_batch(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
start_index: u32,
batch_size: u32,
) -> u32
Allocate HITZ rewards to a specific entry's reward pool
Admin-only function for manual reward allocation (e.g., promotions, bonuses)
fn allocate_rewards(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
hitz_amount: i128,
)
Batch allocate rewards to multiple entries
Admin-only function for manual batch allocation (e.g., campaigns, airdrops)
fn batch_allocate_rewards(
env: soroban_sdk::Env,
entry_ids: soroban_sdk::Vec,
amounts: soroban_sdk::Vec,
)
Claim HITZ rewards from an entry's reward pool
Stakers receive rewards proportional to their stake Formula: claimable = (reward_pool × user_stake) / total_stake - already_claimed
fn claim_rewards(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
claimer: soroban_sdk::Address,
) -> i128
Unstake HITZ tokens from an entry
Allows users to withdraw their staked HITZ back to their wallet. User loses their stake percentage and future rewards from this entry.
entry_id - The entry to unstake fromcaller - The user unstaking (must have stake)amount - Amount of HITZ to unstake (in stroops)Amount unstaked
fn unstake(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
caller: soroban_sdk::Address,
amount: i128,
) -> i128
Get claimable HITZ rewards for a user
fn get_claimable_rewards(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
user: soroban_sdk::Address,
) -> i128
Get reward pool size for an entry
fn get_reward_pool(env: soroban_sdk::Env, entry_id: soroban_sdk::String) -> i128
Calculate APR for an entry based on HITZ rewards
APR = ((reward_pool / total_stake) / days_since_creation) × 365 × 100 Returns APR as basis points (1% = 100, 10% = 1000)
fn calculate_apr(env: soroban_sdk::Env, entry_id: soroban_sdk::String) -> i128
Get comprehensive entry statistics for ranking
Returns: (tvl_xlm, escrow_xlm, total_stake_hitz, reward_pool_hitz, apr_basis_points)
fn get_entry_stats(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
) -> (i128, i128, i128, i128, i128)
fn version(env: soroban_sdk::Env) -> u32
Merge one entry into another (admin-only).
All escrow, TVL, reward pool, and stakes move from from_id to into_id.
The from_id entry is removed from storage and index.
For stake migration:
stakers list is provided: migrates those users' stakes from from_id to into_idstakers is empty: only moves totals (admin must ensure no orphaned stakes)Note: We cannot iterate all stakers (no index), so admin must provide the list. Use off-chain indexing or events to track stakers.
fn merge_entries(
env: soroban_sdk::Env,
from_id: soroban_sdk::String,
into_id: soroban_sdk::String,
stakers: soroban_sdk::Vec,
)
Remove an entry completely (admin-only).
If stakers list is provided:
If stakers is empty:
Note: We cannot iterate all stakers (no index), so admin must provide the list. Use off-chain indexing or events to track stakers.
fn remove_entry(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
stakers: soroban_sdk::Vec,
)