# H2H Blockchain Smart Contract Architecture

## Overview

This directory contains pseudocode specifications for the H2H betting platform's smart contract layer. The contracts implement a **hybrid blockchain architecture** where critical escrow and settlement operations occur on-chain for trustlessness, while user experience and auxiliary features remain off-chain for performance.

## Architecture Goals

1. **Trustless Escrow**: Funds are held by smart contracts, not a centralized authority
2. **Automatic Settlement**: Oracle network fetches real-world event results and settles bets
3. **Transparency**: All bet states and fund movements are publicly verifiable on-chain
4. **Decentralization**: Multiple independent oracle nodes prevent single point of failure
5. **Dispute Resolution**: Multi-layered fallback for edge cases and disagreements

## Contract Components

### 1. BetEscrow Contract

**Purpose**: Manages the complete lifecycle of bets including creation, matching, escrow, and settlement.

**Key Features**:
- Bet creation with configurable odds and stake amounts
- Atomic escrow locking for both parties upon bet acceptance
- Oracle-delegated settlement
- Manual settlement fallback if oracle fails
- Dispute mechanism with 48-hour window
- Admin override for disputed bets

**State Machine**:
```
OPEN → MATCHED → PENDING_ORACLE → COMPLETED
 ↓                                    ↑
CANCELLED                        DISPUTED
```

[See BetEscrow.pseudocode.md for full implementation](./BetEscrow.pseudocode.md)

### 2. BetOracle Contract

**Purpose**: Bridges blockchain and external data sources through a decentralized oracle network.

**Key Features**:
- Multi-node consensus mechanism (e.g., 3 of 5 nodes must agree)
- Cryptographic signature verification for all submissions
- Support for multiple API adapters (sports, entertainment, politics, etc.)
- Automatic settlement upon consensus
- Timeout handling with manual fallback

**Oracle Flow**:
```
Request → Nodes Fetch Data → Submit Results → Verify Consensus → Settle Bet
```

[See BetOracle.pseudocode.md for full implementation](./BetOracle.pseudocode.md)

## System Architecture Diagram

```
┌─────────────────────────────────────────────────────────────────────┐
│                          Frontend (React + Web3)                     │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────────────────┐   │
│  │ MetaMask     │  │ Transaction  │  │ Blockchain Status      │   │
│  │ Connection   │  │ Signing      │  │ Badges & Gas Estimates │   │
│  └──────────────┘  └──────────────┘  └────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘
                              ↓ ↑
                        Web3 JSON-RPC
                              ↓ ↑
┌─────────────────────────────────────────────────────────────────────┐
│                     Blockchain Layer (Smart Contracts)               │
│                                                                       │
│  ┌────────────────────────┐         ┌─────────────────────────┐    │
│  │   BetEscrow Contract   │ ←────→  │   BetOracle Contract    │    │
│  │                        │         │                         │    │
│  │  • createBet()         │         │  • requestSettlement()  │    │
│  │  • acceptBet()         │         │  • submitResponse()     │    │
│  │  • settleBet()         │         │  • checkConsensus()     │    │
│  │  • disputeBet()        │         │  • verifySignatures()   │    │
│  │                        │         │                         │    │
│  │  Escrow: ETH/tokens    │         │  Trusted Nodes: 5       │    │
│  └────────────────────────┘         └─────────────────────────┘    │
│              ↓ Events                        ↑ API Calls            │
└──────────────┼──────────────────────────────┼──────────────────────┘
               │                              │
               │ (BetCreated, BetMatched,     │ (Oracle Requests)
               │  BetSettled events)          │
               ↓                              │
┌─────────────────────────────────────────────┼──────────────────────┐
│                    Backend (FastAPI)        │                       │
│                                             │                       │
│  ┌────────────────────┐    ┌───────────────┴────────┐             │
│  │  Event Indexer     │    │   Oracle Aggregator    │             │
│  │                    │    │                        │             │
│  │  • Poll blocks     │    │  • Collect node votes  │             │
│  │  • Index events    │    │  • Verify consensus    │             │
│  │  • Sync to DB      │    │  • Submit to chain     │             │
│  └────────────────────┘    └────────────────────────┘             │
│              ↓                          ↑                           │
│         PostgreSQL               Oracle Nodes (3-5)                │
│  ┌────────────────────┐    ┌────────────────────┐                 │
│  │  Cached Bet Data   │    │  • Fetch ESPN API  │                 │
│  │  (for fast queries)│    │  • Sign results    │                 │
│  └────────────────────┘    │  • Submit to chain │                 │
│                             └────────────────────┘                 │
│                                      ↑                              │
└──────────────────────────────────────┼──────────────────────────────┘
                                       │
                              External APIs
                     ┌─────────────────┴────────────────┐
                     │                                   │
              ┌──────┴──────┐                  ┌─────────┴────────┐
              │  ESPN API   │                  │  Odds API        │
              │  (Sports)   │                  │  (Politics, etc.)│
              └─────────────┘                  └──────────────────┘
```

## Complete Bet Lifecycle

### 1. Bet Creation

```
User (Alice)
    ↓
  Frontend: Fill out CreateBetModal
    ↓
  Web3: Sign transaction
    ↓
  BetEscrow.createBet(stake=100, odds=1.5, eventId="super-bowl-2024")
    ↓
  Emit BetCreated event
    ↓
  Backend Indexer: Sync to PostgreSQL
    ↓
  Marketplace: Bet appears as "OPEN"
```

**On-Chain State**:
- Bet ID: 42
- Status: OPEN
- Creator: Alice's address
- Opponent: null
- Escrow: 0 ETH (no funds locked yet)

**Off-Chain State (DB)**:
- Title: "Super Bowl LVIII Winner"
- Description: "49ers vs Chiefs..."
- blockchain_bet_id: 42
- blockchain_tx_hash: "0xabc123..."

### 2. Bet Acceptance

```
User (Bob)
    ↓
  Frontend: Click "Accept Bet" on BetDetails page
    ↓
  Display GasFeeEstimate component
    ↓
  User confirms
    ↓
  Web3: Sign transaction with stake amount (100 ETH)
    ↓
  BetEscrow.acceptBet(betId=42) payable
    ↓
  Contract transfers Alice's 100 ETH from her approved balance
  Contract receives Bob's 100 ETH from msg.value
    ↓
  Escrow locked: 200 ETH total
    ↓
  Emit BetMatched event
    ↓
  Frontend: Show TransactionModal ("Confirming...")
    ↓
  Wait for block confirmation (10-30 seconds)
    ↓
  TransactionModal: "Success!" with Etherscan link
    ↓
  Backend Indexer: Update DB status to MATCHED
    ↓
  Frontend: Refresh bet details, show "Matched" status
```

**On-Chain State**:
- Bet ID: 42
- Status: MATCHED
- Creator: Alice's address
- Opponent: Bob's address
- Escrow: 200 ETH

**Off-Chain State (DB)**:
- status: matched
- opponent_id: Bob's user ID
- blockchain_status: "MATCHED"

### 3. Oracle Settlement (Automatic)

```
Event occurs in real world (Super Bowl game ends)
    ↓
  BetEscrow.requestSettlement(betId=42)
    ↓
  BetOracle.requestSettlement(betId=42, eventId="super-bowl-2024")
    ↓
  Emit OracleRequested event
    ↓
  ┌─────────────────────────────────────┐
  │ Oracle Nodes (listening for events) │
  └─────────────────────────────────────┘
         ↓           ↓            ↓
      Node 1      Node 2       Node 3
         │           │            │
    Fetch ESPN  Fetch ESPN   Fetch ESPN
    API result  API result   API result
         │           │            │
    "49ers won" "49ers won"  "49ers won"
         │           │            │
    Map to Alice Map to Alice Map to Alice
         │           │            │
    Sign result Sign result Sign result
         ↓           ↓            ↓
  BetOracle.submitOracleResponse(requestId, winner=Alice, signature)
                    ↓
         Check submissions count (3/3)
                    ↓
         Check consensus (3 votes for Alice)
                    ↓
         Consensus reached!
                    ↓
  BetEscrow.settleBet(betId=42, winner=Alice)
                    ↓
         Transfer 200 ETH to Alice
                    ↓
         Emit BetSettled event
                    ↓
  Backend Indexer: Update DB
                    ↓
  Frontend: Show "Completed" status
                    ↓
  Alice's wallet balance: +200 ETH
```

**On-Chain State**:
- Bet ID: 42
- Status: COMPLETED
- Winner: Alice's address
- Escrow: 0 ETH (paid out)

**Off-Chain State (DB)**:
- status: completed
- winner_id: Alice's user ID
- settled_at: timestamp

## Integration Points

### Frontend → Blockchain

**Files**: `frontend/src/blockchain/hooks/useBlockchainBet.ts`

```typescript
// Example: Accepting a bet
const { acceptBet } = useBlockchainBet()

await acceptBet(betId=42, stakeAmount=100)
  ↓
MetaMask popup for user signature
  ↓
Transaction submitted to blockchain
  ↓
Wait for confirmation
  ↓
Update UI with new bet status
```

### Backend → Blockchain

**Files**: `backend/app/blockchain/services/blockchain_service.py`

```python
# Example: Creating bet on-chain
blockchain_service.create_bet_on_chain(
    stake_amount=100,
    event_id="super-bowl-2024"
)
  ↓
Build transaction with Web3.py
  ↓
Sign with backend hot wallet
  ↓
Submit to RPC endpoint
  ↓
Return transaction hash
```

### Blockchain → Backend (Event Indexing)

**Files**: `backend/app/blockchain/services/blockchain_indexer.py`

```python
# Continuous background process
while True:
    latest_block = get_latest_block()
    events = get_events_in_block(latest_block)

    for event in events:
        if event.type == "BetCreated":
            sync_bet_created_to_db(event)
        elif event.type == "BetMatched":
            sync_bet_matched_to_db(event)
        elif event.type == "BetSettled":
            sync_bet_settled_to_db(event)

    sleep(10 seconds)
```

## Data Flow: On-Chain vs Off-Chain

| Data | Storage Location | Reason |
|------|------------------|--------|
| Bet escrow funds | ⛓️ On-Chain | Trustless, no centralized custody |
| Bet status (OPEN/MATCHED/COMPLETED) | ⛓️ On-Chain + 💾 DB Cache | Source of truth on-chain, cached for speed |
| Bet participants (creator/opponent) | ⛓️ On-Chain + 💾 DB | Enforced by smart contract |
| Settlement winner | ⛓️ On-Chain | Oracle consensus, immutable |
| Bet title/description | 💾 DB only | Not needed for contract logic |
| User email/password | 💾 DB only | Authentication separate from blockchain |
| Transaction history | ⛓️ On-Chain (events) + 💾 DB | Events logged on-chain, indexed to DB |
| Search/filters | 💾 DB only | Too expensive to query blockchain |

## Security Model

### On-Chain Security

1. **Escrow Protection**: Funds locked in smart contract, not controlled by any individual
2. **Atomic Operations**: Both parties' funds locked in single transaction (no partial states)
3. **Role-Based Access**: Only oracle can settle, only owner can admin-override
4. **Reentrancy Guards**: Prevent malicious contracts from draining escrow
5. **Signature Verification**: All oracle submissions cryptographically signed

### Oracle Security

1. **Multi-Node Consensus**: Require 3 of 5 nodes to agree (prevents single node manipulation)
2. **Signature Verification**: Each node signs results with private key
3. **Timeout Fallback**: If oracle fails, users can manually settle after 24 hours
4. **Dispute Window**: 48 hours to dispute automatic settlement
5. **Admin Override**: Final fallback for edge cases

### Threat Model

| Threat | Mitigation |
|--------|-----------|
| Malicious oracle node | Multi-node consensus (3/5 threshold) |
| All oracle nodes fail | 24-hour timeout → manual settlement allowed |
| Disputed result | 48-hour dispute window → admin resolution |
| Smart contract bug | Audited code, time-lock for upgrades |
| User loses private key | Non-custodial, user responsible (standard Web3) |
| Front-running | Commit-reveal scheme (future enhancement) |

## Gas Costs & Optimization

### Estimated Gas Usage (Ethereum Mainnet)

| Operation | Gas Limit | Cost @ 50 gwei | Cost @ 100 gwei |
|-----------|-----------|----------------|-----------------|
| Create Bet | 120,000 | 0.006 ETH ($12) | 0.012 ETH ($24) |
| Accept Bet | 180,000 | 0.009 ETH ($18) | 0.018 ETH ($36) |
| Settle Bet (Oracle) | 150,000 | 0.0075 ETH ($15) | 0.015 ETH ($30) |
| Submit Oracle Response | 80,000 | 0.004 ETH ($8) | 0.008 ETH ($16) |

### Layer 2 Optimization

**Recommendation**: Deploy on Polygon or Arbitrum for:
- **90-95% lower gas costs**: Accept bet costs ~$2 instead of $36
- **Faster confirmations**: 2 seconds vs 12-15 seconds
- **Same security**: Inherits Ethereum security via rollups
- **No code changes**: Same Solidity contracts work on L2

**Example L2 Costs (Polygon)**:
- Create Bet: ~$0.50
- Accept Bet: ~$1.00
- Settle Bet: ~$0.75

## Testing Strategy

### Unit Tests
- Test each contract function individually
- Verify state transitions (OPEN → MATCHED → COMPLETED)
- Test edge cases (insufficient funds, unauthorized access, etc.)

### Integration Tests
- Test BetEscrow ↔ BetOracle integration
- Test oracle consensus mechanism with simulated nodes
- Test timeout and fallback scenarios

### End-to-End Tests
- Deploy contracts to testnet (Sepolia/Mumbai)
- Create bet through frontend
- Accept bet with second account
- Trigger oracle settlement
- Verify funds distributed correctly

## Deployment Plan

### Phase 1: Testnet Deployment
1. Deploy contracts to Sepolia (Ethereum) or Mumbai (Polygon)
2. Verify contracts on Etherscan
3. Set up 3 oracle nodes
4. Configure API adapters for test events
5. Test full lifecycle with test ETH

### Phase 2: Security Audit
1. Engage smart contract auditor (CertiK, OpenZeppelin, Trail of Bits)
2. Fix any discovered vulnerabilities
3. Re-audit critical changes

### Phase 3: Mainnet Launch
1. Deploy to Ethereum mainnet or Polygon
2. Transfer ownership to multi-sig wallet
3. Launch with limited beta users
4. Monitor for 2 weeks before full launch

## Future Enhancements

1. **EIP-2771 Meta-Transactions**: Backend pays gas for user actions
2. **Batch Settlement**: Settle multiple bets in single transaction
3. **Flexible Odds**: Support decimal odds like 1.75x instead of whole numbers
4. **Partial Matching**: Allow bets to be partially filled by multiple opponents
5. **NFT Receipts**: Issue NFTs representing bet participation
6. **DAO Governance**: Community votes on oracle disputes

## Repository Structure

```
backend/app/blockchain/
├── contracts/
│   ├── BetEscrow.pseudocode.md       # This file
│   ├── BetOracle.pseudocode.md       # Oracle contract spec
│   └── README.md                      # Architecture overview (you are here)
├── services/
│   ├── blockchain_service.py          # Web3 integration
│   ├── blockchain_indexer.py          # Event listener
│   ├── oracle_node.py                 # Oracle node implementation
│   └── oracle_aggregator.py           # Consensus aggregator
└── config.py                          # Contract addresses, RPC URLs
```

## References

- [Ethereum Smart Contracts](https://ethereum.org/en/developers/docs/smart-contracts/)
- [Chainlink Oracles](https://chain.link/education/blockchain-oracles)
- [OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts/)
- [Solidity by Example](https://solidity-by-example.org/)
- [Web3.py Documentation](https://web3py.readthedocs.io/)

---

**Note**: This is pseudocode for architectural planning. For production deployment, these contracts would need to be written in actual Solidity, audited for security, and thoroughly tested on testnets before mainnet launch.
