Skip to content

feat(contract): Add TEE Dispute Game#212

Draft
doutv wants to merge 24 commits intocontract/releasefrom
contract/tee-dispute-game
Draft

feat(contract): Add TEE Dispute Game#212
doutv wants to merge 24 commits intocontract/releasefrom
contract/tee-dispute-game

Conversation

@doutv
Copy link
Copy Markdown

@doutv doutv commented Mar 30, 2026

Summary

Implements TEE Dispute Game contracts on the OP Stack Dispute Game framework.

Core Contracts

  • TeeDisputeGame.solIDisputeGame implementation (gameType=1960). Full lifecycle: propose → challenge → prove → resolve. Uses EIP-712 typed data signing for batch digest, inline PROPOSER/CHALLENGER immutables for access control, and bond management with configurable distribution modes (NORMAL/REFUND).
  • TeeProofVerifier.sol — TEE enclave identity manager. Registers enclaves via RISC Zero ZK proof of AWS Nitro attestation, verifies batch ECDSA signatures from registered enclaves, and supports generation-based O(1) bulk revocation. Core parameters (riscZeroVerifier, imageId, expectedRootKey) are immutable post-deployment.

doutv and others added 24 commits March 19, 2026 12:01
TEE DisputeGame contracts for OP Stack. Replaces SP1 ZK proofs with
AWS Nitro Enclave ECDSA signatures for batch state transition verification.

- src/dispute/tee/TeeDisputeGame.sol: IDisputeGame impl (gameType=1960)
- src/dispute/tee/TeeProofVerifier.sol: enclave registration + batch ECDSA verification
- src/dispute/tee/AccessManager.sol: proposer/challenger permissions with fallback timeout
- src/dispute/DisputeGameFactoryRouter.sol: multi-zone router (zoneId→factory)
- interfaces/dispute/: ITeeProofVerifier, IRiscZeroVerifier, IDisputeGameFactoryRouter
- tests: 69 unit tests covering full lifecycle
- scripts: DeployTee.s.sol, RegisterTeeGame.s.sol

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace registerZone/updateZone/removeZone with a single setZone(zoneId, factory)
that handles all three operations. Pass address(0) to remove a zone. Also remove
redundant getFactory view (factories mapping is already public).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…structor

Constructor now takes an explicit _owner parameter instead of defaulting to
msg.sender, ensuring the deployer never holds owner privileges.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9 integration tests covering the full TradeZone TEE dispute game lifecycle
using real DisputeGameFactory, AnchorStateRegistry, TeeProofVerifier, and
AccessManager (only MockRiscZeroVerifier and MockSystemConfig remain mocked).

Covers: unchallenged DEFENDER_WINS, challenged + proposer/third-party prove,
CHALLENGER_WINS (challenger takes all), guardian blacklist REFUND mode,
parent-child game chains, short-circuit on parent failure, and Router
pass-through. Runnable in CI without ETH_RPC_URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9 integration tests covering the full TradeZone TEE dispute game lifecycle
using real DisputeGameFactory, AnchorStateRegistry, TeeProofVerifier, and
AccessManager (only MockRiscZeroVerifier and MockSystemConfig remain mocked).

Covers: unchallenged DEFENDER_WINS, challenged + proposer/third-party prove,
CHALLENGER_WINS (challenger takes all), guardian blacklist REFUND mode,
parent-child game chains, short-circuit on parent failure, and Router
pass-through. Runnable in CI without ETH_RPC_URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…er and DisputeGameFactoryRouter

Eliminated the BatchGamesCreated event as it was deemed unnecessary for the current implementation. This simplifies the event emissions related to game creation.
…Game

- Add GameType check in initialize() to prevent cross-chain parent references
  in a shared DisputeGameFactory (XL vs TZ isolation)
- Fix C-02: resolve() parent-loses path now credits proposer instead of
  address(0) when child game was never challenged
- Fix H-03: add IN_PROGRESS status guard to prove() to prevent post-resolution
  state mutation
- Document C-03: add NatSpec to prove() explaining TEE trust model and why
  early proving before challenges is by design
- Add cross-chain isolation integration tests
- Add C-02 regression test
- Add audit findings report and TEE dispute game spec to book/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update bond distribution table: parent-loses path now has two rows
  (child challenged vs child unchallenged)
- Document prove() IN_PROGRESS guard and early prove design
- Update parent chain invalidation cascade description
- Clarify resolve() parent dependency bond handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ables

Simplify TeeDisputeGame access control to match PermissionedDisputeGame's
pattern. Remove the external AccessManager contract (Ownable, whitelist
mappings, O(n) fallback iteration) in favor of two immutable addresses
set in the constructor with inline checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…Z Ownable

M-01: Add `msg.sender != proposer` check to prove(), preventing frontrunning
of prover credit. Simplify resolve() bond distribution since prover == proposer
is now guaranteed.

M-02: Replace TeeProofVerifier's custom ownership (state var, modifier, event,
transferOwnership) with OpenZeppelin Ownable v4, which provides zero-address
validation on transferOwnership out of the box.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ed batchDigest

- closeGame() now reverts with GamePaused() when ASR is paused, preventing
  games from permanently entering REFUND mode during temporary pauses
- Replace legacy anchors(GAME_TYPE) with getAnchorRoot() in initialize()
- Migrate batchDigest from plain keccak256 to EIP-712 typed data hash with
  domain separator (chainId + TEE_PROOF_VERIFIER address) to prevent
  cross-chain and cross-contract signature replay
- Expose domainSeparator() and batchProofTypehash() getters for off-chain
  TEE signers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… setters for TeeProofVerifier

Borrow patterns from DKIMOracle to improve TeeProofVerifier:
- Replace per-address EnclaveInfo mapping with generation counter for O(1) bulk revocation via revokeAll()
- Replace _parseJournal with AttestationData struct + abi.encodePacked journal reconstruction (rootKey baked into digest, eliminating explicit comparison)
- Make riscZeroVerifier, imageId, expectedRootKey mutable with owner-gated setters to avoid redeployment
- Add constructor parameter validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eProofVerifier

Owner-gated contract — invalid params cause ZK verify failure naturally,
explicit checks add no security value. Also remove 96-byte rootKey length
constraint to support different key formats.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace // ============ banners with //////////////////////////////////////////////////////////////// style
- Apply forge fmt (bracket spacing, multiline func headers, line wrapping)
- Group imports with // Libraries and // Interfaces comments
- Remove constructor/setter parameter validations (owner-gated, no security value)
- Remove rootKey 96-byte length constraint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add forge scripts and documentation for TEE ZK Prover local testing:

- DeployTeeMock.s.sol: deploys full TEE stack with MockRiscZeroVerifier
- TeeProveE2E.s.sol: E2E flow (register, create, challenge, prove, resolve)
  with two modes: mock (ENCLAVE_KEY signs locally) and external
  (BATCH_SIGNATURE passed in from TEE prover, no private key exposure)
- tee-local-integration-guide.md: Chinese integration guide covering
  architecture, EIP-712 signing spec, cast commands, and troubleshooting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ameFactory

Decision to share the existing DisputeGameFactory directly, making the
router layer unnecessary. Removes the contract, interface, all tests,
deploy script references, and doc mentions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split E2E scripts into mock and fork variants:
- DeployTeeMock/TeeProveE2E: pure mock mode (simplified)
- DeployTeeFork/TeeProveE2EFork: fork mainnet with real
  RiscZeroVerifierRouter (0x8EaB...D319), real seal registration,
  and external BATCH_SIGNATURE from TEE prover

Update integration guide with fork mode section including:
- fork mainnet setup, deploy, and E2E commands
- journal field parsing (Boundless seal -> env vars)
- chainId difference (mock=31337, fork=1)
- troubleshooting for real ZK proof failures

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revise the TEE Dispute Game specification document to include Chinese translations for key sections, enhancing accessibility for Chinese-speaking developers. The updates cover the overview, purpose, architecture, and contract relationship diagrams, ensuring clarity in both English and Chinese.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update TeeProofVerifier contract to set riscZeroVerifier, imageId, and expectedRootKey as immutable after deployment, enhancing security by preventing runtime changes. Remove associated setter functions and update tests to reflect immutability. Revise TEE Dispute Game specification to clarify the implications of these changes on system trust and owner permissions.
Add 11 deterministic unit tests and 5 Foundry invariant tests based on
audit report recommendations. Covers INV-1 (balance >= credits), INV-4
(status monotonicity), INV-5 (GameStatus irreversible), INV-6 (claimData
immutable after resolve), INV-12 (single NORMAL credit recipient), and
INV-13 (bondDistributionMode irreversible). Also adds double-prove,
double-resolve, prove-then-challenge, and deadline boundary revert tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…layouts and game mechanics

Update the TEE Dispute Game specification to include a new section on Clone With Immutable Args (CWIA) detailing the layout of immutable parameters. Expand on the challenge and prove functions with comprehensive preconditions and postconditions. Introduce the resolve function and clarify the parent game validation process during initialization. Additionally, outline the responsibilities of the Guardian regarding blacklisting child games. These changes aim to improve clarity and understanding of the game mechanics and access control.
Delete obsolete audit findings and reports for TeeDisputeGame, including the initial audit report, final audit report, and post-refactor audit report. This cleanup ensures the repository reflects the most current state of the project and removes unnecessary clutter from the documentation. Future audits will be documented separately as needed.
…eData() from view to pure

GAME_TYPE is always GameType.wrap(1960), a compile-time constant — no need for
runtime immutable assignment. This aligns with ZKDisputeGame's pure pattern and
gives the compiler stricter guarantees.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant