This file records each day’s work in KST.
docs/plan/README.md 갱신:
<br> + 불릿으로 쪼개 컬럼 폭 균형 조정docs/plan/01-phase-1-core.md 갱신: “AMM 욕심 금지” → “AMM/CLOB 욕심 금지” + W6 결정 지점 참조, SDK 인터페이스가 미래 CLOB 전환에 어색해지지 않게 두라는 주의 추가, 후속 Phase 요약에 CTF 결정 명시.packages/contracts에 Market.sol + MarketFactory.sol (fixed-price escrow, 수동 resolve) + Foundry 테스트. Day 3까지 forge test 통과가 M1.packages/contracts 컨트랙트 + Foundry 테스트 (M1)packages/sdk viem 래퍼 + ABI 자동 syncpackages/cli 신규 패키지 (commander 기반) + end-to-end demo (M2)§4.5 신설 / §11.2 트림 / §2.2.6 Polymarket-style UI 방향 명시 / 01-phase-1-core.md 동기화packages/web/public/mockups/polymarket-reference.png)2026-05-07-phase1-w1-implementation.md 참고.
scripts/sync-abis.mjs → src/abis/*.ts as const) — 수동 복사 0줄packages/cli/ 패키지 — verex create/list/info/buy/resolve/claim/position + demo.ts (one-shot 시연)§4.5 백엔드 버전 분리 (v1/v2) 신설 — 비교 표 7행 (Backend/Collateral/Pricing/Resolve/Maker/SDK 표면/UI 레이아웃)§2.2.6 Frontend — Polymarket-style 방향 + 차용 범위 (layout/density만 영감, 브랜드 컬러/타이포는 자체) + mockup embed§11.2 트림 — 비교 표·이유 등은 §4.5로 이동, 이제 “v2 통합 시 결정할 4개 항목 + 사전 액션 3개”만 남김01-phase-1-core.md 동기화 — “AMM/CLOB 욕심 금지” 줄을 v1/v2 어조로 갱신, Web 컴포넌트 v1/v2 모드 분리 주의 추가skipLibCheck 빠뜨려서 발생 — 새 TS 패키지 만들 때 default tsconfig 템플릿에 skipLibCheck: true 박아두는 게 좋겠음.packages/mcp-server 스캐폴딩 + 4개 read tool 선언 (list_markets, get_market, get_position, get_market_stats) 중 2개 구현 (list_markets, get_market). M2.5 (Day 11): Claude Desktop에서 anvil markets 조회./markets, /markets/[addr]) — Polymarket-style layout (placeholder data로). v1 단계에 backend가 못 채우는 호가창/시계열은 단순화된 표현.docs/history/0001-mcp-server-as-canonical-agent-interface.md (W2 plan 요구 사항).docs/history/verex: command not found confusion)package.json에 verex 스크립트 추가 (pnpm verex <subcommand>)2026-05-08-v1-security-audit.md. 7개 섹션, severity HIGH 0 / MEDIUM 1 / LOW 2 / INFO 6.
block.timestamp 비교 경고 — v1엔 시간 단위가 시간/일이라 12초 drift 무관, 수용getMarkets() unbounded 배열 (마켓 수 폭증 시 가스 한도 hit)PRIVATE_KEY env fallback.call, double-claim 등) 별도 정리PRIVATE_KEY fallback 제거, CLI chainId 가드, 운영 절차, pagination, owner SPOF). 각 항목에 severity / 트리거 시점 / 코드 위치 명시. audit 문서가 owner이고 plan §11.3은 추적용 — 두 곳이 중복되지 않게 분리.2026-05-07-phase1-w1-implementation.md §6.1, §7.2) — verex 명령이 command not found로 실패하는 원인 (workspace 패키지 bin shim 미생성)과 4가지 우회법 (node 직접 호출, pnpm exec, alias, pnpm link --global) 정리.package.json에 verex 스크립트 추가 — node packages/cli/dist/index.js로 위임. 이제 pnpm verex <subcommand> [options] 로 호출 가능. -f 같은 플래그가 pnpm 자체와 충돌하지 않게 위치(서브커맨드 뒤)만 지키면 됨.0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9, owner 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (anvil account[0]). pnpm verex list -f ...로 빈 상태 확인.block.timestamp)에서 시작해 audit 전체로 자연스럽게 확장. 발견을 단순히 “고친다/안 고친다”가 아니라 v2 도입과의 시간축에 매핑(70% 자동 해소)함으로써, v1 hardening 우선순위를 plan과 일관되게 낮춤. CLI invocation 혼란도 alias/link/script 4가지 옵션을 비교한 뒤 가장 portable한 root script 채택 — 결정 근거를 detail 문서에 남김.verex create ... 라고 적어 사용자가 command not found를 만났음. 새 CLI 패키지를 만들 땐 처음부터 호출 패턴을 검증/문서화해야 — 코드 작동 = “사람이 호출 가능”은 아님. 또 audit를 W1 직후가 아니라 시간차로 한 게 좋은 점도 있음(코드 익숙해진 뒤): “audit는 implementation 직후가 항상 최선은 아니다” 패턴.PRIVATE_KEY fallback 제거) / A2 (CLI chainId 가드)는 W2 작업 중 함께 처리 가능 — quick wins.ctf-exchange 브랜치 생성 (main에서 분기, 미커밋 작업 carry over)docs/plan/gnosis-ctf-research.md 작성 (~280줄, 9 섹션)- [ ] / - [x] 체크박스 적용. S1은 이미 완료라 [x] + ✅ 표시.docs/plan/gnosis-ctf-research.md. 마일스톤: CTF mint→split→merge→redeem 한 사이클이 Foundry 테스트로 통과.gnosis-ctf-research.md 작성 (9 섹션): mental model, 5 핵심 함수 (prepareCondition / splitPosition / mergePositions / reportPayouts / redeemPositions), position ID 유도 (collateral → collectionId → positionId 키체인), event table (S5 indexer 준비), Polymarket Exchange의 CTF 사용 패턴 (AssetOperations.sol에서 본 hard-code parentCollectionId = bytes32(0) + partition = [1, 2]), CTF vs Exchange 경계, open questions 5개, S2.2~S2.6 매핑, 추천 reading order. 자세한 내용은 2026-05-11-plan-restructure-and-gnosis-research.md 참고.ctf-exchange 브랜치 생성 — main에서 분기. 오늘의 모든 작업은 이 브랜치에 commit (push는 안 함, 사용자 미요청).approve(USDC) + fillOrder 1 서명. 기존 “배치 tx PoC”를 production track으로 reframe.redeemPositions를 자동 호출. 사용자 EOA에 ONLY redeemPositions 허용하는 audit-grade 최소 delegate 사용.make plan-check 같은 lint 스크립트로 §11.x 항목이 §1.4 어딘가에서 referenced되는지 자동 검증하면 좋겠음 (지금은 우선순위 낮음).packages/contracts/test/CTFCycle.t.sol. Gnosis CTF (gnosis/conditional-tokens-contracts)를 git submodule로 vendor. 배포 → split → (시뮬레이트 거래) → merge → reportPayouts → redeem 한 사이클을 anvil에서 통과.redeemPositions 동작 — revert 없이 0 반환 검증splitPosition 가능성 — resolve 후 split 시도, revert 여부 확인splitPosition/mergePositions의 ERC-1155 hook (onERC1155Received) 분석 + 보호 수단 검토splitPosition vs 직접 safeTransferFrom 비교 (forge snapshot으로)questionId 컨벤션 — keccak256(질문 텍스트) vs UMA 호환 형식. S6 oracle 전환 시 마이그레이션 비용 고려해서 결정 + research note에 적용nostra-contracts 작업이 같은 패턴 한 번 한 경험이라 §7 답변 + 테스트 작성 가속 가능d0add3a)6d8d920)DeployCTF.s.sol로 anvil에 USDC + ConditionalTokens + CTFExchange 한 번에 배포 성공 (같은 커밋 6d8d920)fdeece7)~/.claude/projects/-Users-jay-work/memory/feedback_english_learning_format.md + ~/.claude/CLAUDE.md 글로벌buyYes/buyNo → fillOrder/fillOrders + signOrder EIP-712). 디자인 결정 항목 다수 — 사용자 입력 필요ctf-exchange 저장소를 submodule로 vendor → 그들의 pre-built ConditionalTokens 바이트코드 (Solidity 0.5.x 컴파일된 artifact) + IConditionalTokens 인터페이스 + CTFExchange 소스 한꺼번에 사용 가능test/CTFCycle.t.sol (11 tests) 가 mint→split→merge→redeem 전체 사이클 + open question에 대한 표적 테스트 실행. 전체 Foundry suite 28/28 통과 (S1: 17 + S2.1: 11)"condition already prepared" (SDK 래퍼에서 try/catch로 idempotent 인터페이스 만들기 가능)onERC1155BatchReceived 구현 (안 하면 spec대로 revert)redeem([1,2]) 통합 호출이 분리 호출 두 개 합보다 33% 저렴 (54k vs 82k)getCollectionId / getPositionId helper 사용으로 수정IERC20.balanceOf(address)) 호출하는 stray 라인 → 제거script/DeployCTF.s.sol 가 anvil에 v2 backbone 한 번에 배포 — MockUSDC (0x5FbDB23156...) + ConditionalTokens (0xe7f1725E77..., Polymarket의 pre-built 아티팩트에서 raw bytecode로 deploy) + CTFExchange (0x9fE4673667..., 소스 컴파일). pragma 협상: CTFExchange가 =0.8.15 픽 → MockUSDC와 DeployCTF script도 ^0.8.15로 (한 컴파일 단위 공유). 다른 컨트랙트들 (Market.sol, MarketFactory.sol from S1)은 ^0.8.24 유지. foundry.toml에서 solc 핀 제거 → multi-version 자동 선택.~/.claude/projects/-Users-jay-work/memory/feedback_english_learning_format.md (프로젝트 범위, 80줄 spec) + ~/.claude/CLAUDE.md (글로벌, 50줄 leaner). 미래 모든 Claude Code 세션에서 자동 적용. 자세한 결정/구현은 2026-05-13-s2-implementation-and-oracle-progression.md 참고.packages/contracts/src/MockUSDC.sol (80줄) — 6 decimal mock ERC-20, mint open. 왜 OZ ERC20 안 쓰고 자체? (의도: 미니멀, dependency 없음)packages/contracts/script/DeployCTF.s.sol (~70줄) — pragma 협상 (^0.8.15 vs CTFExchange =0.8.15), vm.parseJsonBytes로 raw bytecode deploy 패턴, address(0) factories 의미packages/contracts/test/CTFCycle.t.sol (~260줄) — 11 테스트 구조, _deployCTF helper, _balance1155 staticcall 패턴, ContractWithReceiver / ContractWithoutReceiver 헬퍼 contracts. 각 테스트가 §7의 어느 question에 대응하는지 확인. 두 wrong provisional 답변이 어떻게 잡혔는지 코드로 트레이스.foundry.toml — solc 핀 제거 + fs_permissions 추가의 의미.remappings.txt — Polymarket의 lib 구조와 우리 매핑 관계.buyYes/buyNo escrow → fillOrder/fillOrders + signOrder EIP-712). 결정 사항 다수 — 답변 후 진행:
signOrder vs createOrder+signOrder?)verex order sign, verex order fill, verex split, verex merge, verex redeem 같은 명령).ctf-exchange 브랜치를 main으로 머지 — 선행 조건: ① 위 코드 분석 완료, ② forge test 28/28 여전히 pass (regression 없음). PR 또는 직접 fast-forward 머지. 머지 후 브랜치 삭제 또는 보존은 별도 결정 (보존 추천 — S2 작업 단위로 history 추적 가능).docs/analysis/ 폴더 신설 + gnosis-ctf-research.md, eip-7702-research.md, 2026-05-08-v1-security-audit.md 이동 + docs/plan/README.md live 링크 갱신fillOrder end-to-end Foundry 테스트 (test/CTFFillOrder.t.sol, 6 tests, 34/34 전체 통과)script/DemoMarket.s.sol (setup + resolve 두 entrypoint)cast sanity check → resolve → 3 payout 확인 + 옵션 redeem)S2.x sub-step 라벨 컨벤션 명문화 (라벨 정의가 history doc에만 흩어져 있던 문제 해결; grep "S2.5" docs/plan/README.md으로 찾을 수 있게)signOrder EIP-712 TS 구현 + fillOrder helper)test/CTFFillOrder.t.sol (6 tests, ~270줄) 가 Polymarket CTFExchange의 fillOrder 전체 경로를 검증: EIP-712 maker order 서명 (exchange.hashOrder() + vm.sign) → operator가 fillOrder 호출 → USDC + CT (ERC-1155) 정산 검증. 전체 suite 34/34 pass (이전 28 + 신규 6). 자세한 내용은 2026-05-26-s2-fillorder-e2e.md 참고.
fillOrder BUY full-fill = ~110k gas — MM/SDK capacity planning baselinescript/DemoMarket.s.sol 추가 — anvil 위 데모 마켓 lifecycle 자동화. setup() (prepareCondition + registerToken + addOperator + 인벤토리 prefund) + resolve(yesPayout, noPayout) (operator=oracle이 reportPayouts) 두 entrypoint를 --sig로 분리 호출. manual oracle (Stage 1) 구현 = operator EOA 자신이 oracle 역할 (plan §2.2.7의 3-stage 진행 첫 단계). 컨트랙트 코드 추가 없음 — CTF의 prepareCondition(oracle, ...)이 oracle을 임의 EOA로 받기 때문에 script가 곧 구현체.CTFCycle.t.sol (^0.8.24, raw bytecode로 CTF deploy)과 별도로 신규 CTFFillOrder.t.sol을 ^0.8.15 컴파일 단위로 분리해서 CTFExchange를 concretely import. surgical change — 기존 테스트 안 건드림.exchange.hashOrder(order) public view를 호출해서 digest 받고 vm.sign하면 Polymarket pragma/struct가 바뀌어도 테스트 안 깨짐. 단, off-chain SDK (TS)에서는 같은 shortcut 못 씀 — S2.4의 핵심 risk로 history doc 명시.docs/plan/과 docs/history/에 흩어진 분석 문서를 docs/analysis/ 하나로. gnosis-ctf-research.md, eip-7702-research.md, 2026-05-08-v1-security-audit.md 세 개. live 참조 (docs/plan/README.md 6곳, test/CTFCycle.t.sol 1곳)는 모두 새 경로로 업데이트. docs/history/history.md의 stale 링크 1개 (2026-05-08-v1-security-audit.md 참조)는 의도적으로 그대로 — 역사 기록은 작성 시점의 상태를 보존.forge test 30초 smoke check, (B) anvil 7-step 라이브 데모 (anvil 띄움 → DeployCTF broadcast → env export → DemoMarket setup() → 5개 cast sanity check → resolve(1,0) → 3개 payout cast 확인 + 옵션 step 7 cast send redeemPositions로 1000 USDC 회수 검증). §4.3에 검증 안 되는 것 명시 (off-chain TS 서명, CLI, MM agent, matchOrders 경로) — partial confidence 정직하게 표시.grep "S2.5" docs/plan/README.md로 찾을 수 있음.fillOrder e2e + manual oracle script) 하나만 surgical하게 닫고 나머지 (SDK / CLI / MM)는 explicit deferral로 history doc에 enumerate. 한 세션에서 거대한 unreviewable diff 생산하지 않음 — coding-principles의 “If you write 200 lines and it could be 50, rewrite it” + “Push back when warranted” 적용. EIP-712 서명을 exchange.hashOrder() shortcut으로 풀어서 테스트 견고하게 — Polymarket이 향후 pragma 바꿔도 안 깨짐. _sign helper 한 줄짜리 패턴이 6 테스트 모두에 재사용됨.DemoMarket.s.sol를 컴파일 통과만 확인하고 실제 anvil broadcast 검증은 하지 않음 — 두 단계 dependency (anvil + DeployCTF) 셋업 비용이 컸음. 회귀가 있다면 다음 세션 1순위로 픽스 필요. 또 matchOrders 경로는 이 슬라이스에서 다루지 않음 — MM Agent v0가 fillOrder model이냐 matchOrders model이냐가 S2.5 첫 결정인데, fillOrder 한쪽만 테스트 커버리지 있어서 결정 시 reference 부족할 수 있음. S2.5 진입 전에 matchOrders 테스트 추가가 prudent.signOrder + fillOrder helper. 진입 전 결정 항목 4개 (이전 2026-05-13 Next Task에 enumerated): SDK 함수 명명 / EIP-712 domain 처리 / Order struct 직렬화 / 에러 패턴. 추가: 오늘 history doc §5의 Q-S2.3.1 (hybrid hashOrder RPC vs 순수 off-chain EIP-712) — 순수 off-chain 추천.matchOrders 테스트 추가: MM Agent v0 (S2.5) 결정 입력으로 필요. MINT (두 BUY 매칭) / MERGE (두 SELL 매칭) / COMPLEMENTARY (BUY vs SELL) 세 분기 모두 커버.packages/mm-agent?). fillOrder (inventory model) vs matchOrders (matcher model) 선택. Q-S2.3.2 추천: matchOrders.verex order sign/fill, verex split/merge/redeem.DemoMarket.s.sol 라이브 anvil 실행 — 이번 세션 deferred. 사용자가 직접 anvil + DeployCTF + DemoMarket setup + resolve 사이클 한 번 돌려보고 회귀 확인.@verex/sdk v1(Market/MarketFactory) 제거 + CTF surface 신규 (orders / conditions / ct / exchange / usdc / clients)sync-abis.mjs — CTFExchange / IConditionalTokens / MockUSDC 동기화 (Market / MarketFactory 드롭)hashOrder parity 검증 — forge로 emit한 golden digest + vitest (3/3 pass)@verex/cli 재작성 — 10개 CTF 커맨드 (setup / resolve / split / merge / redeem / mint / order sign|fill / balance / condition) + demo.ts E2E 재작성forge test 회귀 확인 (34/34 통과, EmitOrderHash.s.sol 추가에도 영향 없음)docs/plan/watch-list.md 신설 — 외부 트리거 기반 결정 인박스. 항목 1 (Glamsterdam BAL 친화 설계) + 항목 2 (Phase 2 컨트랙트 인터페이스의 Native AA 가정) 등록docs/history/2026-05-27-s2.4-sdk-cli-migration.md 작성 + 본 README 갱신c97f540 commit + push (origin/ctf-exchange)ctf-exchange → main 머지@verex/api의 broken VerexClient import 정리feeRateBps 런칭 정책) 결정MockUSDC + ConditionalTokens + CTFExchange) 기반의 새 surface로 교체. 자세한 내용은 2026-05-27-s2.4-sdk-cli-migration.md 참고.
orders.ts (signOrder + hashOrder, 순수 off-chain EIP-712), conditions.ts (getConditionId), ct.ts (split/merge/redeem/prepareCondition/reportPayouts/balance), exchange.ts (fillOrder/registerToken/addOperator/cancelOrder), usdc.ts (mint/approve), clients.ts (createCTClient/createExchangeClient/createUsdcClient)hashOrder(order, domain)가 forge로 생성한 golden digest 0x68d8d9bd...와 byte-for-byte 일치verex setup/resolve/split/merge/redeem/mint/order sign|fill/balance/condition. 환경변수 (USDC_ADDR/CTF_ADDR/EXCHANGE_ADDR)를 기본, --usdc/--ctf/--exchange 플래그로 override — DemoMarket.s.sol convention과 호환exchange.hashOrder(order) cross-check도 통과docs/plan/watch-list.md 신설 — “외부 이벤트에 따라 결정할 항목”의 single inbox. 두 항목 등록:
fillOrder / splitPosition / mergePositions / redeemPositions) storage 접근 패턴을 BAL-friendly로 재검토. 트리거: Glamsterdam EIP scope 확정 발표Order.signatureType = EOA만 가정. EIP-7702 메인넷 활성 시 additive 진입(EOA path 유지) vs migration(교체) 결정 + Polymarket upstream SignatureType enum 확장과의 정합. S7 product story (one-click / auto-claim / gasless onboarding)와 묶여있어 prerequisite로 봐야 함@verex/api의 broken VerexClient import 발견 — 이번 S2.4와 무관한 stale 코드지만 monorepo 전체 빌드 green 유지를 위해 별도 슬라이스로 픽스 필요 (내일 작업 항목)exchange.hashOrder()와 일치하는지”를 가장 먼저 닫음. forge script(EmitOrderHash.s.sol)로 결정적 Order 하나의 digest를 emit → vitest에 golden value로 박음 → SDK의 hashOrder 결과와 byte-for-byte 비교. 이 한 줄 테스트가 도메인 reconstruction (name/version/chainId/verifyingContract) + Order 타입 인코딩 (12개 필드 순서 + uint8 enum 처리) 모두를 한 번에 검증. 데모 실행 전에 risk를 닫고 들어갔기 때문에 anvil 데모가 한 번에 통과. 또 사용자 결정 항목(v1 cleanup outright vs deprecated, API shape, 테스트 깊이)을 implementation 시작 전에 AskUserQuestion으로 한꺼번에 surface — 중간 rework 없음.@verex/api/@verex/cli 영향을 S2.4 진행 중에 발견 — 사전에 grep으로 확인했어야. 결과적으로 cli 재작성을 S2.4 scope에 inline으로 끌어왔는데, 이건 사용자가 직접 결정한 거라 OK이지만 사전 확인을 했으면 옵션 제시가 더 빨랐을 것. 또 dist/ 폴더의 v1 잔여 파일(예: dist/factory.d.ts)을 한 번 청소 안 하고 넘어갔는데 pnpm sync-abis가 자동 재생성하니 다음 빌드에서 깔끔해질 것 — 손으로 청소는 불필요했음을 사후 확인.ctf-exchange → main 머지
forge test 34/34 회귀 없음 (이미 검증), ③ E2E 데모가 본인 anvil에서도 통과 (이번 세션 시연 외에 본인 reproduce 권장)linked0/verex) 또는 직접 fast-forward — 어느 쪽이든 머지 후 ctf-exchange 브랜치는 history 추적 위해 보존 (삭제 안 함, 2026-05-13 entry의 보존 결정 유지)git pull origin main + S2.5 진입을 같은 브랜치(또는 새 s2.5-mm-agent 브랜치)에서 시작packages/mm-agent. 첫 결정은 fillOrder (inventory model) vs matchOrders (matcher model). Q-S2.3.2 추천: matchOrders — 운영자 capital lock 없음, audit precedent 더 많음. Paper-trading minimum maker로 시작 (실제 fund 안 묶음).@verex/api broken VerexClient import 정리 — quick win. 한 줄짜리 placeholder로 교체하거나 SDK의 createExchangeClient로 마이그레이션 (둘 중 우선순위는 api가 W2~W5 작업의 다음 입력인지 여부에 달림).feeRateBps 런칭 정책) 결정 — S2.5 진입 전 1줄 결정. 0이면 운영자 수익 모델 미정 / nonzero면 SDK에 slippage guard 추가 필요. plan에 명시 없음 — 사용자 판단 필요.docs/plan/watch-list.md 운영 — 트리거 발생 시(Glamsterdam EIP scope 확정 / Pectra mainnet 활성 등) 본 README의 Next Task로 끌어와서 활성화. 발생 전에는 watch-list에서 잠자게 둠.