预测市场 + SDK — 实现

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Build Polymarket-style prediction market (3 Solidity contracts + tests) and isomorphic TypeScript SDK.

Architecture: Simplified Gnosis CTF (no nesting) + on-chain CLOB (EIP-712) + OracleHub hybrid settlement. SDK uses viem for isomorphic browser+Node.js support.

Tech Stack: Solidity 0.8.26, Foundry, OpenZeppelin ERC1155, TypeScript, viem, vitest, tsup


Task 1: Interfaces

Files:

  • Create: contracts/src/prediction/interfaces/IConditionalTokens.sol

  • Create: contracts/src/prediction/interfaces/ICTFExchange.sol

  • Create: contracts/src/prediction/interfaces/IOracleResolver.sol

Step 1: Create IConditionalTokens interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IConditionalTokens {
    event ConditionPreparation(bytes32 indexed conditionId, address indexed oracle, bytes32 indexed questionId, uint256 outcomeSlotCount);
    event ConditionResolution(bytes32 indexed conditionId, address indexed oracle, bytes32 indexed questionId, uint256 outcomeSlotCount, uint256[] payoutNumerators);
    event PositionSplit(address indexed stakeholder, IERC20 collateralToken, bytes32 indexed conditionId, uint256[] partition, uint256 amount);
    event PositionsMerge(address indexed stakeholder, IERC20 collateralToken, bytes32 indexed conditionId, uint256[] partition, uint256 amount);
    event PayoutRedemption(address indexed redeemer, IERC20 collateralToken, bytes32 indexed conditionId, uint256[] indexSets, uint256 payout);

    function prepareCondition(address oracle, bytes32 questionId, uint256 outcomeSlotCount) external;
    function reportPayouts(bytes32 questionId, uint256[] calldata payouts) external;
    function splitPosition(IERC20 collateralToken, bytes32 conditionId, uint256[] calldata partition, uint256 amount) external;
    function mergePositions(IERC20 collateralToken, bytes32 conditionId, uint256[] calldata partition, uint256 amount) external;
    function redeemPositions(IERC20 collateralToken, bytes32 conditionId, uint256[] calldata indexSets) external;

    function getConditionId(address oracle, bytes32 questionId, uint256 outcomeSlotCount) external pure returns (bytes32);
    function getPositionId(IERC20 collateralToken, bytes32 conditionId, uint256 indexSet) external pure returns (uint256);
    function getOutcomeSlotCount(bytes32 conditionId) external view returns (uint256);
    function payoutDenominator(bytes32 conditionId) external view returns (uint256);
}

Step 2: Create ICTFExchange interface

Step 3: Create IOracleResolver interface

Step 4: Verify compilation

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build Expected: compiles with no errors

Step 5: Commit


Task 2: ConditionalTokens Contract

Files:

  • Create: contracts/src/prediction/ConditionalTokens.sol

Step 1: Write ConditionalTokens

Step 2: Verify compilation

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build Expected: compiles with no errors

Step 3: Commit


Task 3: ConditionalTokens Tests

Files:

  • Create: contracts/test/ConditionalTokens.t.sol

Step 1: Write tests

Step 2: Run tests

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract ConditionalTokensTest -v Expected: all ~18 tests pass

Step 3: Commit


Task 4: CTFExchange Contract

Files:

  • Create: contracts/src/prediction/CTFExchange.sol

Step 1: Write CTFExchange

Step 2: Verify compilation

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build Expected: compiles with no errors

Step 3: Commit


Task 5: CTFExchange Tests

Files:

  • Create: contracts/test/CTFExchange.t.sol

Step 1: Write tests

Step 2: Run tests

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract CTFExchangeTest -v Expected: all ~14 tests pass

Step 3: Commit


Task 6: OracleResolver Contract

Files:

  • Create: contracts/src/prediction/OracleResolver.sol

Step 1: Write OracleResolver

Step 2: Verify compilation

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build Expected: compiles with no errors

Step 3: Commit


Task 7: OracleResolver Tests + E2E

Files:

  • Create: contracts/test/OracleResolver.t.sol

  • Create: contracts/test/PredictionMarketE2E.t.sol

Step 1: Write OracleResolver tests

Step 2: Write E2E test

Step 3: Run all prediction market tests

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-path "test/ConditionalTokens.t.sol test/CTFExchange.t.sol test/OracleResolver.t.sol test/PredictionMarketE2E.t.sol" -v Expected: all tests pass (~47 total)

Step 4: Commit


Task 8: SDK Scaffold

Files:

  • Create: sdk/package.json

  • Create: sdk/tsconfig.json

  • Create: sdk/tsup.config.ts

  • Create: sdk/src/index.ts

Step 1: Initialize package

Step 2: Create package.json

Step 3: Create tsconfig.json

Step 4: Create tsup.config.ts

Step 5: Create src/index.ts

Step 6: Install dependencies and verify

Step 7: Commit


Task 9: SDK Types + Helpers

Files:

  • Create: sdk/src/market/types.ts

  • Create: sdk/src/market/helpers.ts

Step 1: Write types

Step 2: Write helpers

Step 3: Commit


Task 10: SDK Helpers Tests

Files:

  • Create: sdk/test/helpers.test.ts

Step 1: Write tests

Step 2: Run tests

Run: cd sdk && npx vitest run Expected: all ~10 tests pass

Step 3: Commit


Task 11: SDK Client + Contract Wrappers

Files:

  • Create: sdk/src/client.ts

  • Create: sdk/src/contracts/conditional-tokens.ts

  • Create: sdk/src/contracts/exchange.ts

  • Create: sdk/src/contracts/resolver.ts

  • Create: sdk/src/contracts/oracle-hub.ts

Step 1: Write client.ts

Step 2: Write contract wrappers (each follows same pattern: ABI subset + typed read/write methods)

Step 3: Update index.ts exports

Step 4: Type check

Run: cd sdk && npx tsc --noEmit Expected: no errors

Step 5: Commit


Task 12: SDK Client Tests

Files:

  • Create: sdk/test/client.test.ts

Step 1: Write tests

Step 2: Run all SDK tests

Run: cd sdk && npx vitest run Expected: all tests pass (~14 total: 10 helpers + 4 client)

Step 3: Build

Run: cd sdk && npx tsup Expected: dist/ contains index.js, index.cjs, index.d.ts

Step 4: Commit


Task 13: Update Docs + Final Commit

Files:

  • Modify: docs/README.md

  • Modify: docs/dev-notes/dev-log.md

Step 1: Update README.md

Add P7 section to plans table and update progress:

Update progress:

Step 2: Add dev-log entry

Append Phase 7 entry with key decisions and contract addresses.

Step 3: Commit


Summary

Task
Component
Tests
Est. Lines

1

3 interfaces

~150

2

ConditionalTokens.sol

~180

3

ConditionalTokens tests

18

~250

4

CTFExchange.sol

~220

5

CTFExchange tests

14

~200

6

OracleResolver.sol

~130

7

OracleResolver + E2E tests

15

~280

8

SDK scaffold

~50

9

SDK types + helpers

~120

10

SDK helpers tests

10

~80

11

SDK client + wrappers

~300

12

SDK client tests

4

~50

13

Docs update

~30

Total

~61

~2040

Last updated