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
9 changes: 4 additions & 5 deletions Clarinet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ authors = []
telemetry = true
cache_dir = './.cache'
requirements = []
[contracts.roxy-trait]
path = 'contracts/roxy-trait.clar'
[contracts.Roxy]
path = 'contracts/roxy.clar'
clarity_version = 3
epoch = 'latest'

[contracts.roxy]
path = 'contracts/roxy.clar'
[contracts.roxy-trait]
path = 'contracts/roxy-trait.clar'
clarity_version = 3
epoch = 'latest'
depends_on = ['roxy-trait']
[repl.analysis]
passes = ['check_checker']

Expand Down
217 changes: 100 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,150 +1,133 @@
# Roxy - Bitcoin L2 Prediction Market Game
# Roxy - Bitcoin L2 Gaming & Prediction SDK

## Overview

Roxy is a decentralized prediction market platform built on Bitcoin Layer 2 (Stacks blockchain) that enables users to make predictions on various outcomes, accumulate points through successful predictions, and participate in a peer-to-peer marketplace for trading points. The platform combines individual prediction capabilities with collaborative guild-based prediction systems, creating a competitive environment with comprehensive leaderboards.
Roxy is a decentralized gaming SDK built on Bitcoin Layer 2 (Stacks) that enables game developers to integrate **prediction markets**, **staking**, and **cross-game identity** directly into their gameplay loop.

Unlike traditional prediction markets that are standalone apps, Roxy brings the market *to the game*. Players can stake on their own matches, compete in high-stakes arenas, and carry their reputation across the entire ecosystem.

![Roxy Logo](https://github.com/user-attachments/assets/f57fe362-4e7c-40d6-977d-cd521fec1452)
![Roxy SDK](https://github.com/user-attachments/assets/f57fe362-4e7c-40d6-977d-cd521fec1452)

## Features
---

### Prediction Markets
## Core Features (v2.3.0)

- **Binary Event System**: Create and participate in YES/NO prediction events covering sports, price movements, and other outcomes
- **Proportional Rewards**: Winners receive rewards proportional to their stake in the winning pool
- **Admin-Controlled Events**: Secure event creation and resolution managed by contract administrators
- **Multi-Event Support**: Simultaneous participation across multiple prediction events
### 1. Prediction Markets & Staking
- **In-Game Wagers**: Allow players to stake STX on the outcome of their own matches or tournaments.
- **Binary Outcomes**: Simple YES/NO pools for clear resolution (e.g., "Will Player X win Match #42?").
- **Proportional Payouts**: Winners share the losing pool's stake, minus protocol fees.
- **Slippage-Free**: Peer-to-pool model ensures liquidity and fair odds.

### Collaborative Guild System
### 2. Campaign Management
- **Developer-Controlled Contexts**: Create "Campaigns" (seasons, tournaments, or specific game modes) to isolate scoring and leaderboards.
- **Custom configurations**: Set scoring modes (Cumulative, High Score, Low Score) and duration.
- **Sponsored Prize Pools**: Deposit STX into a campaign to reward top performers automatically.

- **Guild Creation**: Users can form prediction guilds to pool resources and strategies
- **Shared Staking**: Guild members contribute points to a collective pool for larger prediction stakes
- **Collective Rewards**: Winnings are distributed among guild members based on contributions
- **Guild Leaderboards**: Track and compare guild performance metrics across the platform
### 3. Gamer Identity & Reputation
- **Unified Profile**: A single on-chain username and stats profile across all Roxy-integrated games.
- **Verifiable History**: Wins, losses, and total volume are tracked on-chain, creating a trustless "skill rating".
- **Sybil Resistance**: Cost-to-attack ensures leaderboards remain fair.

### Point Marketplace

- **Point Trading**: Buy and sell earned points using STX tokens
- **Partial Purchases**: Support for buying portions of listed point packages
- **Protocol Fees**: 2% transaction fee automatically collected by the protocol
- **Listing Requirements**:
- Minimum 10,000 earned points required to create listings
- 10 STX listing fee per marketplace listing
- **Secure Transactions**: All trades executed on-chain with automatic point transfers

### Leaderboard & Statistics

- **Individual Metrics**: Track personal performance including total predictions, wins, losses, and win rate
- **Guild Rankings**: Compare guild performance across multiple metrics
- **Points Tracking**: Monitor total points earned and current balances
- **Real-time Updates**: On-chain statistics updated with each transaction

### Points & Rewards System

- **Welcome Bonus**: New users receive 1,000 starting points upon registration
- **Earning Mechanism**: Accumulate points by correctly predicting event outcomes
- **Reward Distribution**: Proportional payout system ensures fair distribution based on stake size
- **Earned Points Tracking**: Separate tracking of earned points for marketplace eligibility
---

## Architecture

### Data Storage
The Roxy ecosystem is composed of three main layers:

#### User Management
- **`user-points`**: Total point balance for each registered user
- **`earned-points`**: Points accumulated from winning predictions (used for marketplace selling threshold)
- **`user-names`**: Username registry for user identification
- **`user-stats`**: Comprehensive statistics including prediction count, wins, losses, win rate, and total points earned
### 1. The Core Contract (`roxy.clar`)
The heart of the protocol. It handles:
- Campaign creation and configuration.
- Staking logic and pool management.
- User identity and global stats.
- Payout calculations and treasury management.

#### Event Management
- **`events`**: Complete event registry containing pool sizes, status (open/closed/resolved), winner information, and metadata
- **`yes-stakes`**: Individual user stakes on YES outcomes per event
- **`no-stakes`**: Individual user stakes on NO outcomes per event
**Testnet Address**: `STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.Roxy`

#### Guild System
- **`guilds`**: Guild information including creator, name, total pooled points, and member count
- **`guild-members`**: Membership registry tracking which users belong to which guilds
- **`guild-deposits`**: Individual user contributions to guild point pools
- **`guild-yes-stakes`**: Guild collective stakes on YES outcomes per event
- **`guild-no-stakes`**: Guild collective stakes on NO outcomes per event
- **`guild-stats`**: Guild-level performance metrics for leaderboard rankings
### 2. The SDK Trait (`roxy-sdk-trait`)
A standard interface that defines how games communicate with the core contract. This ensures forward compatibility and easy integration for developers.

#### Marketplace
- **`listings`**: Active and inactive point sale listings with seller information, point amounts, STX prices, and status
- **`protocol-treasury`**: Accumulated protocol fees from marketplace transactions and listing fees
**Testnet Address**: `STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.roxy-trait`

#### Transaction Logging
- **`transaction-logs`**: Comprehensive on-chain event log for frontend integration, tracking all major actions (registrations, staking, claims, marketplace transactions, etc.)
### 3. The Game Wrapper (`game-example.clar`)
An example implementation showing how to wrap SDK calls within your game logic. This pattern allows games to abstract away the complexity of DeFi interactions from their players.

## Key Functions
---

### User Functions
- `register(username)`: Register a new user and receive starting points
- `stake-yes(event-id, amount)`: Place a YES prediction stake
- `stake-no(event-id, amount)`: Place a NO prediction stake
- `claim(event-id)`: Claim rewards from resolved events

### Marketplace Functions
- `create-listing(points, price-stx)`: List points for sale (requires 10,000+ earned points)
- `buy-listing(listing-id, points-to-buy)`: Purchase points from marketplace
- `cancel-listing(listing-id)`: Cancel an active listing

### Guild Functions
- `create-guild(guild-id, name)`: Create a new prediction guild
- `join-guild(guild-id)`: Join an existing guild
- `deposit-to-guild(guild-id, amount)`: Contribute points to guild pool
- `guild-stake-yes(guild-id, event-id, amount)`: Place guild YES stake
- `guild-stake-no(guild-id, event-id, amount)`: Place guild NO stake
- `guild-claim(guild-id, event-id)`: Claim guild rewards

### Admin Functions
- `create-event(event-id, metadata)`: Create new prediction events
- `resolve-event(event-id, winner)`: Resolve events and set winners
- `withdraw-protocol-fees(amount)`: Withdraw accumulated protocol fees

### Read-Only Functions
- `get-user-points(user)`: Query user point balance
- `get-earned-points(user)`: Query earned points (for marketplace eligibility)
- `can-sell(user)`: Check if user can create marketplace listings
- `get-event(event-id)`: Get event details and status
- `get-listing(listing-id)`: Get marketplace listing information
- `get-protocol-treasury()`: Query protocol treasury balance
- `get-user-stats(user)`: Get user leaderboard statistics
- `get-guild-stats(guild-id)`: Get guild leaderboard statistics

## Constants

- **Starting Points**: 1,000 points for new users
- **Minimum Earned for Selling**: 10,000 earned points required to create marketplace listings
- **Listing Fee**: 10 STX per marketplace listing
- **Protocol Fee**: 2% (200 basis points) on all marketplace transactions

## Getting Started
## Integration Guide

### Prerequisites
- Stacks wallet (Hiro Wallet recommended)
- STX tokens for transaction fees and marketplace purchases
- Clarinet development environment (for local testing)
- **Clarinet**: For local development and testing.
- **Stacks.js**: For frontend wallet connection.

### Step 1: Implement the Trait
Your game contract should implicitly or explicitly interact with `roxy-sdk-trait`.

```clarity
(use-trait roxy-sdk-trait 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.roxy-trait.roxy-sdk-trait)
```

### Step 2: Create a Campaign
Initialize your game mode (Campaign) to start tracking scores.

```clarity
(contract-call? 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.Roxy create-campaign
0x00... (metadata-hash)
tx-sender (reporter)
u100 (start-height)
u1000 (end-height)
u0 (scoring-mode: cumulative)
)
```

### Step 3: Trigger SDK Actions
Call SDK functions from your game client or contract wrapper.

**Example: Staking on a Match**
```clarity
(contract-call? 'STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.Roxy stake
event-id
u1000000 ;; 1 STX
true ;; VOTE YES
)
```

---

## Key Functions

### Usage

1. **Register**: Call `register(username)` to create an account and receive 1,000 starting points
2. **Participate**: Stake points on prediction events using `stake-yes` or `stake-no`
3. **Claim Rewards**: After events are resolved, use `claim` to collect your winnings
4. **Trade Points**: Once you've earned 10,000+ points, create listings on the marketplace
5. **Join Guilds**: Form or join guilds for collaborative predictions and shared rewards
### Game/Campaign Management
- `create-campaign`: Launch a new tracking context.
- `create-match`: Open a betting pool for a specific game event.
- `resolve-match`: (Reporter only) Settle the outcome and enable payouts.

## Protocol Fees
### Player Actions
- `set-username`: Claim a unique identity.
- `stake`: Place a bet on an active match.
- `claim-reward`: Withdraw winnings from a resolved match.
- `sync-score`: Post game results to the campaign leaderboard.

The protocol collects fees to support development, rewards, and governance:
- **Marketplace Fee**: 2% of each point sale transaction
- **Listing Fee**: 10 STX per marketplace listing creation
- **Treasury Management**: Admin can withdraw accumulated fees via `withdraw-protocol-fees`
### Read-Only
- `get-campaign`: View campaign details and total prize pool.
- `get-event`: Check odds/pools for a specific match.
- `get-user-profile`: Retrieve a player's alias and stats.

---

## Development & Testing

### Local Setup
1. Clone the repo.
2. `clarinet integrate` to spin up a local Devnet.
3. Deploy contracts (automatically handled by Clarinet).

### Frontend Example
Check `example/frontend-example` for a complete Vite + React implementation showing:
- Wallet Connection
- Profile Management
- Game Loop Integration
- Transaction Broadcasting

---

## License
MIT
7 changes: 7 additions & 0 deletions check_output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: unexpected argument '--no-dashboard' found

tip: to pass '--no-dashboard' as a value, use '-- --no-dashboard'

Usage: clarinet check [OPTIONS] [FILE]

For more information, try '--help'.
6 changes: 6 additions & 0 deletions contract-address.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"Roxy-trait": "STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.roxy-trait",
"Roxy-SDK": "STVAH96MR73TP2FZG2W4X220MEB4NEMJHPMVYQNS.Roxy",
"Click-game": "ST2N04CYE3CQ1S354MZX4KHYJYD4QW25ZW37GQY7J.click-game"

}
32 changes: 28 additions & 4 deletions contracts/roxy-trait.clar
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,42 @@
(define-trait roxy-sdk-trait
(
;; Campaign Management
(create-campaign ((buff 32) principal uint uint) (response uint uint))
(create-campaign ((buff 32) principal uint uint uint) (response uint uint))
(join-campaign (uint (optional principal)) (response bool uint))
(onboard-player (uint principal (optional principal)) (response bool uint))
(update-campaign-status (uint (string-ascii 20)) (response bool uint))
(set-campaign-metadata (uint (buff 32)) (response bool uint))
(set-campaign-winner (uint principal) (response bool uint))
(claim-campaign-prize (uint) (response uint uint))
(claim-campaign-prize-for (uint principal) (response uint uint))

;; Score Syncing
(sync-score (uint principal <roxy-game-trait>) (response uint uint))
(sync-scores-batch ((list 50 { campaign-id: uint, player: principal, score: uint }) <roxy-game-trait>) (response (list 50 uint) uint))
(sync-player-state (uint principal (buff 32) <roxy-game-trait>) (response bool uint))

;; Prediction Market
(create-match (uint (string-ascii 200)) (response uint uint))
(create-match (uint (buff 32)) (response uint uint))
(stake (uint uint bool) (response bool uint))
(stake-for (uint uint bool principal) (response bool uint))
(resolve-match (uint bool) (response bool uint))
(cancel-match (uint) (response bool uint))
(refund-stake (uint) (response uint uint))
(refund-stake-for (uint principal) (response uint uint))
(claim-reward (uint) (response bool uint))
(claim-reward-for (uint principal) (response uint uint))

;; User Management
(set-username ((string-ascii 50)) (response bool uint))
(set-player-username (principal (string-ascii 50) uint) (response bool uint))

;; Admin/Governance
(set-campaign-creation-fee (uint) (response bool uint))
(set-match-creation-fee (uint) (response bool uint))
(set-stx-per-usd (uint) (response bool uint))
(set-paused (bool) (response bool uint))
(propose-admin (principal) (response bool uint))
(claim-admin () (response bool uint))

;; Getters
(get-campaign (uint) (response (optional {
Expand All @@ -36,17 +57,20 @@
reporter: principal,
start-time: uint,
end-time: uint,
status: (string-ascii 20)
status: (string-ascii 20),
winner: (optional principal),
scoring-mode: uint
}) uint))
(get-event (uint) (response (optional {
campaign-id: uint,
yes-pool: uint,
no-pool: uint,
status: (string-ascii 20),
winner: (optional bool),
metadata: (string-ascii 200)
metadata-hash: (buff 32)
}) uint))
(get-leaderboard-score (uint principal) (response uint uint))
(get-player-state (uint principal) (response (optional (buff 32)) uint))
(get-participant-status (uint principal) (response bool uint))
(get-yes-stake (uint principal) (response uint uint))
(get-no-stake (uint principal) (response uint uint))
Expand Down
Loading
Loading