Repository navigation
feat: on-chain MPT receipt proof verification - #67
Merged
Merged
Conversation
12 tasks
Contributor
Author
Phase A 최종 완료 — E2E 검증 성공추가 커밋 (295b043, cdb2364)RPC 안정성 (295b043):
Sharpe ratio 표시 + maxTrades 제한 (cdb2364):
E2E 테스트 결과
|
raymond1203
reviewed
Feb 21, 2026
raymond1203
left a comment
Contributor
There was a problem hiding this comment.
Code Review
전체적으로 Phase A 아키텍처는 깔끔하고 @noble/hashes 도입, compute_constant_merkle_root() 최적화 등 좋은 선택들이 많습니다. 아래 보완 포인트 정리합니다.
CRITICAL
1. Receipt hash 진위 검증 없음 (Phase A 보안 모델)
- 클라이언트가 제출한 receipt hash가 실제 Ethereum receipt인지 on-chain에서 검증하지 않습니다
- 악의적 클라이언트가 가짜 hash를 넣어도 STARK 검증이 통과될 수 있습니다
- Phase B에서 해결 예정이지만, Phase A의 보안 한계를 코드/문서에 명시적으로 기록해야 합니다
MAJOR
2. verify_sharpe_with_commitment e2e 테스트 없음
- 프론트엔드의 주요 검증 경로인데 테스트가 0개입니다
- 최소 1개의 통합 테스트 필요: receipt hashes → aggregate commitment → constant_merkle_root → pi[3] 바인딩 → STARK verify
3. 버전 네이밍 혼란
- 변수명:
STARK_VERIFIER_V4_ADDRESS - PR body: "v5" (
0x5f83...) - CLAUDE.md: "v6"
- 3개 버전 번호가 혼재합니다. 변수명과 주석 통일 필요
4. RLP/MPT TypeScript 코드 테스트 없음
lib/rlp.ts(220줄) +lib/receipt-trie.ts(601줄) = 820줄 신규 코드- Ethereum 표준 알고리즘 구현인데 테스트가 없어 encoding 버그 시 silent failure 위험
- 최소
rlpEncodeReceipt,buildReceiptTrieAndProve기본 테스트 필요
MINOR
5. 클라이언트 Sharpe ratio 표시값이 STARK 검증값과 다를 수 있음
WalletProver.tsx에서 자체 계산한 population Sharpe ratio를 표시하는데, STARK public inputs의sharpe_sq_scaled와 다를 수 있습니다
6. 클라이언트 MPT 검증 실패 시 warn만 하고 TX 진행
receipt-proof.ts에서 client-side MPT 검증 실패 시console.warn만 출력하고 계속 진행- on-chain에서도 실패할 가능성 높아 gas 낭비 TX 발생 가능. hard error 또는 사용자 경고 권장
7. hexToBytes 중복
lib/rlp.ts와lib/receipt-proof.ts에 동일한 함수 존재. 공통 유틸로 통합 권장
8. maxTrades 5000→100 변경
- 동작 변경인데 인라인 주석만 있고 PR description에 언급 없음
9. 프로덕션 console.log 다수
- calldata estimation, Phase A info 등 디버그 로그가 남아있습니다
긍정적 평가
compute_constant_merkle_root()— O(log n) 최적화 정확- on-chain / off-chain aggregate commitment 알고리즘 일치 확인
@noble/hashes도입 — 기존 커스텀 keccak 대비 훌륭한 선택- ~97KB → N×32B 경량화 아키텍처 깔끔
raymond1203
added a commit
that referenced
this pull request
Feb 21, 2026
- Add 3 Rust integration tests for commitment binding logic (88 total) - Add 24 TypeScript tests: 16 RLP + 8 receipt-trie (vitest) - Add Phase A security documentation to verify_sharpe_with_commitment - Rename STARK_VERIFIER_V4_ADDRESS → STARK_VERIFIER_ADDRESS - Change "Sharpe Ratio" label to "Sharpe Ratio (est.)" - Upgrade client-side MPT verification from warn to throw - Remove console.log debug statements
raymond1203
self-requested a review
February 21, 2026 16:46
- Add verify_sharpe_proof_with_receipt() to Stylus verifier MPT proof → extract receipt RLP → compute commitment → STARK cross-check - Implement on-chain MPT verification (mpt.rs): verify_mpt_proof(), compute_dataset_commitment_onchain(), decode_proof_nodes(), compute_constant_merkle_root() - Add RLP encoding/decoding library (lib/rlp.ts) per Ethereum Yellow Paper - Add Merkle Patricia Trie builder + proof generator (lib/receipt-trie.ts) - Fix receipt-proof.ts: replace buggy custom keccak256 with @noble/hashes Receipt trie root now matches on-chain receiptsRoot exactly - Fix RLP status encoding: status 0 → empty bytes (not [0x00]) - Add debug_getRawReceipts RPC support with re-encoding fallback - Update WalletProver.tsx: dual verification (MPT+STARK / STARK-only fallback) Handle WalletConnect error objects, detect oversized payload errors - Deploy verifier v5 at 0x5f83f682b9b77614e2b90d75092abc97b49ae378
Replace 97KB receipt RLP + MPT proof on-chain submission with compact receipt hash aggregate. All trade receipts are now bound via keccak hash chain (N x 32B) instead of a single receipt. On-chain: verifySharpeWithCommitment recomputes aggregate commitment from receipt hashes, verifies STARK proof, cross-checks pi[3]. Client: fetchReceiptHashes computes keccak256(receiptRlp) per trade. - Add compute_commitment_from_hashes() to mpt.rs (hash chain) - Add verify_sharpe_with_commitment() entry point to lib.rs - Add fetchReceiptHashes/computeAggregateCommitment to receipt-proof.ts - Add verifySharpeWithCommitment ABI to contracts.ts - Simplify WalletProver.tsx: remove fallback logic, single code path - Deploy v6 contract: 0x365344c7057eee248c986e4170e143f0449d943e Resolves #68, #72
Public Arbitrum RPC can hang indefinitely on eth_getTransactionReceipt. Add 15s AbortController timeout to all RPC calls, per-batch progress logging, reduced batch size (10→5), and inter-batch delay to prevent rate limiting. Also add RPC error checking to rpcCall.
- Compute Sharpe ratio from raw returnsBps (mean/stddev) instead of BN254 field element which produces meaningless large numbers - Display Sharpe in result card with color coding (green>=1, orange>=0, red<0) - Limit maxTrades to 100 to keep calldata under MetaMask limit (100 hashes × 32B = 3.2KB vs 4206 × 32B = 134KB that was rejected) - 100 trades is statistically sufficient for Sharpe ratio computation
- Add 3 Rust integration tests for commitment binding logic (88 total) - Add 24 TypeScript tests: 16 RLP + 8 receipt-trie (vitest) - Add Phase A security documentation to verify_sharpe_with_commitment - Rename STARK_VERIFIER_V4_ADDRESS → STARK_VERIFIER_ADDRESS - Change "Sharpe Ratio" label to "Sharpe Ratio (est.)" - Upgrade client-side MPT verification from warn to throw - Remove console.log debug statements
raymond1203
force-pushed
the
feat/receipt-mpt-verification
branch
from
February 21, 2026 16:51
82ba6c8 to
d6d8715
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
verify_sharpe_proof_with_receipt()추가: MPT proof → receipt RLP 추출 → dataset commitment 재계산 → STARK cross-checkmpt.rs):verify_mpt_proof(),compute_dataset_commitment_onchain(),decode_proof_nodes(),compute_constant_merkle_root()lib/rlp.ts) — Ethereum Yellow Paper 준수lib/receipt-trie.ts)@noble/hashes로 교체. Receipt trie root가 on-chain receiptsRoot와 정확히 일치[0x00]잘못됨)debug_getRawReceiptsRPC 지원 (unavailable 시 re-encoding fallback)0x5f83f682b9b77614e2b90d75092abc97b49ae378Architecture
Known Limitation
GMX V2 receipt이 ~97KB (다수 이벤트 로그)로 MetaMask payload 한계 초과. 현재 STARK-only fallback으로 처리. Phase A (다음 PR) 에서
receiptHash(32B)만 전송하는 구조로 전환 예정.Test plan
cargo test --features export-abi— Stylus verifier 79 tests 통과cargo stylus check— WASM 유효성@noble/hashesoutput == expected hash