A faction-based competitive gaming protocol built on Stellar's Soroban smart contract platform. Ohloss combines DeFi yield generation with gaming mechanics, enabling players to compete using faction points earned from their deposits.
Ohloss creates a gamified DeFi experience where:
- Players deposit assets into a yield-generating vault (via Blend protocol's fee-vault-v2)
- Earn faction points (FP) based on deposit amount and time held (asymptotic multipliers)
- Choose a faction: WholeNoodle (0), PointyStick (1), or SpecialRock (2)
- Compete in games by wagering faction points against other players
- Win rewards every 4-day epoch - the faction with the most contributed FP shares the accumulated BLND yield (auto-converted to USDC)
- Deposit/Withdrawal: Players interact directly with fee-vault-v2 for yield generation
- Faction Points System: Dynamic multipliers based on amount ($1,000 asymptote) and time (35-day asymptote)
- Game Sessions: Wager FP in whitelisted game contracts with oracle verification
- Epoch System: 4-day cycles with automatic yield distribution to winning faction
- Reward Claims: Proportional USDC rewards based on FP contribution
- Emergency Pause: Admin can halt all player functions in case of vulnerabilities
- Game Authorization: Only whitelisted game contracts can submit outcomes via
require_auth() - TTL Management: Automatic storage extension (7-day threshold, 30-day extension)
- FP Reset Logic: >50% withdrawals during epoch reset time multiplier to prevent gaming
- Reentrancy Protection: Soroban's authorization framework provides protocol-level protection
- ✅ 61/61 comprehensive tests passing
- ✅ All critical features implemented and tested
- ✅ Security documentation complete
- ✅ Ready for testnet deployment and external audit
ohloss/
├── contracts/
│ ├── ohloss/ # Main Ohloss contract
│ │ ├── src/
│ │ │ ├── lib.rs # Main contract interface (27 exported functions)
│ │ │ ├── types.rs # Data structures and configuration
│ │ │ ├── storage.rs # Storage utilities and TTL management
│ │ │ ├── vault.rs # Balance queries and cross-epoch comparison
│ │ │ ├── faction.rs # Faction selection and locking
│ │ │ ├── faction_points.rs # FP calculation with multipliers
│ │ │ ├── game.rs # Game lifecycle (start/end)
│ │ │ ├── epoch.rs # Epoch cycling and BLND→USDC conversion
│ │ │ ├── rewards.rs # Reward distribution
│ │ │ ├── events.rs # Event emissions (#[contractevent])
│ │ │ ├── errors.rs # Error definitions
│ │ │ ├── fee_vault_v2.rs # Fee vault client interface
│ │ │ ├── router.rs # Soroswap router client interface
│ │ │ └── tests/ # Comprehensive test suite
│ │ └── Cargo.toml
│ └── number-guess/ # Example game contract
├── bunt/ # TypeScript bindings and E2E tests (Bun runtime)
├── ohloss-frontend/ # Main frontend (Passkey smart wallets)
├── game-frontend/ # Number Guess game UI
├── api-worker/ # Cloudflare Worker API proxy
├── fp_simulations/ # Python multiplier simulations
├── docs/ # Technical documentation
├── CLAUDE.md # AI assistant development guide
├── AGENTS.md # MCP tools and agent reference
├── CHITSHEET.md # Contract addresses and deployment commands
├── Cargo.toml # Workspace configuration
└── README.md # This file
- Rust 1.84.0+ with
wasm32v1-nonetarget - Stellar CLI (latest version)
- Bun (for TypeScript tests, NOT Node.js)
# Install Rust target
rustup target add wasm32v1-none
# Install Stellar CLI
cargo install --locked stellar-cli --features opt
# Install Bun (macOS/Linux)
curl -fsSL https://bun.sh/install | bashcd contracts/ohloss
stellar contract buildOutput: target/wasm32v1-none/release/ohloss.wasm
# Rust unit and integration tests
cargo test
# TypeScript integration tests (requires Bun)
cd bunt
bun install
bun testCurrent Status: 61/61 Rust tests passing ✅
# Deploy contract
stellar contract deploy \
--wasm target/wasm32v1-none/release/ohloss.wasm \
--source admin \
--network testnet
# Initialize contract
stellar contract invoke \
--id <CONTRACT_ID> \
--source admin \
--network testnet \
-- __constructor \
--admin <ADMIN_ADDR> \
--fee_vault <VAULT_ADDR> \
--soroswap_router <ROUTER_ADDR> \
--blnd_token <BLND_ADDR> \
--usdc_token <USDC_ADDR> \
--epoch_duration 300 # 5 minutes for testing (default: 345600 = 4 days)Status: Live on mainnet. See CHITSHEET.md for contract addresses.
# Current mainnet contract
OHLOSS=CBOM2KGQDK4TMTIULH2UJWNLWEIXG47IM2RND4UDGM7KK5EQUQDFOVAYOhloss integrates with three external Soroban contracts:
-
fee-vault-v2 (script3/fee-vault-v2)
- Yield-generating vault for BLND token
- Players interact directly for deposits/withdrawals
- Ohloss queries balances and acts as admin to withdraw accumulated fees
- Methods:
deposit(),withdraw(),get_underlying_tokens(),admin_withdraw()
-
Soroswap Router (soroswap/core)
- DEX for BLND → USDC conversion during epoch cycling
- Method:
swap_exact_tokens_for_tokens()
-
soroban-fixed-point-math (kalepail/soroban-fixed-point-math)
- Safe fixed-point arithmetic library
- Methods:
fixed_mul_floor(),fixed_div_floor()
FP uses asymptotic multipliers to reward larger deposits and longer holding times:
fp = base_deposit × amount_multiplier × time_multiplier
Amount Multiplier: Asymptotic curve toward $1,000 USD
multiplier = 1.0 + (amount_usd / (amount_usd + $1000))
- $0 → 1.0x
- $1,000 → ~1.5x
- $3,000 → ~1.75x
- $9,000 → ~1.9x
Time Multiplier: Asymptotic curve toward 35 days
multiplier = 1.0 + (time_held_seconds / (time_held_seconds + 35_days))
- 0 days → 1.0x
- 35 days → ~1.5x
- 70 days → ~1.67x
Reset Penalty: Withdrawing >50% of epoch balance resets timestamp to 0, dropping time multiplier back to 1.0x.
- Deposit: Player deposits USDC directly into fee-vault-v2 (earns BLND yield)
- Select Faction: Choose WholeNoodle, PointyStick, or SpecialRock
- Start Game: Wager FP against another player (faction locks on first game of epoch)
- Play: Off-chain gameplay with oracle verification
- End Game: Winner gains FP from loser, contributes to faction standings
- Epoch End: After 4 days, winning faction shares USDC rewards proportionally
- Claim Rewards: Players claim their share of the reward pool
Every 4 days (345,600 seconds):
- Determine winning faction (highest total FP contributed)
- Withdraw accumulated BLND from fee-vault admin balance
- Convert BLND → USDC via Soroswap
- Set reward pool (USDC amount)
- Players from winning faction can claim proportional rewards
__constructor- Initialize contractset_admin- Update admin addressget_admin- Query admin addressupdate_config- Update epoch durationupgrade- Update contract WASMpause/unpause- Emergency controlsis_paused- Query pause state
add_game- Whitelist game contractremove_game- Remove game contractis_game- Check if contract is whitelisted
get_vault_balance- Query player's vault balance (via fee-vault-v2)
Note: Players deposit/withdraw directly via fee-vault-v2, not through Ohloss.
select_faction- Choose faction (WholeNoodle/PointyStick/SpecialRock)is_faction_locked- Check if faction is locked for epoch
start_game- Lock FP and start game sessionend_game- Verify outcome and spend FP (winner's FP contributes to faction)
get_epoch- Get epoch informationcycle_epoch- Finalize epoch and start nextget_faction_standings- Query faction FP totalsget_winning_faction- Get winner of finalized epochget_reward_pool- Get USDC reward pool for epoch
claim_yield- Claim USDC rewards for finalized epochget_claimable_amount- Calculate pending rewardshas_claimed_rewards- Check if player claimed for epoch
get_player- Get persistent player dataget_epoch_player- Get epoch-specific player data
Always research latest versions before adding/updating dependencies.
# 1. Add to workspace (root Cargo.toml)
[workspace.dependencies]
new-package = "x.y.z"
# 2. Use in contract (contracts/ohloss/Cargo.toml)
[dependencies]
new-package = { workspace = true }Critical: All dependencies must use the same soroban-sdk version (currently 23.1.0).
cd bunt
stellar contract bindings typescript \
--wasm ../contracts/ohloss/target/wasm32v1-none/release/ohloss.wasm \
--output-dir ./bindings/ohloss \
--contract-id <CONTRACT_ID>// Rust tests in contracts/ohloss/src/tests/
#[test]
fn test_deposit_withdraw() {
let env = Env::default();
// ... test logic
}// TypeScript tests in bunt/test/ (uses Bun)
import { test, expect } from "bun:test";
test("deposit increases balance", async () => {
// ... test logic
});If you're building a game that integrates with OHLOSS, use the OHLOSS Game Studio starter kit. It includes a mock OHLOSS contract, example games, deployment scripts for testnet, and a frontend scaffold.
- PLAN.md - Detailed technical specification
- SECURITY.md - Security analysis and attack mitigation
- PRODUCTION_READINESS.md - Production deployment checklist
- CLAUDE.md - AI assistant development guide
- AGENTS.md - MCP tools and agent reference
- OG_PLAN.md - Original requirements
- CHITSHEET.md - Contract addresses and deployment commands
Version: 1.0.0 Build Status: ✅ Successful Test Status: ✅ 61/61 Tests Passing Mainnet: ✅ Live
- ✅ Fee-vault integration (players deposit directly)
- ✅ Faction points with asymptotic multipliers
- ✅ Game lifecycle with multi-sig authorization
- ✅ Epoch cycling with BLND→USDC conversion
- ✅ Reward distribution system
- ✅ Emergency pause mechanism
- ✅ TTL storage management
- ✅ Event emissions
- ✅ Comprehensive test coverage
- ✅ Mainnet deployment
- External security audit
- Multiplier optimization (see
fp_simulations/RECOMMENDATIONS.md)
This is a production smart contract protocol. All changes must:
- Include comprehensive tests
- Follow Soroban best practices (no_std, checked arithmetic, proper auth)
- Use
soroban-fixed-point-mathfor all multiplier calculations - Update documentation
- Pass security review
[Add license information]
- Issues: GitHub Issues
- Documentation: See
docs/directory - Security: See SECURITY.md for reporting vulnerabilities