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
64 changes: 32 additions & 32 deletions .github/workflows/claude-review.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
claude-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Claude Code Review
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
review_comment_prefix: "evm-cortex-review"
direct_prompt: |
Review this PR for:
1. Solidity code quality and security patterns
2. Smart contract vulnerabilities (reentrancy, access control, oracle manipulation)
3. Gas optimization opportunities
4. Test coverage gaps (Foundry tests)
5. Breaking changes to existing contracts
Use evm-cortex's code-reviewer agent standards.
Provide VERDICT: PASS | WARN | FAIL
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write
issues: write
id-token: write

jobs:
claude-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Claude Code Review
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Review this PR for:
1. Solidity code quality and security patterns
2. Smart contract vulnerabilities (reentrancy, access control, oracle manipulation)
3. Gas optimization opportunities
4. Test coverage gaps (Foundry tests)
5. Breaking changes to existing contracts

Use evm-cortex's code-reviewer agent standards.
Provide VERDICT: PASS | WARN | FAIL
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Full analysis with PoC verification for Medium+ findings. Mix of opus and sonnet
Complete audit with invariant fuzzing, formal properties, multi-iteration depth analysis, and skeptic review for High/Critical findings.

### Pashov 12-Agent Pipeline
For comprehensive security review, use the `pashov-audit-pipeline` skill which runs 12 specialized attacker agents in parallel. Nine work a single lens — math precision, access control, economic security, execution trace, invariant, periphery, first principles, asymmetry, boundary — and three are gap-hunters (numerical, trust, flow) that report only bugs living at the seam between lenses. Findings are deduplicated, run through four judging gates, confidence-scored, and severity-classified with PoCs for Critical/High.
For comprehensive security review, use the `pashov-audit-pipeline` skill which runs 12 specialized attacker agents in parallel. Nine work a single lens — math precision, access control, economic security, execution trace, invariant, periphery, first principles, asymmetry, boundary — and three are gap-hunters (numerical, trust, flow) that report only bugs living at the seam between lenses. Findings are deduplicated, run through four judging gates, confidence-scored, and assembled by shell into one report, with an EVM Cortex severity annex and PoCs for Critical/High. Supports loop mode (`--loop N` passes per scan, each told what earlier passes found) and a findings ledger across scans (`--memory`).

### 0xSimao Accounting-First Pipeline
For accounting-heavy protocols (vaults, lending, staking, yield, AMMs, bridges), use the `simao-audit-pipeline` skill. It reverse-engineers 0xSimao's 869 published findings: the orchestrator first writes a **money map** — assets, tracked totals, an asymmetry table, invariants, lifecycles, and actor cohorts — then hands it to 12 parallel single-specialty lenses (accounting-desync, share-exchange-rate, temporal-cohort, liquidation-solvency, cross-chain-state, rounding-precision, ordering-mev, dos-griefing, access-trust, integration-assumptions, edge-states, flow-completeness). His signature class: a tracked total that desyncs from reality, letting early actors over-withdraw and leaving the last user out insolvent. Findings are deduplicated through four hard gates, judged, and severity-classified with Foundry PoCs for High findings. Complements `pashov-audit-pipeline` — run both and treat overlap as signal.
Expand Down
10 changes: 9 additions & 1 deletion UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ These are user data:

## Version History

### Unreleased
### v1.1.0 (2026-09-29)

Minor release. Installers gain a real upgrade mode, the Pashov audit pipeline moves to solidity-auditor v4 with loop mode and scan memory, `simao-audit-pipeline` and the `fizz` family are new, the Uniswap skills are corrected against current Uniswap code, and the EVM facts are refreshed. `package.json`, `plugin.json`, and `evm-cortex version` now agree on the version; the latter two had stayed at 1.0.0 through 1.0.1 and 1.0.2. Skills total 95, agents 50.

**Installers now support upgrading.** Previously the default mode skipped every existing file and reported the result as "Skipped: N (already existed)", which made an upgrade a silent no-op — the documented `git pull && ./install.sh` flow updated nothing. Default mode now distinguishes *already current* from *out of date*, lists the stale files, and points at `--update`. `install-cursor.sh` gained overwrite support, which it previously lacked entirely.

Expand All @@ -73,6 +75,12 @@ These three skills now ship `references/`, `scripts/`, and `templates/` subdirec

**Added `simao-audit-pipeline`.** An accounting-first audit skill vendored from [0xSimao AI](https://github.com/0xsimao/0xsimao-ai) (VERSION 1.0.0), reverse-engineered from 0xSimao's 869 published findings. The orchestrator builds a money map (assets, tracked totals, asymmetry table, invariants, lifecycles, cohorts), then runs 12 parallel single-specialty lenses over it, deduplicates through four hard gates, and emits severity-classified findings with Foundry PoCs for Highs. It ships a `references/` subdirectory (method, severity calibration, report formatting, 12 attack lenses + shared rules) carried over from upstream intact except for the repo's `onchain` spelling normalization; the EVM Cortex adaptations (agent mapping, Foundry pre-flight, PoC routing) live in `SKILL.md` only. Skills total 95.

**`pashov-audit-pipeline` synced to solidity-auditor v4.** Upstream (2026-09-23) added loop mode (`--loop N` passes per scan, each pass told what earlier passes found, one combined report), a findings ledger across scans (`--memory`, on automatically when passes > 1, stored at `.solidity-auditor/memory.tsv` in the audited repo), and a shell-assembled report: each pass writes its gated findings to a run file and `references/assemble.sh` is the only thing that produces `full-report.md`, so the report can never overstate its coverage. Findings are worded in Simplified Technical English (`report-language.md`, appended to every agent bundle), the confidence threshold moved from 80 to 75, deploy scripts are now in scope, agents are READ-ONLY in the audited repo, and the upgrade warning fires only when the local `VERSION` is lower. Upstream's `SKILL.md` is vendored verbatim as `references/orchestration.md` so future syncs stay a file-by-file diff; the EVM Cortex layer (agent mapping, context package, Foundry pre-flight, a `**Severity**` line in each finding block, and a Turn 6 severity/PoC annex built by shell from the assembled report) lives in `SKILL.md`. PoCs are written under `.solidity-auditor/runs/{stamp}/poc/` and run with `FOUNDRY_TEST` overridden, never into the project's `test/`. Audited repos should gitignore `.solidity-auditor/`.

**EVM current-state facts refreshed from ethskills.com (2026-09-25).** `rules/evm-current-state.md` now records Fusaka as shipped (Dec 3, 2025), Glamsterdam as in progress for Q3-Q4 2026 with FOCIL dropped, and Hegota (Q4 2026) without Verkle; adds Unichain (chain ID 130, time-priority ordering) and Robinhood Chain (chain ID 4663, Orbit L2 whose transaction filtering can censor force-included transactions); notes the Aerodrome/Velodrome merger into Aero, Base's announced Superchain exit, and Hardhat 3 as a legitimate toolchain alongside this squad's Foundry default; and pins the ERC-8004 registry and ERC-4337 EntryPoint v0.7 addresses after `cast code` verification. `agents/eip-expert.md` had Fusaka as "targeting late 2026" and Glamsterdam as "2027+"; both corrected, with a CFI/SFI/DFI (EIP-7723) guide for checking fork scope on forkcast. `agents/l2-specialist.md` gained Unichain, Robinhood Chain, chain IDs, and the dominant-DEX-per-chain note. `skills/erc8004-patterns` replaces its `0x...` placeholder with the verified registry addresses.

**Uniswap skills and agents corrected against current Uniswap code and docs (2026-09-25).** The seven `uniswap-*`/`lp-analyst`/`pool-finder` skills and six matching agents were homegrown in April and had drifted. Compile-breaking fixes: `SwapParams`/`ModifyLiquidityParams` now import from `v4-core/src/types/PoolOperation.sol` instead of `IPoolManager.*`; `BaseHook` and `HookMiner` were removed from `v4-periphery` on 2026-02-06 (PR #510), so hook examples import `@openzeppelin/uniswap-hooks/src/base/BaseHook.sol` (what `Uniswap/v4-template` pins) or `Uniswap/v4-hooks-public`, and override `_beforeSwap`/`_afterSwap` internally; `uniswap-v4-testing` had the V4 swap sign convention inverted everywhere (negative `amountSpecified` is exact input), redeclared `PoolKey key` over the `Deployers` field, used a pre-V4 fork block, and carried a bad EIP-55 checksum. Fact fixes: V3 TickLens address was non-hex and wrong; V4 positions are ERC-721, not ERC-6909; protocol-fee mechanics rewritten (set by the `protocolFeeController`, charged on swap input before the LP fee, lower 12 bits zeroForOne); `sync()` is callable outside `unlock()`; `notifyBurn` has five arguments; `Actions` has 26 codes; V4 is on 19 mainnets with Blast dropped and X Layer, Robinhood Chain, and Arc added; docs moved to developers.uniswap.org. New facts: the protocol fee switch is live on V3 mainnet since UNIfication executed 2025-12-28 (`feeProtocol` 68 or 102) and on V4 static-fee pools since 2026-07-27, so fee-revenue formulas now carry `(1 - protocol_share)`; Unichain (chain ID 130) V3 and V4 addresses and Ethereum StateView/V4Quoter/ReservesLens/Permit2 added, every address `cast code`-verified and EIP-55 checksummed; `pool-finder` calls StateView instead of a non-existent `getSlot0` ABI on the PoolManager and its PoolId `cast` example now reproduces the live ETH/USDC pool id. Numeric corrections in `uniswap-math` and `lp-analyst` (sqrtPriceX96 worked examples, tick for 3e-9, `maxLiquidityPerTick` magnitudes, capital-efficiency multipliers) were recomputed with arbitrary-precision arithmetic.

### v1.0.0 (2026-04-10)

**Initial release as EVM Cortex** — Ethereum protocol engineering squad.
Expand Down
69 changes: 39 additions & 30 deletions agents/amm-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,22 @@ L = Δy / (√(P_upper) - √(P_lower)) // liquidit

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
pragma solidity 0.8.26;

import {BaseHook} from "v4-periphery/src/utils/BaseHook.sol";
// BaseHook no longer ships in v4-periphery (removed 2026-02-06, PR #510). Pick one maintained base:
import {BaseHook} from "@openzeppelin/uniswap-hooks/src/base/BaseHook.sol"; // pinned by Uniswap/v4-template
// or: import {BaseHook} from "v4-hooks-public/src/base/BaseHook.sol"; // Uniswap Labs
import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol";
import {PoolKey} from "v4-core/src/types/PoolKey.sol";
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
import {BalanceDelta} from "v4-core/src/types/BalanceDelta.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "v4-core/src/types/BeforeSwapDelta.sol";
import {SwapParams} from "v4-core/src/types/PoolOperation.sol";
import {Currency} from "v4-core/src/types/Currency.sol";

// BaseHook's external callbacks are non-virtual and already `onlyPoolManager`;
// override the internal `_before*`/`_after*` functions and return the external selector.
contract MyHook is BaseHook {
using PoolIdLibrary for PoolKey;

Expand All @@ -83,35 +88,31 @@ contract MyHook is BaseHook {
});
}

function afterInitialize(
address sender,
PoolKey calldata key,
uint160 sqrtPriceX96,
int24 tick
) external override onlyPoolManager returns (bytes4) {
function _afterInitialize(address, PoolKey calldata key, uint160, int24)
internal
override
returns (bytes4)
{
swapCount[key.toId()] = 0;
return this.afterInitialize.selector;
return BaseHook.afterInitialize.selector;
}

function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
function _beforeSwap(address, PoolKey calldata, SwapParams calldata, bytes calldata)
internal
override
returns (bytes4, BeforeSwapDelta, uint24)
{
// Custom pre-swap logic (e.g., dynamic fees, access control)
return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}

function afterSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
BalanceDelta delta,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, int128) {
function _afterSwap(address, PoolKey calldata key, SwapParams calldata, BalanceDelta, bytes calldata)
internal
override
returns (bytes4, int128)
{
swapCount[key.toId()]++;
return (this.afterSwap.selector, 0);
return (BaseHook.afterSwap.selector, 0);
}
}
```
Expand All @@ -120,9 +121,13 @@ contract MyHook is BaseHook {

### Dynamic Fee Hook
```solidity
function beforeSwap(...) external override returns (bytes4, BeforeSwapDelta, uint24) {
function _beforeSwap(address, PoolKey calldata key, SwapParams calldata, bytes calldata)
internal
override
returns (bytes4, BeforeSwapDelta, uint24)
{
uint24 fee = _calculateDynamicFee(key);
return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, fee | LPFeeLibrary.OVERRIDE_FEE_FLAG);
return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, fee | LPFeeLibrary.OVERRIDE_FEE_FLAG);
}

function _calculateDynamicFee(PoolKey calldata key) internal view returns (uint24) {
Expand Down Expand Up @@ -157,12 +162,16 @@ function _executeTWAMMOrders(PoolKey calldata key) internal {
```solidity
mapping(PoolId => mapping(int24 => mapping(bool => uint256))) public limitOrders;

function afterSwap(...) external override returns (bytes4, int128) {
function _afterSwap(address, PoolKey calldata key, SwapParams calldata params, BalanceDelta, bytes calldata)
internal
override
returns (bytes4, int128)
{
int24 currentTick = _getCurrentTick(key);
// Check if price crossed any limit order ticks
// Fill orders that are now in-the-money
_fillCrossedOrders(key, currentTick, params.zeroForOne);
return (this.afterSwap.selector, 0);
return (BaseHook.afterSwap.selector, 0);
}
```

Expand All @@ -174,8 +183,8 @@ function afterSwap(...) external override returns (bytes4, int128) {
2. **Choose minimal permissions** — only enable the hooks you need. Each enabled hook adds gas cost to every matching operation.
3. **Preserve pool invariants** — hooks must not break the AMM's core accounting. If your hook modifies deltas, prove conservation of value.
4. **Consider MEV implications** — beforeSwap hooks that read onchain state can be front-run. Use commit-reveal or batch auctions for price-sensitive logic.
5. **Test with the V4 test framework** — use `PoolManager` deployers and routers from v4-periphery for realistic testing.
6. **Gas budget** — hooks execute on every swap. Keep gas under 50K for beforeSwap/afterSwap. Profile with `forge test --gas-report`.
5. **Test with the V4 test framework** — use `Deployers` (`v4-core/test/utils/Deployers.sol`) and the test routers (`PoolSwapTest`, `PoolModifyLiquidityTest` from `v4-core/src/test/`) for realistic testing.
6. **Gas budget** — hooks execute on every swap. There is no universal gas threshold; measure `beforeSwap`/`afterSwap` overhead on realistic and adversarial state with `forge test --gas-report` and track regressions with `forge snapshot --check`.

### Impermanent Loss Calculation:

Expand Down
12 changes: 10 additions & 2 deletions agents/eip-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,26 @@ ERCs (Ethereum Request for Comments) are a category of EIPs scoped to applicatio
| 7918 | Blob base fee bounded | Blob base fee can't drop below execution gas cost equivalent. |
| 7934 | RLP block size limit | Limits serialized block size. |

### Fusaka (targeting late 2026)
### Fusaka (live, December 3, 2025)
| EIP | Title | Impact |
|-----|-------|--------|
| 7594 | PeerDAS | Peer Data Availability Sampling. Major L2 scaling improvement. |
| 7892 | Blob-only hardforks | Enables blob parameter changes without full hard fork. |

### Glamsterdam (targeting 2027+)
### Glamsterdam (in progress, targeting Q3-Q4 2026 — dates slip)
| EIP | Title | Impact |
|-----|-------|--------|
| 7732 | Enshrined PBS (ePBS) | Proposer-Builder Separation in protocol. Removes MEV-Boost relay dependency. |
| 7928 | Block Access Lists | Contracts declare state access upfront. Enables parallel EVM execution. |

FOCIL (fork-choice inclusion lists) was removed from Glamsterdam scope to reduce complexity. Check [forkcast.org](https://forkcast.org) for the current SFI list before quoting scope.

### Hegota (targeting Q4 2026)
Does **not** contain Verkle trees. Verkle was the statelessness candidate for years, then deprioritized in 2024-2025 over quantum-resistance and ZK-compatibility concerns. Ethereum may move to a binary state tree instead (EIP-7864, Draft as of March 2026). Check https://forkcast.org/upgrade/hegota for confirmed scope.

### Checking whether a feature is actually scheduled
Roadmap diagrams and blog posts older than six months are aspirational. The status that matters is the fork relationship on [forkcast.org](https://forkcast.org), defined in EIP-7723: **CFI** (Considered for Inclusion — being evaluated, implementation starting), **SFI** (Scheduled for Inclusion — in devnets, ships barring disasters), **DFI** (Declined for Inclusion — rejected for that fork). Only SFI means "coming in fork X". For what client teams are saying, read the public [eth-rnd-archive](https://github.com/ethereum/eth-rnd-archive); for the canonical spec, prefer [execution-specs](https://github.com/ethereum/execution-specs) and [consensus-specs](https://github.com/ethereum/consensus-specs) over EIP text, which may have been modified during implementation.

## EVM Opcodes (Developer-Critical Finals)

| EIP | Opcode/Feature | Solidity Impact |
Expand Down
Loading
Loading