verex

Verex — Feature Designs

Per-feature design docs for the Verex prediction market, in the Category → Feature → to-do structure. The full design document & roadmap is appended below (folded in from the former plan/ folder); this top section is the per-feature index.

Status is keyed to the 10-step roadmap (§1.4 in the design document below): S1 ✅ · S2 ✅ · S3 ✅* · S4 ✅ · S6 partial* · S9 partial* · S5, S7–S8, S10 planned — the detailed per-step audit (2026-08-03, all 10 steps re-audited 2026-08-18, spot-checked again on the 08-21 plan reset) lives in docs/tasks/current-plan.md → Roadmap status; that table is authoritative for step-level status, and the unchecked §1.4 checkboxes below predate it. Plan reset 2026-08-21 (jay): the 2026-08-03 batch plan shipped waves 0–2 and was archived at docs/tasks/aug-03-plan.md; its unfinished tail and everything it deferred now live in Backlog below. Update 2026-09-04: W6 — a counterparty verex does not custody — is built and proven (merged 2026-08-26, exercised unattended on 2026-09-02 by rabbit’s J2 agent trading through it); status and the one open sub-item (W6.5, match-time funds re-check) live in docs/tasks/current-plan.md → W6. Local dev now runs on an anvil fork of Sepolia (one root .env, 7702-aware seed).

Categories

Category Roadmap Doc Status
Markets S2 markets.md ✅ Done — oracle-typed markets live on Sepolia (staging + prod) and the local fork; create → trade → resolve works
Negative-risk (multi-outcome) post-S2 negative-risk-markets.md ⬜ Design only — no NegRisk adapter under packages/contracts/src
Market groups & probability sums post-S2 (design) market-groups.md — when outcome YES prices must sum to 100% and when they must not (exclusive · directional/nested · independent); normalization + invariant rules per group type ⬜ Design only — no groupType in schema.prisma, seeded groups mis-modelled (V5.1)
Trading & orders S2 trading-orders.md ✅ Done — CLOB matching against the LMSR operator; external signed makers since 2026-08-26 (W6), funds read-and-reject; open: W6.5 match-time re-check
Settlement & redeem S2 settlement-redeem.md ✅ Done — settle worker + external redeem recorded from the verified receipt (W6.4); external redeem costs the holder gas, trading does not
Oracle (resolution) S2 → S6 oracle.md ◐ Partial — mock path proven end-to-end; the live UMA adapter is deployed but has never resolved a market (V1.2, A5 open → W1)
MM Agent S2.5 → S6 mm-agent.md ✅ Done, differently — in-process mm.ts LMSR ladder, not a separate worker (structural drift noted in the plan)
Hybrid AMM + CLOB early (priority) hybrid-amm-clob.md — incl. Extreme-probability handling (CPMM tail slippage → simulation · curve decision · tail guard, 2026-07-17) ◐ Partial — LMSR quoting lives inside the CLOB today; the on-chain pool (phase B) deferred to mainnet (V3.1)
Account abstraction S7–S8 account-abstraction.md ⬜ Not started (V4) — the fork seed’s 7702 hygiene is not AA
API & indexer S4–S5 api-indexer.md ◐ Split — API ✅ (Fastify + Cloud SQL, staging + prod); indexer dropped by decision, read-only checker queued as W5 (V3.2)
Web UI S3 web-ui.md ✅ Done — Polymarket-style feed + market pages on Cloud Run
MCP interface S3 → S8 mcp-interface.md ⬜ Not built — packages/mcp-server does not exist; queued as W7
Onboarding & payments S8–S9 onboarding-payments.md ⬜ Not started (V4)
Runtime validation (Zod) incremental — CLI now · api S4 · mm-agent S2.5 zod-validation.md — env/ABI/JSON boundary validation + inferred types; folds in audit item A2 ⬜ Not started — no zod imports under packages/*/src
Markets as tokens post-S2 (exploratory) markets-as-tokens.md — ERC-20 wrapper for CTF outcome shares → external DeFi composability (DEX listing, lending, bots) ⬜ Exploratory design only
CCIP market results S6-adjacent (exploratory) ccip-market-result.md — Chainlink CCIP MarketResultReceiver + CCIPLocalSimulator local test setup (Foundry/Hardhat); cross-chain resolution path for the oracle Stage-2 track ⬜ Exploratory design only
Thirdweb exploratory thirdweb.md — platform bundle vs hand-rolled parts (Connect wallets/AA · Engine backend tx · browser-signing deploy); check item: review the Rabbit-side Thirdweb feature too before deciding ⬜ Exploratory — decision not made
Observability S4-adjacent (exploratory) observability.md — OpenTelemetry-first instrumentation with a swappable export target (Cloud Trace now, Datadog later); ChainJob worker traced first since metrics structurally can’t answer “which step is slow”, plus a standing metric-cardinality rule ⬜ Design only (V5.2)

Hierarchy: Category (file) → Feature (bold item) → to-do (checkbox); (you) = needs your decision or action.

Status column added 2026-09-04 — audited against packages/*/src, schema.prisma and the plan’s roadmap table, not against doc text. Legend: ✅ done · ◐ partial · ⬜ not started/design only.

Other docs (moved from the former plan/)

Backlog — unfinished and deferred work from the 2026-08-03 batch

Why this section exists (2026-08-21, jay). The batch plan (aug-03-plan.md) delivered waves 0–2 and closed all five gates, so it was archived and current-plan.md restarted empty. What it did not deliver, and what it consciously deferred, is listed here rather than left implied by a retired plan. Nothing was deleted — the reasoning for each deferral stays verbatim in the archive, and this is the status surface. Verified against main on 2026-08-21 (packages/*/src, packages/contracts/src, .github/workflows/, schema.prisma), not against the commit log.

V1 — the batch’s verification tail ⬜ the batch is not actually finished

Wave 2 shipped the code and the deploy: UmaCtfAdapter.sol exists, staging’s deployments.json carries umaAdapter 0x1B45F820… pointed at UMA’s real Sepolia OptimisticOracleV2 0x9f1263B8…, oracleType is a first-class Market field fixed at creation, /create offers the choice, the market page shows the badge, resolve.ts branches on it, and uma-demo.ts + ../runbooks/uma-adapter.md walk propose → dispute → vote → finalize. What was never run is wave 3.

  Item Status Gap
V1.1 Fresh seed on staging ⬜ not run wave 2 changed the backbone (oracle-typed markets), so staging wants a first-run seed — no SKIP_SEED
V1.2 ≥1 market resolved end-to-end through the live adapter, winner redeems ⬜ not verified this is the §1.4 milestone and what closes audit item A5 (operator-SPOF). The demo path is proven against the mock oracle (MockOptimisticOracleV2.sol); live Sepolia is untested
V1.3 The CD workflow performing that deploy itself ⬜ not verified .github/workflows/deploy-staging.yml is on main and workflow_dispatch-able, but no run has been confirmed

Until V1.2 passes, S6 stays ◐ partial and A5 stays open — the adapter being deployed is not the same claim as the adapter having resolved anything.

V2 — ci.yml, the half of task 2 that was never written ⬜

The batch plan specified two workflows. Only the CD half exists. The CI half — pnpm install (corepack-pinned), turbo tsc/build for sdk/api/web, forge test in packages/contracts, prisma validate, pnpm-store cache, no deploy credentials — was never built, so nothing type-checks a PR automatically today. Done when: a PR with a deliberate type error goes red and a clean PR goes green including forge tests.

V3 — deferred by decision, kept for the reasoning

These were not forgotten; each was ruled out with a reason worth not re-deriving. Full argument in the archive.

  Item Why it was deferred When to revisit
V3.1 LMSR phase B — on-chain pool + smart routing + slo-mo fallback G1 closed NO (jay, 2026-08-04): every benefit is a benefit of not trusting the operator, and on Sepolia with test USDC there is no adversary and nobody who can lose money mainnet
V3.2 S5 indexer dropped 2026-08-03 — the justification did not survive reading the code; SETTLE_MATCH is already idempotent and onFailed compensates. Reframed as an observability tool, not a correctness one; a read-only DB-vs-chain consistency checker gets most of the value for none of the subsystem. Second trigger, 2026-08-25: the drop rested on “the DB is written only by the API”, and W6 ends that — an external holder can redeem, split or merge on CTF directly, and can move funds out from under a resting order. Still not a subsystem: the reframed read-only checker is the right size, and the first thing it should check is the resting-order gap in W6 after V1 — the adapter adds on-chain state the DB mirrors, including disputes that can change an answer days later — or once external makers are live. That trigger fired 2026-08-26: W6 is live, so the read-only checker is now actionable (queued as W5 in the plan)
V3.3 ChainlinkOracleAdapter demoted to optional 2026-08-03 by counting the seed: 1 of 13 markets is Chainlink-answerable, 13 of 13 suit UMA’s YES_OR_NO_QUERY. A strict subset of what UMA already covers only to tick the “≥1 market per adapter” milestone, using eth-above-10k-2026
V3.4 The constrained admin override inside the UMA adapter pure UMA is the more principled default for a Sepolia demo; the override matters if mainnet is ever the goal. Note it does not fully close A5 — it makes the operator’s lever exceptional, constrained, and visible on-chain instead of the only path mainnet

One open question that survives from wave 2 and is not written down anywhere else: who pays adapter gas, and who funds the bond. The bond currency is settled — Sepolia WETH 0x7b79995e…98E7f9, chosen for self-service (we wrap it ourselves) over UMA’s zero-final-fee USDC, which we cannot mint. Bond size (0.01 WETH) is an arbitrary demo knob.

V4 — roadmap steps with no code at all ⬜

Re-confirmed 2026-08-21 against packages/*/src. These are roadmap items, not owed work; they are here so a cold session does not have to re-grep to learn they are empty.

Step Status Confirmed by
S5 Indexer ⬜ none no packages/api/src/indexer.ts; the DB is written only by the API — see V3.2
S7–S8 AA / cross-chain ⬜ none no 4337 / session-key references under packages/*/src; no CCIP or LayerZero either. (2026-09-04 nuance: the fork seed is now 7702-aware — it probes and strips dead 7702 delegations on reused test accounts — but that is account hygiene, not an AA feature.) Design in account-abstraction.md, ccip-market-result.md
S8–S9 Stripe onboarding ⬜ none no stripe references under packages/*/src. Design in onboarding-payments.md
S10 Final ⬜ none
S3 gaps ⬜ 2 open packages/mcp-server does not exist (mcp-interface.md); ADR 0001 was never written (docs/architecture/ holds only the singleton-vs-factory ADR)

V5 — designed but not built

  Item State
V5.1 Market group types + probability-sum invariants (market-groups.md, designed 2026-08-21) ⬜ design only — MarketGroup exists in schema.prisma but there is no groupType field, so exclusive / directional-nested / independent groups are not yet distinguishable and the normalization rules have nothing to key off
V5.2 Observability — OTel-first, swappable backend (observability.md, designed 2026-08-17) ⬜ design only — no OpenTelemetry references under packages/*/src. The doc’s own sequencing puts the ChainJob worker first, since metrics structurally cannot answer “which step is slow”

Verex 프로젝트 설계 문서 (v1.1)

“사용자는 단순히 질문에 베팅하고, 시스템은 자동으로 결과를 정산한다.”


1. 프로젝트 개요

1.1 목표

Verex는 다음을 목표로 하는 Web3 애플리케이션이다:

1.2 핵심 컨셉

사용자는 질문에 베팅만 하면 되고, 결과 정산·유동성·결제 경험은 시스템이 자동화한다.

1.3 프로젝트 범위

포함

제외 (초기 단계)

1.4 단계별 일정 (10 steps)

§4의 phase 단위 로드맵을 step 단위로 분해한 일정. 각 step은 핵심 산출물 + 마일스톤 둘을 가진다 (예상 시간 열은 2026-08-18 제거 — jay). 일정이 밀리면 다음 step으로 미루지 말고 범위를 줄인다 (원칙 §9.1).

Phase · Step 핵심 산출물 마일스톤
Phase 1 — Scaffold · S1 - [x] Market / MarketFactory parimutuel scaffold (학습 패스)
- [x] SDK 모양 (factory + market client 패턴, ABI sync)
- [x] CLI + commander demo
- [x] forge-std + foundry tooling
- [x] M1: forge test 17/17
- [x] M2: anvil 위 end-to-end CLI demo
Phase 1 — Core (CTF v2) · S2 - [ ] Gnosis CTF 분석 (~2일)IConditionalTokens 인터페이스 + 5 핵심 함수 (prepareCondition / splitPosition / mergePositions / redeemPositions / reportPayouts) + position ID 수학 + Polymarket Exchange가 CTF를 어떻게 호출하는지 → reading note docs/analysis/gnosis-ctf-research.md
- [ ] Polymarket CTF Exchange import + Gnosis CTF (ERC-1155) 통합
- [ ] USDC mock collateral (anvil)
- [ ] Manual oracle (Stage 1 of 3) — operator EOA가 prepareCondition(ourEOA, ...) + reportPayouts(...) 직접 호출. Chainlink/UMA 도입 전까지 모든 마켓의 resolve 경로 (§2.2.7)
- [ ] SDK 표면 전환 — buyYes/buyNofillOrder/fillOrders + signOrder (EIP-712)
- [ ] MM Agent v0 (paper-trading) — CLOB가 동작할 최소 maker
- [ ] CLI을 order-based flow로 갱신
- [ ] CTF mint → split → merge → redeem 한 사이클이 Foundry 테스트로 통과
- [ ] CTF order fill end-to-end on anvil
- [ ] MM v0가 양방향 quote 유지
- [ ] Manual operator가 마켓을 resolve해서 winner가 redeem
Phase 1 — Web MVP · S3 - [ ] Web /markets Polymarket-style feed (실 CTF 데이터)
- [ ] /markets/[addr] order book + buy UI
- [ ] packages/mcp-server 스캐폴딩 + 2 read tool 구현 (list_markets, get_market)
- [ ] ADR 0001-mcp-server-as-canonical-agent-interface.md
- [ ] Metamask: order 서명 → fill → position 표시
- [ ] 두 지갑 시연 영상
Phase 2 — Infra+Data · S4 - [ ] packages/api Fastify (/markets, /orders, /positions/:user)
- [ ] Postgres 스키마 (Markets/Orders/Fills/Positions)
- [ ] 로컬 docker-compose
- [ ] API smoke 테스트 통과
Phase 2 — Infra+Data · S5 - [ ] Indexer (OrderFilled, PositionsMerged, PayoutRedemption → Postgres)
- [ ] Pub/Sub 로컬 에뮬레이터
- [ ] genesis 백필
- [ ] 체인 ↔ DB 동기화 검증
Phase 2 — Infra+Data · S6 - [ ] Chainlink adapter (Stage 2 of 3)ChainlinkOracleAdapter.sol 컨트랙트가 Chainlink price feed 읽고 endTime 후 reportPayouts 자동 호출. 숫자 기반 마켓 (“ETH > $4000 by date X”) 용 (§2.2.7)
- [ ] UMA adapter (Stage 3 of 3)UMAOptimisticOracleAdapter.sol 컨트랙트가 UMA OptimisticOracleV2.requestPrice 통합. 이벤트/뉴스 마켓 (“Did Brazil win?”) 용 — Chainlink가 답할 수 없는 주관적 질문 (§2.2.7)
- [ ] MM Agent v1 (실거래 + 리스크 한도 + 서킷 브레이커)
- [ ] 적어도 한 마켓을 Chainlink adapter로 resolve
- [ ] 적어도 한 마켓을 UMA adapter로 resolve
- [ ] MM v1 paper → live 전환 체크리스트 통과
Phase 3 — Advanced · S7 - [ ] AA 전략 결정 — ERC-4337 / EIP-7702 / hybrid (§11.4 B2) → ADR 0002-aa-strategy.md
- [ ] AA wallet 구현 + Web AA 통합
- [ ] session key 권한 모델 확정 (§11.1 미결 1번)
- [ ] One-click betting (production)approve(USDC) + fillOrder 1 서명 (§11.4 B3)
- [ ] Auto-claim delegate 컨트랙트 + scheduler (§11.4 B6) — 사용자 EOA에 대해 ONLY redeemPositions 허용하는 최소 delegate; backend scheduler가 resolved 마켓 watch하고 자동 트리거
- [ ] 사용자가 AA wallet으로 베팅
- [ ] 1 서명으로 approve+fill 동작
- [ ] resolved 마켓의 winner가 수동 호출 없이 USDC 수령
Phase 3 — Advanced · S8 - [ ] CCIP/LayerZero 크로스체인 참여
- [ ] MCP write-path tool 활성화 (buy_yes/no, claim — session key 경유)
- [ ] Gasless onboarding (production) (§11.4 B4) — Paymaster가 신규 지갑의 첫 N=5 거래 후원
- [ ] Paymaster spend tracker (§11.4 B7) — per-wallet 카운터 (off-chain DB 또는 on-chain mapping; S8 시작 시 결정)
- [ ] 다른 체인에서 베팅
- [ ] MCP로 베팅 시연
- [ ] 신규 유저가 ETH 0으로 베팅 완주
- [ ] N+1번째 거래에서 후원 중단 동작 확인
Phase 3 — Advanced · S9 - [ ] Stripe checkout → backend → mock USDC 지급
- [ ] GCP Cloud Run 배포 (API + MM Agent)
- [ ] GitHub Actions CI/CD
- [ ] Stripe 결제 → 베팅 가능
- [ ] staging 환경 가동
Phase 4 — Final · S10 - [ ] ZK 탐색 (optional, 타임박스)
- [ ] UI polish
- [ ] 공개 demo 영상
- [ ] README 최종
- [ ] 회고 문서 (docs/history/)
- [ ] Demo Day

총 예상: ~25–35일 집중 작업 (캘린더로는 회복일 / 외부 대기 / 비-코딩 작업 포함해서 6–8주 정도가 현실적).

해석 가이드

1.5 Sub-step 라벨 (S2.x 컨벤션)

§1.4 표는 step 단위 (S1..S10)만 정의함. 한 step (특히 S2) 안의 작업을 시간 순서대로 나눠 추적할 때는 history doc에서 S<step>.<n> 형식의 sub-step 라벨을 비공식 컨벤션으로 사용. plan에 first-class entity는 아니고, 작업 단위 cross-reference 용.

현재 사용 중인 S2 sub-step 매핑 (S2 row의 deliverable 불릿을 시간 순서로 분해):

라벨 작업 단위 첫 등장
S2.1 Gnosis CTF 분석 (research note + Foundry cycle 테스트) history.md 2026-05-11
S2.2 Polymarket CTF Exchange import + Gnosis CTF deploy history.md 2026-05-11
S2.3 CTF order fill end-to-end (Foundry-level + anvil 데모 스크립트) history.md 2026-05-26
S2.4 SDK 표면 전환 — buyYes/buyNofillOrder/signOrder (EIP-712) history.md 2026-05-13
S2.5 MM Agent v0 (paper-trading minimum maker) history.md 2026-05-13
S2.6 CLI을 order-based flow로 갱신 history.md 2026-05-13

운영 규칙:


2. 시스템 아키텍처

2.1 전체 구조

[Frontend]
   ↓
[API Server]
   ↓
[Event System (Pub/Sub or Kafka)]
   ↓
[Indexer Workers]
   ↓
[PostgreSQL]
        ↘ Blockchain (EVM)
                  ↑
            [MM Agent]   ← 별도 워커 프로세스

2.2 주요 구성 요소

2.2.1 Smart Contracts

메인 백본 (S2부터):

핵심 기능:

Phase 1 S1의 parimutuel scaffold (Market.sol, MarketFactory.sol)는 SDK/CLI 모양 검증용 학습 패스였고 메인 백본은 아님 (planning 브랜치 history 참고).

2.2.2 Backend

역할:

주요 엔드포인트:

GET /markets
GET /markets/:id
GET /positions/:user

2.2.3 Indexer

Blockchain event → DB 저장.

2.2.4 Event System

2.2.5 Database

PostgreSQL (Cloud SQL).

2.2.6 Frontend

디자인 방향: Polymarket-style CLOB UI (S3부터 실데이터)

UI 레이아웃과 시각적 밀도는 Polymarket 메인 피드 스타일 — 카드 그리드 피드, 카테고리/검색 네비게이션, 멀티해상도 마켓 그룹화, 트렌딩 사이드바, 추천 마켓 hero 카드.

S3에 Web MVP가 들어올 시점엔 이미 S2의 CTF Exchange 백본이 작동 중이므로, 호가창·시계열·다해상도 확률 차트 모두 실데이터로 동작한다. (S1 parimutuel scaffold는 backend가 못 채우는 요소가 있었으나 메인 백본 아님 — §4.5 참고.)

차용 범위: layout/density/카드 구조에 대한 영감만. 브랜드 컬러, 타이포, 카피, 아이콘 세트는 자체 결정 (Polymarket의 시각 identity를 그대로 복사하지 않음).

UI 레퍼런스 (한국어 로컬라이즈, 2026-05-07):

Polymarket reference

원본 파일: packages/web/public/mockups/polymarket-reference.png

기능:

2.2.7 Oracle (3-stage progression)

마켓 resolve를 누가/어떻게 결정하는가에 대한 단계적 도입. 각 stage가 새로운 oracle 컨트랙트 주소를 가지므로 마켓 생성 시 쓸 oracle을 선택 (prepareCondition(oracleAddr, ...)). 같은 마켓의 oracle을 사후 변경할 수 없음 — 새 마켓은 새 oracle 사용.

Stage 시점 Oracle 사용 케이스 한계
1. Manual S2~ 운영자 EOA 모든 종류 (수동) 운영자가 SPOF (§11.3 A5). 빠르지만 신뢰 의존
2. Chainlink adapter S6 first ChainlinkOracleAdapter 컨트랙트 숫자 마켓 — 가격, 통계 등 “ETH > $4000 by 2027-01-01” Chainlink가 인덱싱하는 수치만. 주관적 질문 불가
3. UMA adapter S6 second UMAOptimisticOracleAdapter 컨트랙트 이벤트/뉴스 — “Did Brazil win the World Cup?” 응답 지연 (분쟁 윈도우). 분쟁 시 escalation 비용

채택 순서가 manual → Chainlink → UMA인 이유: 신뢰 가정의 점진적 분산. Manual은 단일 운영자 전제 (가장 빠른 출시); Chainlink는 분산된 oracle 네트워크지만 데이터 종류 제한; UMA는 분쟁 가능 + 사람 attestation으로 임의의 명제도 다룸 (가장 강한 보증, 가장 큰 시스템 복잡도).

같은 종류 마켓에 여러 oracle 가능: “ETH > $4000?” 마켓을 stage 1엔 manual로 한 번, stage 2엔 Chainlink로 한 번 만들 수 있음 (서로 다른 conditionId). UI가 어느 마켓이 어느 oracle인지 표시.

2.2.8 Account Abstraction

기본 기능:

EIP-7702 기반 사용자 대면 기능 (S7~S8 산출):

선택된 AA 전략이 EIP-7702 또는 hybrid일 때 활성화:

자세한 구현·결정 항목은 §11.4 참고.

2.2.9 Cross-chain

2.2.10 Payment (Stripe)

2.2.11 MM Agent (Market Maker, 신규 subproject)

자동화된 마켓 메이커 봇. 별도 워커 프로세스로 실행되며 SDK를 통해 컨트랙트와 상호작용한다.

목적

핵심 기능

범위 (초기)

범위 (제외, 후속)

기술 스택


3. 인프라 (GCP)

3.1 구성

3.2 배포 전략

3.3 CI/CD

GitHub Actions.


4. 개발 로드맵 (10 steps)

Phase 1: Core (Step 1~3)

Phase 2: Infra + Data (Step 4~6)

Phase 3: Advanced (Step 7~9)

Phase 4: Final (Step 10)

4.5 백엔드 버전 분리 (v1 / v2)

Historical note (2026-05-11 갱신): 이전 plan은 Phase 1 (S1~3)을 v1 (fixed-price escrow), Phase 2 S6에 v2 (CTF) 전환으로 두었음. 운영자 prior CTF 경험을 반영해 v2를 S2부터 메인 백본으로 당김. S1의 parimutuel Market/MarketFactory 코드는 SDK/CLI 모양 검증용 학습 패스로 planning 브랜치 history에 보존 — 메인 라인은 S2의 CTF Exchange + Gnosis CTF + USDC.

무엇이 S1에서 S2로 carry over하나

S1 코드 자체와 v1 보안 audit 발견은 Phase 1 S1 implementation note (2026-05-07-phase1-w1-implementation.md) 와 v1 Security Audit (2026-05-08-v1-security-audit.md) 에서 historical record로 추적됨.


5. 데이터 모델

Markets

Trades

Positions

MMQuotes (MM Agent 전용)

MMInventory


6. 핵심 기능 정의

6.1 Market Flow

  1. createMarket
  2. MM Agent가 초기 호가 제공
  3. 사용자가 YES/NO 매수
  4. market 종료
  5. resolve
  6. claim

6.2 UX 목표


7. 폴더 구조

monorepo는 pnpm workspaces + Turborepo 기반.

verex/
├── packages/
│   ├── contracts/        # Foundry, Solidity 0.8.24
│   ├── sdk/              # TypeScript, viem — 컨트랙트 wrapper
│   ├── api/              # Fastify REST API
│   ├── web/              # Next.js 14 dApp
│   └── mm-agent/         # 신규: 자동 마켓 메이커 워커
│       ├── src/
│       │   ├── index.ts        # CLI 엔트리
│       │   ├── runner.ts       # 메인 루프 (poll → quote → submit)
│       │   ├── strategy.ts     # 가격/사이즈 결정
│       │   ├── inventory.ts    # 포지션 추적
│       │   ├── risk.ts         # 한도 및 서킷 브레이커
│       │   └── config.ts       # market별 설정 로더
│       ├── test/
│       ├── package.json
│       └── README.md
├── docs/
│   ├── principles/       # 설계 원칙, 요구사항 (이 문서)
│   ├── plans/            # phase별 실행 계획
│   └── history/          # 의사결정 로그
├── package.json
├── pnpm-workspace.yaml
└── turbo.json

원칙


8. 확장 계획

ZK

XR (Vision Pro)

MM Agent 진화


9. 개발 원칙

9.1 핵심 원칙

9.2 금지


10. 성공 기준


11. TODO / 오픈 이슈

확정되지 않았지만 추적해야 할 요구사항. 설계가 무르익으면 본문 섹션으로 승격한다.

11.1 Harness 기반 + 개인 AI 에이전트 (신규, 미확정)

의도

1차 후보 하네스: OpenClaw

보조 옵션 (병행 검토)

Verex × OpenClaw skill (초안)

사용자의 OpenClaw에 설치되는 skill이 노출할 도구:

읽기는 @verex/sdk로 RPC만 치면 되고, 쓰기는 §2.2.8 AA + session key 위임이 전제.

해결해야 할 질문

  1. (가장 큰 미결) 지갑 서명 권한 — AA(§2.2.8)에서 사용자가 자기 OpenClaw에 어떤 범위의 session key를 위임할 것인가? 한도/만료/허용 함수 화이트리스트 설계 필요.
  2. Skill 배포 경로 — Verex가 ClawHub에 공식 publish할지, repo에 자체 skill 폴더 두고 사용자가 가져가게 할지.
  3. 시스템 측(MM Agent §2.2.11, indexer 등)에 Claude Agent SDK를 쓸 것인가, 아니면 단순 워커로 둘 것인가 — 현 단계는 후자(단순 워커) 권장, AI가 필요한 영역만 후속 도입.
  4. Phase 진입 시점 — Phase 2 후반 ~ Phase 3 (AA가 자리잡은 뒤). 현재 로드맵엔 별도 트랙으로 추가 예정.

다음 액션

  1. AA(ERC-4337) + session key로 OpenClaw가 위임받을 수 있는 권한 모델 PoC 스펙 작성
  2. packages/openclaw-skill/ 폴더 추가 검토 (skill 매니페스트 + tool 정의)
  3. Phase 3 로드맵에 “Personal agent 통합” 항목 추가 후 본문 §2.2.x로 승격

11.2 CTF Exchange (v2) 통합 — 코드로 이전됨

CTF Exchange는 이제 S2 메인 백본 (§1.4 / §4 Phase 1). 더 이상 planning 트랙이 아니라 implementation 트랙. 본 절에 있던 결정 항목들은 S2 진입 시점에 코드/ADR로 해소됨:

Historical context: 이전 §11.2는 “v2를 S6에 시작할지” 결정 항목을 추적했음. 2026-05-11에 S2로 당기는 결정 후 trim. 자세한 전환 배경은 §4.5 참고.

11.3 v1 Security Audit — 액션 항목

셀프 리뷰 산출물: docs/analysis/2026-05-08-v1-security-audit.md. 본 절은 그 audit에서 추적이 필요한 액션 항목만 모음.

리뷰 결과 요약: HIGH 0 / MEDIUM 1 / LOW 2 / INFO 6. v1 발견의 ~70%는 v2 (Phase 2 S6 — CTF + UMA) 도입으로 자동 해소.

액션 항목 (트리거 시점별)

# 항목 Severity 트리거 시점 위치
A1 PRIVATE_KEY env fallback 제거 — vm.envOrvm.envUint INFO testnet/staging deploy 직전 packages/contracts/script/Deploy.s.sol:18
A2 CLI에 chainId 가드 추가 (anvil 31337만 허용) INFO S2 진입 시 함께, 늦어도 testnet 진입 전 packages/cli/src/clients.ts
A3 운영 절차: resolve 전 yesPool > 0 && noPool > 0 확인 LOW OBSOLETE (v1 parimutuel-only) — S2 CTF는 별도 풀 개념 없음 n/a
A4 MarketFactory.getMarkets() pagination LOW OBSOLETE (v1-only) — S2 CTF는 다른 레지스트리 패턴 n/a
A5 단일 글로벌 owner SPOF — 별도 mitigation 없이 S6 UMA 도입에 의존 MEDIUM S6 UMA 통합 시 자동 해소 n/a — 추적만

원칙: v1 자체 hardening은 더 이상 우선순위 아님 (S1 코드는 history). A1/A2는 S2 작업 + testnet 진입 시점에 함께 처리, A3/A4는 v1-only라 obsolete, A5는 S6 UMA가 해소.

상세 (severity 판단 근거, mitigation 분석, v2 매핑): audit 문서 §2 ~ §5 참고.

11.4 EIP-7702 (EOA delegation) — Phase 3 AA 전략 결정

풀 리서치 노트: docs/analysis/eip-7702-research.md. 본 절은 그 노트에서 추적이 필요한 결정·액션만 모음.

한 줄 컨텍스트: EIP-7702는 EOA가 특정 트랜잭션에서 임시로 컨트랙트 코드를 빌려 실행할 수 있게 하는 표준. 별도 스마트 계정 배포 없이 배치 실행 / 가스 스폰서십 / 소셜 복구 같은 AA 핵심 기능을 EOA에서 직접 제공. ERC-4337 (현 §2.2.8 후보)과 경합·보완 관계.

액션 항목 (트리거 시점별)

# 항목 Priority 트리거 시점 산출물 위치
B1 대상 체인의 EIP-7702 지원 상태 검증 (활성화 여부, RPC 호환성, viem 버전 요구사항). 대상 체인은 §2.2.1/§3에서 정해지는 배포 체인 HIGH Phase 3 S7 진입 전 docs/analysis/eip-7702-research.md 갱신
B2 AA 전략 결정: (a) ERC-4337 only / (b) EIP-7702 only / (c) hybrid HIGH S7 시작 시 §2.2.8 본문 갱신 + ADR docs/history/0002-aa-strategy.md
B3 배치 트랜잭션 PoC — USDC approve + createPosition 1 서명 MEDIUM S7 PoC 단계 packages/contracts/src/BatchExecutor.sol (또는 외부 audited contract 채택)
B4 Paymaster 가스 스폰서십 PoC — 신규 유저 첫 베팅 무가스 MEDIUM S7~S8 packages/api 또는 외부 paymaster 서비스 통합
B5 DelegateContract 선택 기준 + Revoke 패턴 audit-grade로 정리 HIGH 실거래 (testnet 이상) 진입 전 docs/security/eip-7702-delegate-policy.md
B6 Auto-claim delegate 컨트랙트 — 특정 사용자에 대해 ONLY redeemPositions 허용하는 최소 delegate. 다른 function selector 없음, audit-grade. + backend scheduler가 resolved 마켓 watch HIGH S7 mid-week (S7 AA wallet 구현 후) packages/contracts/src/AutoClaimDelegate.sol + packages/api의 scheduler 모듈
B7 Paymaster spend tracker — per-wallet 카운터, 첫 N=5 거래만 후원, N+1번째부터 중단. 저장: off-chain DB vs on-chain mapping 결정 MEDIUM S8 시작 시 결정 후 — packages/api 또는 packages/contracts/src/PaymasterSpendCap.sol
B8 모듈러 계정 표준 선택 (B2 하위 결정) — B2가 4337/hybrid로 결정될 경우 스마트 계정의 모듈 표준: ERC-6900 vs ERC-7579 (권고). 계정은 7579 계열 (Nexus/Kernel v3), 인프라 (번들러·페이마스터)는 독립 층이라 Alchemy 유지. 리서치: docs/analysis/erc-6900-vs-7579-research.md HIGH S7 시작 시 (B2와 함께) ADR 0002-aa-strategy.md에 포함 + features/account-abstraction.md 갱신

연결되는 본문 섹션

원칙: Phase 3 진입 전까지는 리서치 단계. 본격 PoC는 S7 시작과 함께. v2 (CTF Exchange) 통합과 별개로 진행 가능 — 단 둘 다 같은 시기에 들어오므로 일정 조정 필요.


🎯 최종 한 줄

“Verex는 Web3 기술을 통합한 실전형 예측시장 플랫폼이다.”