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
66 changes: 66 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Rain Protocol metadata system — Solidity contracts, Rust CLI/bindings, and a Graph subgraph for emitting and indexing on-chain metadata following the [MetadataV1 spec](https://github.com/rainprotocol/specs/blob/main/metadata-v1.md).

The core contract is **MetaBoard** — deterministically deployed at `0xfb8437AeFBB8031064E274527C5fc08e30Ac6928` across all supported networks. It emits `MetaV1_2` events that the subgraph indexes.

## Build & Test Commands

All commands require the Nix development shell. Use `nix develop` to enter it, or prefix commands with `nix develop -c`.

| Task | Command |
|------|---------|
| Solidity tests | `nix develop -c rainix-sol-test` |
| Solidity static analysis | `nix develop -c rainix-sol-static` |
| Solidity build artifacts | `nix develop -c rainix-sol-artifacts` |
| Rust tests | `nix develop -c rainix-rs-test` |
| Rust static analysis | `nix develop -c rainix-rs-static` |
| Rust build artifacts | `nix develop -c rainix-rs-artifacts` |
| Subgraph build | `nix develop -c subgraph-build` |
| Subgraph tests | `nix develop -c subgraph-test` |
| REUSE license check | `nix develop -c rainix-sol-legal` |

Run a single Solidity test (inside nix shell):

```sh
forge test --match-test testFunctionName
forge test --match-contract MetaBoardTest
```

Run a single Rust test (inside nix shell):

```sh
cargo test test_name
```

## Architecture

### Solidity (`src/`)
- `src/concrete/MetaBoard.sol` — Main contract; emits `MetaV1_2` events with sender, subject, and metadata bytes
- `src/lib/LibMeta.sol` — Metadata validation; checks magic number prefix `0xff0a89c674ee7874`
- `src/lib/LibDescribedByMeta.sol` — Helper for contracts implementing `IDescribedByMetaV1`
- `src/lib/deploy/LibMetaBoardDeploy.sol` — Deterministic deployment using Zoltu deployer pattern

### Rust (`crates/`)
- `crates/cli` — `rain-metadata` binary; metadata generation/validation for multiple types (authoring, dotrain, Solidity ABI, etc.)
- `crates/bindings` — Solidity bindings generated via `alloy::sol!` from JSON ABIs in `/out`
- `crates/metaboard` — GraphQL client (Cynic) for querying MetaBoard subgraph data

### Subgraph (`subgraph/`)
- AssemblyScript handlers indexing `MetaV1_2` events from MetaBoard
- Deployed across ~15 networks (Arbitrum, Base, Polygon, Flare, etc.)

## Key Configuration

- **Solidity**: `foundry.toml` — solc 0.8.25, Cancun EVM, optimizer 1M runs, `bytecode_hash = "none"`, `cbor_metadata = false`
- **Rust workspace**: `Cargo.toml` at root, three crates
- **Fuzz runs**: 5,096 (foundry.toml `[fuzz]`)
- **Remappings**: `rain.deploy/=lib/rain.deploy/src/`

## Licensing

DecentraLicense 1.0 (DCL-1.0). REUSE 3.2 compliant — all files need SPDX license headers.
4 changes: 4 additions & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ version = 1

[[annotations]]
path = [
".cargo/config.toml",
".envrc",
".gas-snapshot",
".github/workflows/**/",
".gitignore",
".gitmodules",
"audit/**/",
"Cargo.lock",
"Cargo.toml",
"CLAUDE.md",
"crates/**/",
"foundry.lock",
"subgraph/**/",
"README.md",
"flake.lock",
Expand Down
42 changes: 21 additions & 21 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion foundry.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"rev": "1801b0541f4fda118a10798fd3486bb7051c5dd6"
},
"lib/rain.deploy": {
"rev": "ccfdb378d2ab1ed95461ecf1355682250e487e4c"
"rev": "43a6ed3a98f0141e1963b4b9136e8c80e2889bd1"
}
}
7 changes: 7 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[profile.default]

solc = "0.8.25"
auto_detect_solc = false

# optimizer settings for snapshotting.
optimizer = true
Expand All @@ -9,11 +10,17 @@ evm_version = "cancun"

bytecode_hash = "none"
cbor_metadata = false
ffi = true

remappings = [
"rain.deploy/=lib/rain.deploy/src/"
]

fs_permissions = [
{ access = "read", path = "subgraph/networks.json" },
{ access = "read", path = "subgraph/subgraph.yaml" }
]

[fuzz]
runs = 5096

Expand Down
2 changes: 1 addition & 1 deletion lib/rain.deploy
1 change: 1 addition & 0 deletions src/interface/deprecated/IMetaV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ interface IMetaV1 {
/// hash of some data/thing that this metadata is about.
/// @param meta Rain metadata V1 compliant metadata bytes.
/// https://github.com/rainprotocol/specs/blob/main/metadata-v1.md
//slither-disable-next-line unindexed-event-address
event MetaV1(address sender, uint256 subject, bytes meta);
}
2 changes: 1 addition & 1 deletion src/interface/unstable/IMetaV1_2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ interface IMetaV1_2 {
/// hash of some data/thing that this metadata is about.
/// @param meta Rain metadata V1 compliant metadata bytes.
/// https://github.com/rainprotocol/specs/blob/main/metadata-v1.md
//slither-disable-next-line naming-convention
//slither-disable-next-line naming-convention,unindexed-event-address
event MetaV1_2(address sender, bytes32 subject, bytes meta);
}
6 changes: 6 additions & 0 deletions src/lib/deploy/LibMetaBoardDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,10 @@ library LibMetaBoardDeploy {
/// than just checking the address.
bytes32 constant METABOARD_DEPLOYED_CODEHASH =
bytes32(0x60e0735a3406074fd8f85adb2813d0d7c346337ea4bcc6f2ef4eb25077a4933c);

uint256 constant METABOARD_START_BLOCK_ARBITRUM = 431042729;
uint256 constant METABOARD_START_BLOCK_BASE = 42021282;
uint256 constant METABOARD_START_BLOCK_BASE_SEPOLIA = 38683088;
uint256 constant METABOARD_START_BLOCK_FLARE = 55347067;
uint256 constant METABOARD_START_BLOCK_POLYGON = 82855948;
}
30 changes: 12 additions & 18 deletions subgraph/networks.json
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
{
"matic": {
"metaboard0": {
"address": "0x23F77e7Bc935503e437166498D7D72f2Ea290E1f",
"startBlock": 55856789
"address": "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928",
"startBlock": 82855948
}
},
"arbitrum-one": {
"metaboard0": {
"address": "0x1eFd85E6C384fAD9B80C6D508E9098Eb91C4eD30",
"startBlock": 256572417
"address": "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928",
"startBlock": 431042729
}
},
"base": {
"metaboard0": {
"address": "0x59401C9302E79Eb8AC6aea659B8B3ae475715e86",
"startBlock": 18309350
"address": "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928",
"startBlock": 42021282
}
},
"mainnet": {
"base-sepolia": {
"metaboard0": {
"address": "0x8F61d274aaB5D8CFD82dc266529EAe33020386a9",
"startBlock": 21041769
"address": "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928",
"startBlock": 38683088
}
},
"berachain-mainnet": {
"flare": {
"metaboard0": {
"address": "0x8F61d274aaB5D8CFD82dc266529EAe33020386a9",
"startBlock": 3092258
}
},
"sonic": {
"metaboard0": {
"address": "0x8F61d274aaB5D8CFD82dc266529EAe33020386a9",
"startBlock": 17707513
"address": "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928",
"startBlock": 55347067
}
}
}
2 changes: 1 addition & 1 deletion subgraph/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dataSources:
name: metaboard0
network: arbitrum-one
source:
address: "0x017F5651eB8fa4048BBc17433149c6c035d391A6"
address: "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928"
abi: MetaBoard
startBlock: 266485075
mapping:
Expand Down
5 changes: 5 additions & 0 deletions subgraph/tests/address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// SPDX-License-Identifier: LicenseRef-DCL-1.0
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
import { Address } from "@graphprotocol/graph-ts";

export const CONTRACT_ADDRESS = Address.fromString("0xfb8437AeFBB8031064E274527C5fc08e30Ac6928");
5 changes: 3 additions & 2 deletions subgraph/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { MetaV1_2 } from "../generated/metaboard0/MetaBoard"; // Update the path as per your file structure
import { MetaV1_2 } from "../generated/metaboard0/MetaBoard";
import { ethereum, Address, BigInt, Bytes } from "@graphprotocol/graph-ts";
import { newMockEvent } from "matchstick-as";
import { handleMetaV1_2 } from "../src/metaBoard";
import { CONTRACT_ADDRESS } from "./address";


export function createNewMetaV1Event(sender: string, subject: Bytes, meta: Bytes, transactionHash: string, transactionBlockNumber: number, transactionTimestamp: number): MetaV1_2 {
Expand Down Expand Up @@ -32,4 +33,4 @@ export function handleNewMetaV1Events(events: MetaV1_2[]): void {
});
}

export const CONTRACT_ADDRESS = Address.fromString("0x23F77e7Bc935503e437166498D7D72f2Ea290E1f");
export { CONTRACT_ADDRESS } from "./address";
Loading
Loading