Conversation
…ted requests (#49) Co-authored-by: Christian Drappi <c@seismic.systems>
… test init (#140) Co-authored-by: Christian Drappi <c@seismic.systems> Co-authored-by: Ameya Deshmukh <ad@seismic.systems>
delete outdated developers.md file, add new contributors.md file (modified from https://github.com/SeismicSystems/documentation/blob/main/foundry/documentation.md), and point README to it.
use .into() function to convert MERCURY to SpecId. This allows removing MERCURY from the specid, like we did in SeismicSystems/seismic-revm#184 This will work for both current setup (where MERCURY is part of SpecID), and after we repoint revm to use the changes in seismic-revm. Opting to not point to the temporary reth-sdk as part of this PR, but might do it in a followup to test future changes.
## Summary - Add comprehensive `CLAUDE.md` with build instructions (macOS/Linux), test commands, project layout, Seismic-specific modifications, code style, and CI documentation - Include troubleshooting table for known issues (zsh filter escaping, upstream test divergences, network-dependent tests, ssolc installation) - Remove `CLAUDE.md` from `.gitignore` so it can be tracked ## Test plan - [x] All three binaries (`sforge`, `sanvil`, `scast`) build and run with documented commands - [x] All Seismic CI tests pass (`test_seismic_tx_encoding`, `test_seismic_*`, `private_storage_*`) - [x] Doc tests pass when excluding `cast` crate (which requires network) - [x] Every command in the CLAUDE.md verified on macOS arm64 cc @cdrappi --------- Co-authored-by: Christian Drappi <christiandrappi@gmail.com>
Uses SeismicSystems/seismic-compilers#14 When compiling with -vvv we can now see the commit version: ``` $ sforge build -vvv [⠊] Compiling... [⠑] Compiling 44 files with ssolc 0.8.31 (676bdec) [⠘] ssolc 0.8.31 (676bdec) finished in 615.21ms ``` Before we'd see `Compiler ... with Solc 0.8.31` only.
This updates the compiler print to be able to tell whcih exact ssolc commit is used. This brings in SeismicSystems/seismic-compilers@5a398ff Also added some comments to explain how the `seismic` config field works as I got confused about what the code was doing.
Update upstream's release.yml script to work for seismic binaries (basically just added `s` in front of everything. Turned off the docker releases because don't see a use case for them at this point. This will make nightly releases, which are pruned monthly afaiu.
Afaiu its a superset, and this clippy command will compile + check all binaries (not only the 2 hardcoded) with all features (ran into some issues in the release ci recently because we weren't ever testing with the js-tracer feature flag).
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - uses: dtolnay/rust-toolchain@clippy | ||
| - uses: Swatinem/rust-cache@v2 | ||
| with: | ||
| cache-on-failure: true | ||
| - run: cargo clippy --workspace --all-targets --all-features | ||
| # Not enforcing warnings here because there are too many to fix atm, but we may want to turn this back on. | ||
| # env: | ||
| # RUSTFLAGS: -Dwarnings | ||
|
|
||
| test: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 23 days ago
In general, this class of issue is fixed by explicitly declaring a permissions: block at the workflow root (or per job) that grants only the scopes required. For a pure CI workflow that only checks out code, downloads artifacts, and runs tests, contents: read (and optionally packages: read if needed) is typically sufficient.
For this specific file, .github/workflows/seismic.yml, no job performs writes to the repository, issues, or pull requests. The only GitHub API usage is actions/checkout (which needs contents: read) and curl calls to a public GitHub API endpoint for another repository. Therefore, the single best fix is to add a workflow-level permissions: block directly under the name: Seismic CI line, setting contents: read. This will apply to all jobs (including clippy at line 43 where CodeQL flagged the issue) without changing existing functionality.
No additional imports, methods, or definitions are needed; this is a declarative change to the workflow YAML only.
| @@ -1,4 +1,6 @@ | ||
| name: Seismic CI | ||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| push: |
Ran the workflow manually and it succeeded: https://github.com/SeismicSystems/seismic-foundry/actions/runs/22312870726 Set it to: - make a release once a week (or whenever manually triggered) - build for 3 platforms (ubuntu-x86, mac-x86, mac-arm). Disabled all the others because had issues with github's self hosted runners, plus I don't think there's demand at this point in time
Adding option to pass --unsafe-via-ir option down to ssolc. This updates the seismic-compiler to get the similar changes from SeismicSystems/seismic-compilers#18 Needed because versions of ssolc (SeismicSystems/seismic-solidity#204) require --unsafe-via-ir argument, which foundry's config didn't support before this. Now one can change foundry.toml to have ``` via_ir = true unsafe_via_ir = true ``` and both of these will be passed down to ssolc. chore: Also fixed .gitignore since it was ignoring crates/cli/src/opts/build by mistake.
## Summary - A critical and embarassing bug: `block.timestamp` was returning (correctValue) / 1000 ## AI comments - Enable "timestamp-in-seconds" for seismic EVM so TIMESTAMP reports seconds - Align vm.warp/getBlockTimestamp to seconds
Current behavior is for `scast call` to default to a seismictx, which
requires passing a private key. That makes our scast not evm compatible,
as it can't be used to read public slots without passing a private key.
also changed the flag name on call from `--encryption-private-key` to
`--seismic`. Sending a seismictx for eth-call now behaves exactly like
`scast send` does (they both have the same exact flag).
--help output looks like:
```
--seismic [<ENCRYPTION_PRIVATE_KEY>]
Encrypt calldata via ECDH and route through `seismic_call`.
--seismic <SK>: use this hex-encoded private key for encryption
--seismic: generate a random ephemeral key
(omit flag): perform a standard `eth_call`
```
and is now placed under the call/send options, instead of being
flattened under the wallet options where it was previously.
## Summary This PR increases sanvil CI test coverage from ~8 Seismic-specific tests to ~380 tests by fixing broken tests, regenerating stale fixtures, bumping dependencies, and adding new Seismic fork tests. All test exclusions are moved from CI filter expressions to `#[ignore = "reason"]` annotations on the tests themselves. ## What changed **10 previously-skipped tests fixed and re-enabled:** - `anvil_api::can_get_node_info` — expected `SpecId::PRAGUE`, changed to `SpecId::MERCURY` - `api::can_call_with_undersized_max_fee_per_gas` — was reading `last_sender` from the tx request object; now decodes from `seismic_call()` return bytes - `revert::test_solc_revert_example` — removed unused `sender` variable and `with_from(sender)` incompatible with Seismic tx flow - `api::can_call_on_pending_block` — Mercury EVM TIMESTAMP opcode returns milliseconds; divide header timestamp by 1000 before comparison - `transaction::get_blocktimestamp_works` — same timestamp fix, plus multiply mock timestamp by 1000 for `evm_set_next_block_timestamp` - `proof::test_account_proof` — regenerated hardcoded Merkle proof bytes to account for the 3 system contracts (AES_LIB, DIRECTORY, INTELLIGENCE) injected at genesis - `otterscan::test_call_ots_trace_transaction` — updated expected trace values to match Seismic trace shielding (empty `input` on top-level CALL, empty `output` on STATICCALL) - `state::can_load_existing_state_legacy_stress` — regenerated fixture from current sanvil; the old file had inconsistent storage format (2 `FlaggedStorage` entries, 1 plain hex string) from a partial conversion during the Alloy 1 merge - `state::can_load_existing_state` — bumped `seismic-revm-inspectors` to `e2a96b7d` which adds `#[serde(default)]` to `CallTrace.tx_type`, allowing old state dumps without the field to deserialize - `state::test_backward_compatibility_state_dump_deserialization_v1_2` — same dep bump **3 new Seismic fork tests added:** - `test_seismic_fork_chain_id` — forks Seismic testnet, verifies chain_id = 5124, verifies `--chain-id` override - `test_seismic_fork_block_number` — forks at block 1000, verifies block number and block data - `test_seismic_fork_send_tx` — sends an ETH transfer on forked Seismic state, verifies receipt and balance These are the Seismic equivalents of the upstream mainnet fork tests that require Ethereum mainnet RPCs. **CI workflow simplified:** The sanvil integration test step is now `cargo nextest run -p anvil --test it` with no filter expressions. All skipped tests use `#[ignore = "reason"]` directly on the test function. Reasons fall into four categories: - `"requires mainnet fork RPC"` — 64 tests across fork.rs, anvil_api.rs, state.rs, simulate.rs, traces.rs, genesis.rs - `"Mercury is post-Cancun; ..."` / `"Mercury has EIP-1559; ..."` / `"Mercury accepts EIP-1559 by design"` / `"Mercury doesn't include Osaka gas limit caps"` — 4 tests with hardfork incompatibilities - `"EIP-4844 blob support not wired through Seismic type forks"` — 4 tests blocked on blob support across seismic-alloy/seismic-evm/seismic-revm - `"CheatEcrecover not wired into SeismicPrecompiles; needs SharedBuffer handling in inspector"` — 1 test for `anvil_impersonate_signature`; the inspector `call()` hook fires correctly but needs EVM context to resolve SharedBuffer input **Dependency bump:** `seismic-revm-inspectors` bumped from `9e26c0a` to `e2a96b7d` — adds `#[serde(default)]` to `CallTrace.tx_type` so old state dumps without the field deserialize correctly. `CallTrace.tx_type` defaults to `0` (legacy), which is safe because nothing reads it from deserialized state — the trace shielding code that would use it is still a TODO.
## Summary - The RNG precompile uses `tx_hash` as a seed for deterministic randomness, but `SeismicTransaction::new()` defaults `tx_hash` to `B256::ZERO` and nothing was overriding it with the actual hash - Every transaction produced identical RNG output (same seed → same result), breaking contracts relying on per-transaction randomness (e.g. poker card shuffling always dealt the same cards) - Propagates the real `tx_hash` from `PendingTransaction::hash()` in all three execution paths: `TransactionExecutor::env_for`, `inspect_tx`, and `trace_tx_with_js_tracer` ## Test plan - [ ] `cargo nextest run test_seismic_` — existing Seismic tests still pass - [ ] `cargo nextest run test_seismic_tx_encoding` — tx encoding unaffected - [ ] `bun viem:test` — viem integration tests still pass - [ ] Manual: run poker game and verify different cards dealt each round --------- Co-authored-by: drappi-ai <christiandrappi+ai@gmail.com>
Adds a GitHub Actions workflow that runs Claude to review PRs and posts the review as a sticky comment.
|
Implements comprehensive seismic_prelude import aliasing strategy across the entire codebase, adds Claude PR review workflow, and updates maintainer information. Phase 1
Phase 2
LGTM overall - this correctly implements the documented seismic_prelude import aliasing strategy to minimize upstream merge conflicts. The panic is the only blocking issue. |
… as TxSeismic (#176) ## Summary - When `sforge script --broadcast` broadcasts transactions, auto-detect whether each transaction targets a function with shielded type parameters (`suint*`, `sint*`, `saddress`, `sbool`) by inspecting the compiled ABI from `ssolc` - If any parameter is a shielded type, encrypt the calldata and send as **TxSeismic (type 0x4a)** instead of EIP-1559 (type 0x2) - Previously, all broadcast transactions were sent as EIP-1559, leaking shielded values as plaintext calldata on-chain ## Changes **`crates/script-sequence/src/transaction.rs`** - Added `has_shielded_args: bool` to `TransactionWithMetadata` (`#[serde(default)]` for backward compat) **`crates/script/src/transaction.rs`** - In `ScriptTransactionBuilder::set_call()`, check if matched function has shielded params via ABI `Param.ty` - Added `function_has_shielded_params()` / `param_is_shielded()` helpers **`crates/script/src/broadcast.rs`** - Added `encrypt_transaction_for_seismic()` — generates ephemeral ECDH keypair, builds `TxSeismicElements`/`TxSeismicMetadata`, encrypts calldata, sets type 0x4a, converts gas to legacy format - In `broadcast()`: fetch TEE pubkey once per sequence via `seismic_getTeePublicKey` RPC if any tx needs encryption - Per-tx: shielded calls → legacy gas + encrypt + type 0x4a; normal calls → EIP-1559 (unchanged); deploys → unchanged ## Design decisions - **Detection**: Uses `Param.ty` from the `JsonAbi` produced by `ssolc` — no new flags or ABI schema changes needed - **Encryption flow**: Mirrors `scast send --seismic` exactly (ephemeral key, `client_encrypt` with AEAD metadata, type 0x4a, legacy gas) - **Mixed batches**: Each tx typed independently — a single broadcast can contain both shielded (0x4a) and non-shielded (0x2) transactions - **CREATE txs**: Never encrypted (protocol constraint — TxSeismic can't be used for contract creation) - **Unique nonces**: Each encrypted tx gets a fresh random 12-byte encryption nonce ## Test plan - [ ] Deploy a contract with functions that take `suint256` params and functions that don't - [ ] Write a script that calls both types of functions - [ ] Run `sforge script --broadcast` - [ ] Verify: calls to shielded-param functions → type 0x4a with encrypted input - [ ] Verify: calls to non-shielded functions → type 0x2 with plaintext input - [ ] Verify: contract deployments → type 0x2 - [ ] Verify: all transactions execute successfully - [ ] Existing CI tests pass (`test_seismic_`, `private_storage_`)
…rs (#179) ## Summary - Add 11 `SolidityErrorCode` variants (5500–5510) for ssolc shielded literal warnings so they are recognized by name instead of falling through to `Other(u64)`. Covers all 4 match arms: `as_str()`, `From<u64>`, `FromStr`, `Into<u64>`. - Bump `seismic-compilers` to `e6e099e` ([PR #19](SeismicSystems/seismic-compilers#19)) which adds named constants for these warning IDs and context-aware suppression in test/script files. - Add unit tests for round-trip conversion of all 11 variants. - Add 3 CLI integration tests (require `ssolc`) verifying end-to-end behavior: - `src/` files: all warnings (5500, 5501, 5506) emitted; suppressible via `ignored_error_codes` - `test/` files: ext-call warnings (5506) auto-suppressed by seismic-compilers; constructor (5500) and new-expr (5501) still emitted - `script/` files: same suppression as test/ ## Test plan - [x] `cargo test -p foundry-config -- error::tests` — unit tests for variant round-trips - [x] `cargo test -p forge --test cli shielded_literal_warnings` — CLI integration tests (requires `ssolc`) - [x] `cargo check -p foundry-config` — clean compilation
## Summary
- Update all `SolidityErrorCode` shielded variants from old 4-digit
codes (5500-5510) to new 5-digit codes (10103, 10401-10416) matching
ssolc commit `bcce7ba86`
- Add new "other context" variants
(`ShieldedLiteralOther{Int,Bool,Address,Fixedbytes,Enum}`) and
`ShieldedNumberLiteral` that ssolc now emits
- Update ssolc detection in integration tests to use PATH lookup instead
of hardcoded `/usr/local/bin/ssolc`
- Preserves all of Ameya's enum variants, test structure, and string
aliases — only numeric codes change
## Test plan
- [ ] `cargo nextest run -p foundry-config` — error.rs unit tests
(roundtrip, as_str, from_str)
- [ ] `cargo nextest run shielded_literal_warnings` — integration tests
with ssolc (requires ssolc in PATH)
## Summary
- Replace hardcoded `/usr/local/bin/ssolc` (Linux) / `C:\Program
Files\Seismic\bin\ssolc.exe` (Windows) with PATH lookup via
`Command::new("ssolc")`
- When `seismic = true` and no `solc` is configured in foundry.toml,
automatically find `ssolc` from PATH (previously fell through to
upstream solc auto-detect)
- Update test skip guards to check PATH instead of hardcoded path
## Test plan
- [ ] CI passes (existing ssolc tests use PATH lookup now)
- [ ] `sforge build` works when `ssolc` is in PATH but not at
`/usr/local/bin/ssolc`
- [ ] Error message is clear when `ssolc` is not installed
… mode (#187) ## Summary - When `seismic = true` and `via_ir = true`, require explicit `unsafe_via_ir = true` opt-in - Emits a clear error message explaining the via-ir pipeline is unstable/experimental in ssolc - Users can set `unsafe_via_ir = true` in `foundry.toml` or pass `--unsafe-via-ir` on the CLI ## Test plan - [x] `test_seismic_via_ir_with_unsafe_via_ir_ok` — seismic + via_ir + unsafe_via_ir proceeds normally - [x] `test_non_seismic_via_ir_without_unsafe_via_ir_ok` — non-seismic configs unaffected - [x] `cargo build --bin sforge` compiles cleanly
…nd CLI (#188) ## Summary - Bumps seismic-compilers dependency to `cdai__seismic-warning-configs` branch, which adds `SeismicConfig { no_seismic_warnings, seismic_warnings_in_tests }` and `CliSettings.seismic_cfg` - Adds `no_seismic_warnings` and `seismic_warnings_in_tests` fields to `Config` in `crates/config/src/lib.rs`, with serde support and `false` defaults - Adds `--no-seismic-warnings` and `--seismic-warnings-in-tests` CLI flags to `BuildOpts`, available on all sforge commands (build, test, script, etc.) - Threads config values into both `CliSettings.seismic_cfg` (for solc settings) and `Project::builder().set_seismic_config()` (for project-level warning filtering) - Fixes `diagnostics()` call in `forge-verify` to pass the new `SeismicConfig` argument ## Usage In `foundry.toml`: ```toml no_seismic_warnings = true # suppress ALL ssolc warnings (codes >= 10000) seismic_warnings_in_tests = true # show ssolc warnings even in *.t.sol files ``` Via CLI: ```bash sforge build --no-seismic-warnings sforge test --seismic-warnings-in-tests ``` ## Test plan - [x] `cargo build --bin sforge` compiles successfully - [x] `cargo +nightly fmt --all --check` passes - [ ] CI: `cargo nextest run test_seismic_` passes - [ ] Manually verify `--no-seismic-warnings` flag appears in `sforge build --help` - [ ] Manually verify `no_seismic_warnings = true` in foundry.toml suppresses ssolc warnings --------- Co-authored-by: Ameya Deshmukh <ad@seismic.systems>
) moved `sfoundryup/*` back to `foundryup/*` to make checking diff with upstream code easier. The binary installed is still named sfoundryup, and also added a symlink `sfoundryup/install` -> `foundryup/install` so that users can still see ``` curl -L https://raw.githubusercontent.com/SeismicSystems/seismic-foundry/seismic/sfoundryup/install | bash ```
We had forked and drastically simplified foundryup to the point where the only install option was cloning the repo and install from source, which is very slow. Now that our CI builds release binaries, it makes sense to make sfoundryup able to download those. I reverted foundryup to match upstream (master branch) and then made the minimal diff to make it work for our usecase (eg changing `foundryup` -> `sfoundryup` everywhere). The default option is also now to download the latest published release, which means users won't get broken everytime we push a temporary small bug to seismic branch. Also gives us some time to plan breaking change upgrades. Currently we don't have any published releases (only nightly pre-releases) so `sfoundryup` will fail. I will fix this in a subsequent PR by fixing our release CI and publishing a first v0.1.0 release. We will then in the future just need to tag versions for CI to build a new release version which will then be downloaded by sfoundryup automatically. Users can also get the latest nightly release by using `sfoundryup -i nightly` With this change sfoundryup can now also manage multiple versions: ``` $ ./foundryup/foundryup --list sfoundryup: nightly sfoundryup: - sforge 1.3.5-nightly (94eb5fc 2026-03-16T06:43:41.332565000Z) sfoundryup: - cast 1.3.5-nightly (94eb5fc 2026-03-16T06:43:41.332565000Z) sfoundryup: - anvil 1.3.5-nightly (94eb5fc 2026-03-16T06:43:41.332565000Z) sfoundryup: - chisel 1.3.5-nightly (94eb5fc 2026-03-16T06:43:41.332565000Z) sfoundryup: nightly-557cad357702a1027bb8d3d245f8d9d28626d127 sfoundryup: - sforge 1.3.5-nightly (557cad3 2026-03-09T06:34:02.839560000Z) sfoundryup: - cast 1.3.5-nightly (557cad3 2026-03-09T06:34:02.839560000Z) sfoundryup: - anvil 1.3.5-nightly (557cad3 2026-03-09T06:34:02.839560000Z) sfoundryup: - chisel 1.3.5-nightly (557cad3 2026-03-09T06:34:02.839560000Z) ``` ## Note to reviewers The diff looks huge but its now very minimal with upstream. Instead of checking this PR's diff, better to checkout this branch locally and run `git diff master`.
Changed it to a symlink in previous PR but github raw links to not follow symlinks, so changing it to a wrapper script.
Lots of small fixes/updates: - Enabled v*.*.* tag trigger for stable/versioned releases - Added permissions: contents: write to cleanup job — fixes stuck nightly tag (15 commits behind HEAD) - Dynamic changelog: Find previous semver tag step replaces hardcoded STABLE_VERSION: "v1.2.3" - Removed schisel from bins, tarballs, man pages, attestation - Commented out Windows archive code - Renamed nightly → weekly in release titles
No description provided.