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, 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 HITZ fees (also the oracle updater)hitz_token - HITZ token contract address (OpenZeppelin token)base_fee - Base fee per difficulty unit in stroops (default 1,000,000 = 0.1 HITZ)fn init(
env: soroban_sdk::Env,
admin: soroban_sdk::Address,
treasury: soroban_sdk::Address,
hitz_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., 1,000,000 = 0.1 HITZ)fn set_base_fee(env: soroban_sdk::Env, new_base_fee: i128)
NOTE: withdraw_xlm_to_treasury() removed - no longer needed in HITZ-only economy Update oracle price (treasury-only)
Treasury bot calls this after fetching current market price from DEX. This price is used for dynamic staking calculations.
caller - Treasury address (must be the configured Treasury)new_price - New HITZ/USDC price in stroops (e.g., 1,000,000 = $0.10 USDC 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) Price is in USDC stroops per HITZ (e.g., 1,000,000 = $0.10 USDC per HITZ)
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 specifies the investment in HITZ stroops (min 3 HITZ = 30,000,000 stroops), 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: 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.
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 from the STAKER pool. If artist equity exists, stakers share (100% - total_artist_equity) of rewards. Formula: claimable = (staker_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 staker (accounts for artist equity)
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, escrow, 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)
Set non-dilutable artist equity for an entry (admin-only)
Allows verified artists to receive a fixed percentage of all rewards. Multiple artists can have equity on the same entry (collaborations).
entry_id - Entry to assign equity to (must exist)artist - Artist's wallet addressequity_bps - Equity in basis points (1-9990, where 100 = 1%, 9990 = 99.9%)fn set_artist_equity(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
artist: soroban_sdk::Address,
equity_bps: u32,
)
Artist claims their non-dilutable equity rewards
entry_id - Entry to claim fromartist - Artist's address (must match stored equity, requires auth)Amount of HITZ claimed
fn claim_artist_equity(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
artist: soroban_sdk::Address,
) -> i128
Get artist equity info for an entry
(equity_bps, claimed_amount, claimable_amount) or (0, 0, 0) if no equity
fn get_artist_equity(
env: soroban_sdk::Env,
entry_id: soroban_sdk::String,
artist: soroban_sdk::Address,
) -> (u32, i128, i128)
Get total artist equity for an entry (sum of all artists)
Total equity in basis points (0-9990)
fn get_total_artist_equity(env: soroban_sdk::Env, entry_id: soroban_sdk::String) -> u32
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,
)