diff --git a/.gitignore b/.gitignore index 795b5de..707b787 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,4 @@ task1.md task1.md # Task files -task1.md \ No newline at end of file +task1.md diff --git a/README.md b/README.md index d713de0..5afddcf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Checkmate-Escrow β€” Competitive Chess Betting on Stellar -A trustless chess wagering platform built on Stellar Soroban smart contracts. Players stake XLM or USDC before a match, and the winner is automatically paid out the moment the game ends β€” no middleman, no delays, no trust required. +A trustless chess wagering platform built on Stellar Soroban smart contracts. Players stake tokens before a match, and the winner is automatically paid out the moment the game ends β€” no middleman, no delays, no trust required. ## 🎯 What is Checkmate-Escrow? @@ -9,7 +9,7 @@ Checkmate-Escrow combines competitive chess with Stellar's fast settlement to cr Players: -- Stake XLM or USDC into a Soroban escrow contract before a match begins +- Stake tokens into a Soroban escrow contract before a match begins - Play their game on Lichess or Chess.com as normal - Receive automatic payouts the instant the match result is verified on-chain @@ -24,13 +24,47 @@ This makes Checkmate-Escrow: ## πŸš€ Features -- **Create a Match**: Set stake amount, currency (XLM or USDC), and link a Lichess/Chess.com game ID +- **Create a Match**: Set stake amount, token address, and link a Lichess/Chess.com game ID +- **Flexible Token Support**: Any Stellar token address is accepted by default; once the admin adds at least one token via `add_allowed_token`, only allowlisted tokens are accepted for new matches - **Escrow Stakes**: Both players deposit funds into the contract before the game starts - **Oracle Integration**: Real-time result verification via Lichess/Chess.com APIs - **Automatic Payouts**: Winner receives the full pot the moment the result is confirmed - **Draw Handling**: Stakes are returned to both players in the event of a draw +- **Admin Controls**: Pause/unpause, oracle rotation, admin transfer, and match timeout configuration - **Transparent**: All escrow balances and payout history are verifiable on-chain +## πŸ—ΊοΈ Match Lifecycle + +Matches move through the following states: + +``` +Pending ──► Active ──► Completed + β”‚ β–² + └──► Cancelled ◄───────── + (expire_match / cancel_match) +``` + +| State | Description | +|-------------|----------------------------------------------------------| +| `Pending` | Match created; awaiting deposits from both players | +| `Active` | Both players have deposited; game is in progress | +| `Completed` | Oracle submitted result; payout executed | +| `Cancelled` | Cancelled before activation, or expired after timeout | + +### Events Reference + +| Topic (namespace / name) | Emitted by | Payload | +|---------------------------|---------------------|----------------------------------------------| +| `escrow` / `init` | `initialize` | `(oracle_address, admin_address)` | +| `admin` / `paused` | `pause` | `()` | +| `admin` / `unpaused` | `unpause` | `()` | +| `admin` / `oracle_up` | `update_oracle` | `(old_oracle, new_oracle)` | +| `admin` / `xfer` | `transfer_admin` | `(old_admin, new_admin)` | +| `match` / `created` | `create_match` | `(match_id, player1, player2, stake_amount)` | +| `match` / `completed` | `submit_result` | `(match_id, winner)` | +| `match` / `cancelled` | `cancel_match` | `match_id` | +| `match` / `expired` | `expire_match` | `match_id` | + ## πŸ› οΈ Quick Start ### Prerequisites @@ -106,25 +140,46 @@ Follow the step-by-step guide in `demo/demo-script.md` - [Oracle Design](docs/oracle.md) - [Threat Model & Security](docs/security.md) - [Roadmap](docs/roadmap.md) +- [Deployment Guide](docs/deployment.md) ## πŸŽ“ Smart Contract API ### Match Management ``` -create_match(stake_amount, token, game_id, platform) -> u64 +create_match(player1, player2, stake_amount, token, game_id, platform) -> u64 get_match(match_id) -> Match -cancel_match(match_id) +cancel_match(match_id, caller) +expire_match(match_id) +get_player_matches(player) -> Vec +get_active_matches() -> Vec ``` ### Escrow ``` -deposit(match_id) -get_escrow_balance(match_id) -> i128 +deposit(match_id, player) is_funded(match_id) -> bool +get_escrow_balance(match_id) -> i128 ``` +#### `is_funded` vs `get_escrow_balance` + +These two functions answer different questions and are easy to confuse: + +- **`is_funded(match_id)`** β€” returns `true` only when *both* players have deposited their stake (i.e. the match has transitioned to `Active`). It reflects deposit flags, not token balances. Use this to gate game-start logic. + +- **`get_escrow_balance(match_id)`** β€” returns the total token amount currently held in escrow for the match: `0`, `1Γ—stake`, or `2Γ—stake` depending on how many players have deposited. Once a match is `Completed` or `Cancelled` (funds already paid out or refunded), this always returns `0` regardless of on-chain token balances. + +Examples: + +| Scenario | `is_funded` | `get_escrow_balance` | +|---------------------------------------|-------------|----------------------| +| Only player1 deposited | `false` | `1 Γ— stake_amount` | +| Both players deposited (Active) | `true` | `2 Γ— stake_amount` | +| Match completed (payout done) | `true` | `0` | +| Match cancelled (refunds done) | `false` | `0` | + ### Oracle & Payouts ``` @@ -174,8 +229,8 @@ cargo test ## πŸ—ΊοΈ Roadmap -- **v1.0 (Current)**: XLM-only escrow, Lichess Oracle integration, basic match flow -- **v1.1**: USDC and custom token support, Chess.com Oracle +- **v1.0 (Current)**: Token-allowlist escrow, Lichess Oracle integration, basic match flow +- **v1.1**: Chess.com Oracle, expanded token support - **v2.0**: Multi-game tournaments, bracket payouts - **v3.0**: Frontend UI with wallet integration - **v4.0**: Mobile app, ELO-based matchmaking, leaderboards