Pause the contract (emergency stop)
When paused, all user-facing functions are disabled except admin functions. This is an emergency mechanism to protect user funds in case of discovered vulnerabilities.
NotAdmin - If caller is not the adminfn pause(env: soroban_sdk::Env) -> Result<(), soroban_sdk::Error>
Check if a contract is an approved game
fn is_game(env: soroban_sdk::Env, id: soroban_sdk::Address) -> bool
Unpause the contract
Restores normal contract functionality after emergency pause.
NotAdmin - If caller is not the adminfn unpause(env: soroban_sdk::Env) -> Result<(), soroban_sdk::Error>
Update the contract WASM hash (upgrade contract)
NotAdmin - If caller is not the adminfn upgrade(
env: soroban_sdk::Env,
new_wasm_hash: soroban_sdk::BytesN<32>,
) -> Result<(), soroban_sdk::Error>
Add a game contract to the approved list
NotAdmin - If caller is not the adminfn add_game(
env: soroban_sdk::Env,
id: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
End a game session with outcome verification
Requires game contract authorization. Both players' FP wagers are spent/burned. Only the winner's wager contributes to their faction standings. ZK proof verification handled client-side for MVP.
SessionNotFound - If session doesn't existInvalidSessionState - If session is not PendingInvalidGameOutcome - If outcome data doesn't match sessionProofVerificationFailed - If ZK proof is invalidfn end_game(
env: soroban_sdk::Env,
game_id: soroban_sdk::Address,
session_id: u32,
proof: soroban_sdk::Bytes,
outcome: GameOutcome,
) -> Result<(), soroban_sdk::Error>
Get the admin address
fn get_admin(env: soroban_sdk::Env) -> soroban_sdk::Address
Get epoch information
Returns current epoch if no number specified, otherwise the specified epoch.
EpochNotFinalized - If requested epoch doesn't existfn get_epoch(
env: soroban_sdk::Env,
epoch: Option,
) -> Result
Check if contract is paused
fn is_paused(env: soroban_sdk::Env) -> bool
Update the admin address
NotAdmin - If caller is not the current adminfn set_admin(
env: soroban_sdk::Env,
new_admin: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
Get the current configuration
fn get_config(env: soroban_sdk::Env) -> Config
Get player information
Returns complete persistent player data including selected faction, total deposited, and deposit timestamp.
UserNotFound - If user has never interacted with the contractfn get_player(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
) -> Result
Start a new game session
Locks factions and fp for both players. If this is a player's first game in the epoch, initializes their fp and locks their faction.
GameNotWhitelisted - If game_id is not approvedSessionAlreadyExists - If session_id already existsInvalidAmount - If wagers are <= 0InsufficientFactionPoints - If players don't have enough fpContractPaused - If contract is in emergency pause modefn start_game(
env: soroban_sdk::Env,
game_id: soroban_sdk::Address,
session_id: u32,
player1: soroban_sdk::Address,
player2: soroban_sdk::Address,
player1_wager: i128,
player2_wager: i128,
) -> Result<(), soroban_sdk::Error>
Cycle to the next epoch
Finalizes current epoch (determines winner, withdraws BLND, swaps to USDC, sets reward pool) and opens next epoch.
The new epoch number
EpochNotReady - If not enough time has passedEpochAlreadyFinalized - If current epoch is already finalizedFeeVaultError - If fee-vault operations failSwapError - If BLND → USDC swap failsfn cycle_epoch(env: soroban_sdk::Env) -> Result
Remove a game contract from the approved list
NotAdmin - If caller is not the adminfn remove_game(
env: soroban_sdk::Env,
id: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
Initialize the contract
Sets up the admin, external contract addresses, and creates the first epoch.
admin - Admin address (can modify config and upgrade contract)fee_vault - fee-vault-v2 contract addresssoroswap_router - Soroswap router contract addressblnd_token - BLND token addressusdc_token - USDC token addressepoch_duration - Duration of each epoch in seconds (default: 345,600 = 4 days)reserve_token_ids - Reserve token IDs for claiming BLND emissions (e.g., vec![&env, 1] for reserve 0 b-tokens)AlreadyInitialized - If contract has already been initializedfn __constructor(
env: soroban_sdk::Env,
admin: soroban_sdk::Address,
fee_vault: soroban_sdk::Address,
soroswap_router: soroban_sdk::Address,
blnd_token: soroban_sdk::Address,
usdc_token: soroban_sdk::Address,
epoch_duration: u64,
reserve_token_ids: soroban_sdk::Vec,
) -> Result<(), soroban_sdk::Error>
Update global configuration
Allows admin to update specific configuration parameters. Only updates parameters that are provided (non-None).
new_fee_vault - New fee-vault-v2 contract address (optional)new_soroswap_router - New Soroswap router contract address (optional)new_blnd_token - New BLND token address (optional)new_usdc_token - New USDC token address (optional)new_epoch_duration - New epoch duration in seconds (optional)new_reserve_token_ids - New reserve token IDs for claiming BLND emissions (optional)NotAdmin - If caller is not the adminfn update_config(
env: soroban_sdk::Env,
new_fee_vault: Option,
new_soroswap_router: Option,
new_blnd_token: Option,
new_usdc_token: Option,
new_epoch_duration: Option,
new_reserve_token_ids: Option>,
) -> Result<(), soroban_sdk::Error>
Select a faction for the user
Sets the user's persistent faction preference. Can be changed at ANY time. If you haven't played a game this epoch, the new faction applies immediately. If you've already played this epoch, the current epoch stays locked to your old faction, and the new selection applies starting next epoch.
faction - Faction ID (0=WholeNoodle, 1=PointyStick, 2=SpecialRock)InvalidFaction - If faction ID is not 0, 1, or 2fn select_faction(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
faction: u32,
) -> Result<(), soroban_sdk::Error>
Get the reward pool (USDC) for a finalized epoch
EpochNotFinalized - If epoch doesn't exist or isn't finalizedfn get_reward_pool(
env: soroban_sdk::Env,
epoch: u32,
) -> Result
Get player's epoch-specific information
Returns complete epoch-specific data including locked faction, available/locked FP, total FP contributed, and initial balance snapshot.
If the user exists but hasn't played this epoch yet, returns a valid EpochUser with:
UserNotFound - If user has never interacted with the contractfn get_epoch_player(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
) -> Result
Check if a user's faction is locked for the current epoch
Once locked (after first game), faction cannot be changed until next epoch.
fn is_faction_locked(env: soroban_sdk::Env, user: soroban_sdk::Address) -> bool
Claim epoch reward for a user for a specific epoch
Users who contributed FP to the winning faction can claim their share of the epoch's reward pool (USDC converted from BLND yield).
Amount of USDC claimed
EpochNotFinalized - If epoch doesn't exist or isn't finalizedRewardAlreadyClaimed - If user already claimed for this epochNotWinningFaction - If user wasn't in the winning factionNoRewardsAvailable - If user has no rewards to claimContractPaused - If contract is in emergency pause modefn claim_epoch_reward(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
epoch: u32,
) -> Result
Get the winning faction for a finalized epoch
EpochNotFinalized - If epoch doesn't exist or isn't finalizedfn get_winning_faction(
env: soroban_sdk::Env,
epoch: u32,
) -> Result
Check if user has claimed rewards for an epoch
fn has_claimed_rewards(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
epoch: u32,
) -> bool
Calculate how much a user would receive if they claimed now
This doesn't actually claim, just calculates the amount. Useful for UIs to show pending rewards.
Amount user would receive, or 0 if not eligible
fn get_claimable_amount(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
epoch: u32,
) -> i128
Get faction standings for a specific epoch
Returns a map of faction ID to total faction points.
EpochNotFinalized - If epoch doesn't existfn get_faction_standings(
env: soroban_sdk::Env,
epoch: u32,
) -> Result, soroban_sdk::Error>