Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ task1.md
task1.md

# Task files
task1.md
task1.md
73 changes: 64 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -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?
Expand All @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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<u64>
get_active_matches() -> Vec<u64>
```

### 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

```
Expand Down Expand Up @@ -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
Expand Down
Loading