Automated, trustless, no-loss prize pool on TON, built on STON.fi. Depositors keep their principal; pooled principal earns yield through a STON.fi stable pool (USDT/USDC, USDT/USDe fallback), and each epoch the accrued yield is awarded to a depositor selected by a verifiable on-chain draw. No depositor can lose principal outside a stablecoin depeg event, which is socialized and disclosed.
- On-chain: Tolk (TVM), Blueprint toolchain,
@ton/sandboxfor tests. - Backend: Python 3.12 / FastAPI, Postgres, Alembic.
- Frontend: TypeScript / React / Vite, TON Connect; live pool data from the backend API.
- CI: Codeberg (Woodpecker).
On-chain (Tolk):
C0 sharedschemas, opcodes, error codes, storage layouts. Freeze artifact.C1 pool-corecustody, depositor ledger, epoch FSM, payout orchestration.C2 selection-ledgercumulative-balance lookup for winner selection.C3 draw-enginebonded commit-reveal, slash-on-no-reveal, N-winner derivation.C4 jetton-vaulttransfer_notification verification, deposit bounce handling.C5 yield-adapter-ifacedeposit_principal / harvest_yield / withdraw_principal / get_deployed_value.C6 yield-adapter-stonfireal STON.fi router LP integration, referral fees.C7 yield-adapter-mocksynthetic yield for sandbox and demo.C8 param-governortime-locked, multisig-gated pool params.
Mock infra: custom Jetton masters (mock USDT/USDC) + on-chain faucet.
Backend (FastAPI):
B0 persistencePostgres models + migrations.B1 quote-sourceLP reserve/supply reads; testnet reads the deployed mock STON.fi pool on-chain (api.ston.fi is mainnet-only).B2 indexerchain tail, opcode decode, read model.B3 keeperpermissionless epoch poker (advance/commit/reveal/draw); runs aspython -m app.keeper.B4 apiREST for the frontend.
Frontend (TS/React):
F0 bindingsTolk-to-TS contract wrappers.F1 walletTON Connect.F2 deposit-withdrawpool messaging via direct jUSDT TEP-74 transfers.F3 dashboardodds, prize estimate, draw history, activity, sourced from the backend API.
Tooling:
T0 test-harnessfull-lifecycle sandbox suites.T1 deploy-opsBlueprint deploy scripts, address registry.
contracts/ Blueprint project: Tolk sources, wrappers, sandbox tests, deploy scripts
contracts/ Tolk (.tolk) sources
wrappers/ TS contract wrappers (F0 bindings live here)
tests/ @ton/sandbox suites (T0)
scripts/ deploy + ops (T1)
addresses/ per-network registry (json), written by deployStonpool
backend/ FastAPI service
app/
alembic/
tests/
frontend/ Vite + React app
src/
- Node 24.16.0 (see
.nvmrc) - Python 3.12+
- Postgres 15+
- A TON testnet wallet funded from the faucet
Copy .env.example to .env and fill values. Never commit .env or any mnemonic/key material.
# contracts: compile + sandbox suites
cd contracts && npm install && npx blueprint build --all && npx jest
# backend: API + tests (sqlite for tests; Postgres for run)
cd backend && python -m venv venv && . venv/bin/activate && pip install -r requirements.txt -r requirements-dev.txt
ruff check app tests && pytest -q
# frontend: dev server / checks
cd frontend && npm ci && npm run dev
npm run lint && npm run typecheck && npm run test
See DEPLOY.md for end-to-end testnet bring-up (Blueprint deploy scripts, keeper, demo
seed + draw cycle, static frontend) and the Docker Compose path for the off-chain services.
deployStonpool writes every deployed address to contracts/addresses/testnet.json; the faucet and
stable minters are in deployMockStack's console output. The faucet is in the registry too when
deployStonpool was run with FAUCET set (otherwise paste it from deployMockStack). The faucet
must hold TON or claims revert. seedDemoPool faucet-claims then deposits.
Pull the addresses and seed (PowerShell):
cd contracts
$reg = Get-Content addresses/testnet.json | ConvertFrom-Json
$env:JETTON_MINTER = $reg.jettonMinter
$env:STONPOOL_POOL_CORE_ADDRESS = $reg.poolCore
$env:FAUCET_ADDRESS = $reg.faucet # or paste from deployMockStack if not in the registry
npx blueprint run seedDemoPool --testnet
bash:
cd contracts
export JETTON_MINTER=$(jq -r .jettonMinter addresses/testnet.json)
export STONPOOL_POOL_CORE_ADDRESS=$(jq -r .poolCore addresses/testnet.json)
export FAUCET_ADDRESS=$(jq -r '.faucet // empty' addresses/testnet.json) # or paste from deployMockStack
npx blueprint run seedDemoPool --testnet
The deployer seeds one position by default; set DEMO_MNEMONICS="<24 words>;<24 words>" (semicolon
separated) to seed more depositors, one position each. Deposits must land before the epoch's deposit
deadline, so seed before running runDemoCycle; deploy without --demo for a longer deposit window.
Testnet first. STON.fi v2 contracts are deployed on testnet, but api.ston.fi serves mainnet only and testnet stable liquidity must be self-seeded via the mock token + faucet infra. Real prize economics exist only on mainnet.
Shipped is a complete testnet MVP: on-chain protocol, backend indexer/API/keeper, frontend dApp, deploy + demo tooling, CI, and Docker. Three items are deliberately deferred to a mainnet cut, since none can be exercised or verified against testnet (the real venue and its API are mainnet-only):
- Real
api.ston.ficlient for live APR and referral accruals (testnet uses on-chain mock-pool reads). @ston-fi/sdklive-APR dashboard wiring (the dApp sources APR/odds/prize from the backend API).- Omniston swap-then-deposit for non-stablecoin entry (deposits are direct jUSDT TEP-74).
These belong to a future feat/mainnet-integration effort with its own testing story (forked-mainnet or staged rollout), not the testnet MVP.
MIT. See LICENSE.