Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[submodule "simple-ai-agent"]
path = simple-ai-agent
url = https://github.com/Defiesta/simple-ai-agent
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "contracts/lib/risc0-ethereum"]
path = contracts/lib/risc0-ethereum
url = https://github.com/risc0/risc0-ethereum
40 changes: 40 additions & 0 deletions contracts/.github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

env:
FOUNDRY_PROFILE: ci

jobs:
check:
name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Show Forge version
run: |
forge --version

- name: Run Forge fmt
run: |
forge fmt --check
id: fmt

- name: Run Forge build
run: |
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
11 changes: 11 additions & 0 deletions contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Compiler files
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Dotenv file
.env
34 changes: 34 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Execution Kernel Contracts

On-chain contracts for RISC Zero zkVM kernel execution.

| Contract | Description |
|----------|-------------|
| `KernelExecutionVerifier` | Verifies zkVM proofs and parses `KernelJournalV1` |
| `KernelOutputParser` | Library for parsing `AgentOutput` into executable actions |
| `KernelVault` | MVP vault that executes verified agent actions |

## Installation

```bash
cd contracts
forge install
forge build
```

## Testing

```bash
forge test
forge test -vvv # verbose
forge coverage # coverage report
```

## Documentation

- [Binary Format Specification](./docs/binary-format.md) - Wire formats for journal and actions

## Dependencies

- [risc0-ethereum](https://github.com/risc0/risc0-ethereum) - RISC Zero verifier contracts
- [forge-std](https://github.com/foundry-rs/forge-std) - Foundry testing library
72 changes: 72 additions & 0 deletions contracts/docs/binary-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Binary Format Specification

This document describes the binary formats shared between the Rust zkVM kernel and the Solidity contracts. All formats are byte-for-byte aligned with the Rust implementation in `kernel-core`.

## KernelJournalV1 (209 bytes)

The journal is the output committed by the zkVM kernel after execution.

| Offset | Field | Type | Size | Endianness |
|--------|-------|------|------|------------|
| 0-3 | protocol_version | u32 | 4 | Little-endian |
| 4-7 | kernel_version | u32 | 4 | Little-endian |
| 8-39 | agent_id | bytes32 | 32 | Raw bytes |
| 40-71 | agent_code_hash | bytes32 | 32 | Raw bytes |
| 72-103 | constraint_set_hash | bytes32 | 32 | Raw bytes |
| 104-135 | input_root | bytes32 | 32 | Raw bytes |
| 136-143 | execution_nonce | u64 | 8 | Little-endian |
| 144-175 | input_commitment | bytes32 | 32 | Raw bytes |
| 176-207 | action_commitment | bytes32 | 32 | Raw bytes |
| 208 | execution_status | u8 | 1 | Single byte (0x01=Success, 0x02=Failure) |

## AgentOutput

The `AgentOutput` contains the actions produced by the agent. The `action_commitment` in the journal is `sha256(AgentOutput bytes)`.

### Overall Structure

```
[action_count: u32 LE] # Number of actions (max 64)
[action 0]
[action 1]
...
[action N-1]
```

### Per-Action Structure

```
[action_len: u32 LE] # Length of ActionV1 bytes (NOT included in size limit)
[ActionV1 bytes]: # Bounded by MAX_SINGLE_ACTION_BYTES (16424)
[action_type: u32 LE] # 4 bytes
[target: bytes32] # 32 bytes
[payload_len: u32 LE] # 4 bytes
[payload: bytes] # Up to MAX_ACTION_PAYLOAD_BYTES (16384)
```

### Size Constants

| Constant | Value | Description |
|----------|-------|-------------|
| `MAX_ACTIONS_PER_OUTPUT` | 64 | Maximum actions per AgentOutput |
| `MAX_ACTION_PAYLOAD_BYTES` | 16,384 | Maximum payload size per action |
| `MAX_SINGLE_ACTION_BYTES` | 16,424 | Maximum ActionV1 encoded size (40 + payload) |

**Important**: `MAX_SINGLE_ACTION_BYTES` bounds the `action_len` value (the ActionV1 encoding), NOT the full wire encoding which includes an additional 4-byte length prefix. This matches the Rust implementation in `kernel-core/src/types.rs`.

### Action Types

| Type | Value | Payload Format | Description |
|------|-------|----------------|-------------|
| `ACTION_TYPE_CALL` | `0x00000002` | `abi.encode(uint256 value, bytes callData)` | Generic contract call |
| `ACTION_TYPE_TRANSFER_ERC20` | `0x00000003` | `abi.encode(address token, address to, uint256 amount)` | ERC20 token transfer |

## Cross-Implementation Alignment

The Solidity contracts (`KernelOutputParser.sol`, `KernelExecutionVerifier.sol`) are intentionally byte-for-byte aligned with the Rust implementation. Key alignment points:

1. **Integer encoding**: All integers use little-endian byte order
2. **Size validation**: Both implementations validate `action_len` against `MAX_SINGLE_ACTION_BYTES`, excluding the 4-byte length prefix
3. **Constants**: All size constants match between Rust (`kernel-core/src/types.rs`) and Solidity (`KernelOutputParser.sol`)

This ensures that any valid output from the zkVM kernel will be correctly parsed by the Solidity contracts, and any invalid output will be rejected by both.
15 changes: 15 additions & 0 deletions contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.24"
optimizer = true
optimizer_runs = 200
via_ir = false

[fmt]
line_length = 100
tab_width = 4
bracket_spacing = true

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
1 change: 1 addition & 0 deletions contracts/lib/forge-std
Submodule forge-std added at 1801b0
1 change: 1 addition & 0 deletions contracts/lib/risc0-ethereum
Submodule risc0-ethereum added at 365e7b
3 changes: 3 additions & 0 deletions contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
forge-std/=lib/forge-std/src/
risc0-ethereum/=lib/risc0-ethereum/contracts/src/
@openzeppelin/=lib/risc0-ethereum/lib/openzeppelin-contracts/
Loading