Skip to content
Back to skills

Crane Porting Verification

ASecurity

This skill should be used when the user asks to "verify a protocol port", "port tests", "fork test the port", "Behavior for ported protocol", "TestBase for ported protocol", "parity with mainnet", "port verification", "definition of done for port", or needs to write/run tests that prove Crane-vendored protocol code matches upstream behavior.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 10, 2026
testinggobashtestingapi

Works with

  • api

Security analysis

A93/100
  • highPerforms destructive filesystem operations

Pro shows the line behind each finding and how to fix it

Scanned September 10, 2026

npx -y skills add cyotee/indexedex --skill crane-porting-verification --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Crane Porting Verification?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Crane Porting Verification
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cyotee-crane-porting-verification/badge)](https://www.skillsdirectory.com/skills/cyotee-crane-porting-verification)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: crane-porting-verification
description: This skill should be used when the user asks to "verify a protocol port", "port tests", "fork test the port", "Behavior for ported protocol", "TestBase for ported protocol", "parity with mainnet", "port verification", "definition of done for port", or needs to write/run tests that prove Crane-vendored protocol code matches upstream behavior.
license: MIT
---

# Crane Protocol Port Verification

Mandatory testing and acceptance gates for any protocol ported into Crane. Complements `crane-porting` (how to vendor) and `crane-testing` (how Crane tests are structured).

## Production-first (same ladder as crane-testing)

1. **Real production / ported contracts** — deploy protocol ports (stubs) or use factories for Crane wrappers.
2. **Existing `TestBase_*` chains** — extend, do not reinvent.
3. **Hermetic ports** under `protocols/.../stubs/` **or** fork bases with live addresses.
4. **Harness doubles** only outside the SUT (mintable ERC20, reentrancy token).
5. **`vm.mockCall`** only for non-SUT isolation.

**Forbidden:** mocking the ported protocol SUT, mocking Crane facets/DFPkgs under test, shipping a port with only compile success.

## Required verification layers

Every port must implement the layers that apply. Core ports need **all of 1–5**. Thin interface wrappers may skip 4 if documented.

| # | Layer | Purpose | Location |
|---|-------|---------|----------|
| 1 | **Compile** | `@crane/` imports resolve; no private dep trees required | `forge build` |
| 2 | **Hermetic unit / integration** | Deploy ported contracts locally; exercise core flows | `test/foundry/spec/protocols/...` + `TestBase_*` |
| 3 | **Behavior libraries** | Interface compliance for consumer-facing APIs | `Behavior_I*` next to protocol or under test infra |
| 4 | **Fork parity** | Same inputs → same outputs vs live deployment | `TestBase_*Fork` + RPC |
| 5 | **Wrapper / Service tests** | Crane Service, AwareRepo, DFPkg paths work end-to-end | CraneTest + factories |
| 6 | **Upstream suite (when portable)** | Bring high-value upstream Foundry/Hardhat cases | Adapted under `test/foundry/spec/...` |
| 7 | **Adversarial (if value-bearing wrappers)** | Donation, reentrancy, auth matrix | `crane-adversarial-testing` |
| 8 | **Gas snapshots (optional but preferred)** | Regressions on hot paths | `snapshots/` + gas tests |

## Directory conventions

```
contracts/protocols/{category}/{protocol}/{version}/
├── stubs/                      # Protocol-faithful deployables for hermetic tests
├── test/bases/
│   ├── TestBase_<Protocol>.sol           # Deploys stubs / wires addresses
│   └── TestBase_<Protocol>Fork.sol       # Optional: fork setup + live addresses
└── services/…                  # Covered by wrapper tests

test/foundry/spec/protocols/{category}/{protocol}/{version}/
├── unit/…                      # Pure unit + hermetic integration
├── fork/…                      # Live-chain parity
├── gas/…                       # Optional gas
└── contracts/…                 # Deeper module suites (Aave-style)
```

Mirror the protocol tree under `test/foundry/spec/` the same way existing Aave/Uniswap/CCA suites do.

## TestBase patterns for ports

### Hermetic protocol setup

```solidity
// contracts/protocols/dexes/example/v1/test/bases/TestBase_ExampleV1.sol
abstract contract TestBase_ExampleV1 is TestBase_Weth9 {
    IExampleFactory internal exampleFactory;
    IExampleRouter internal exampleRouter;

    function setUp() public virtual override {
        TestBase_Weth9.setUp(); // CraneTest factories first via parent chain
        if (address(exampleFactory) == address(0)) {
            // Protocol PORT (stubs/), not a mock
            exampleFactory = IExampleFactory(address(new ExampleFactory(feeToSetter)));
        }
        if (address(exampleRouter) == address(0)) {
            exampleRouter = IExampleRouter(
                address(new ExampleRouter(address(exampleFactory), address(weth)))
            );
        }
    }
}
```

Rules:

- Call parent `setUp()` first (`Super.setUp()` / explicit parent).
- Idempotent guards: only deploy if zero address.
- `new` is allowed **only** for protocol ports/stubs, never for Crane production facets/DFPkgs.
- Prefer `vm.label` on deployed addresses.

### Fork setup

```solidity
abstract contract TestBase_ExampleV1_Fork is CraneTest {
    uint256 internal forkId;
    address constant LIVE_FACTORY = 0x…; // from VENDOR / official docs

    function setUp() public virtual override {
        CraneTest.setUp();
        forkId = vm.createSelectFork(vm.envString("ETH_RPC_URL")); // or BASE_RPC_URL
        // Bind interfaces to live addresses; do not redeploy core protocol
    }
}
```

- Record RPC env var and chain id in the test NatSpec / PR description.
- Prefer pinned block numbers for reproducibility when assertions are brittle:
  `vm.createSelectFork(url, blockNumber)`.
- Compare **exact** values where deterministic (balances, reserves, preview outputs). Document any timestamp/block-dependent drift.

### Behavior libraries

For every interface Crane consumers will call:

- Add `Behavior_I{Name}` with `expect_*` / `isValid_*` / `areValid_*` / `hasValid_*`.
- Declaration tests via `TestBase_I{Name}` style where applicable.
- Reuse existing `Behavior_IERC20`, `Behavior_ERC4626`, `Behavior_IFacet` when the surface matches.

Standards interfaces **must not** be validated only with ad-hoc `assertEq` — use Behaviors (`crane-testing` LR-7).

### Crane wrapper tests

If the port adds Service / Aware / Facet / DFPkg:

1. Inherit `CraneTest` (or gold TestBase chain).
2. Deploy facets/packages via **create3Factory / diamondPackageFactory** — full init, no `address(0)` facets.
3. Assert registry population after deploy when factories register packages.
4. Facet declaration tests: `facetName`, `facetInterfaces`, `facetFuncs`, `facetMetadata` via `Behavior_IFacet`.
5. Package declaration tests when DFPkg exists.

### Upstream tests

When the upstream repo has good Foundry tests:

1. Copy valuable cases into `test/foundry/spec/protocols/...`.
2. Rewrite imports to `@crane/...`.
3. Point fixtures at Crane TestBases / stubs.
4. Drop cases that require unavailable off-chain services; replace with fork asserts if needed.
5. Keep license headers and note origin in file header comments.

## Assertion standards (LR-7 excerpts for ports)

- **Exact** expected values / deltas — not "something changed".
- `vm.expectEmit` with full topics/data when events matter for consumers.
- `vm.expectRevert` with selector (and typed form when available).
- Preview parity for any `preview*` on wrappers/vaults: preview == execute result.
- CREATE3 salt determinism for Crane deployables: same inputs → same address.
- Access-control matrix for any Operable / Ownable / role-gated Crane surface.
- Fork parity for at least one **happy path per primary user action** (swap, supply, stake, etc.).

## Minimum scenarios per protocol type

| Category | Must-cover flows (examples) |
|----------|-----------------------------|
| DEX AMM | create pool, add/remove liquidity, swap exact in/out, fee accrual if exposed |
| CL AMM | mint/burn position, swap across ticks, observe/TWAP if ported |
| Lending | supply, borrow, repay, withdraw, liquidation edge (or fork snapshot) |
| LST / wrapper | wrap/unwrap, rate read, share/asset conversion |
| Vault ERC4626 | deposit/mint/withdraw/redeem + preview parity + inflation awareness |
| Gauge / staking | deposit, claim, withdraw, epoch/edge timing |
| Oracle adapter | quote bounds, stale feed behavior if modeled |

Document protocol-specific risks in the test module header (cooldowns, funding rates, admin roles).

## Commands agents should run

From the **Crane repo root** (`lib/crane` or standalone crane checkout):

```bash
# 1. Clean build after import remaps
rm -rf cache out
forge build

# 2. Port suite (path-scoped)
forge test --match-path 'test/foundry/spec/protocols/<category>/<protocol>/**' -vv

# 3. Named focus
forge test --match-contract <ContractName> -vvv

# 4. Fork tests (requires RPC)
ETH_RPC_URL=... forge test --match-path 'test/foundry/spec/protocols/.../fork/**' -vv

# 5. Gas (if snapshots exist)
forge test --match-path 'test/foundry/spec/protocols/.../gas/**' --gas-report
```

Do not claim the port is done if path-scoped tests were not run (or explicitly skipped with a recorded reason, e.g. missing RPC for fork-only work — hermetic suite must still pass).

## Definition of done — verification checklist

Copy into the PR / task completion note:

- [ ] `forge build` clean for touched packages
- [ ] `VENDOR.md` present with pin, license, import policy
- [ ] No new `protocols/**/dependencies/openzeppelin*` or solady clones for this port
- [ ] All new imports use `@crane/...` (no new remapping aliases)
- [ ] Hermetic `TestBase_*` deploys protocol ports successfully
- [ ] Unit/integration tests cover primary user flows with exact asserts
- [ ] `Behavior_*` for consumer interfaces (or reuse of existing Behaviors)
- [ ] Fork tests against documented live addresses (or waiver + residual risk listed)
- [ ] Crane Service / Aware / DFPkg tests if wrappers exist (factory deploy path)
- [ ] Adversarial smoke if wrappers custody assets
- [ ] Path-scoped `forge test` output captured (pass)
- [ ] CODEBASE_MAP / protocol docs / skill updated or ticketed

## Failure triage

| Symptom | Likely cause | Fix direction |
|---------|--------------|---------------|
| Import not found | Missing external file or wrong major | Expand `external/`, fix path |
| Silent behavior change | Routed OZ consumer to Crane-native | Retarget to external OZ |
| Hermetic deploy reverts | Incomplete constructor args / missing init | Match upstream deploy script |
| Fork mismatch | Wrong address, block, or fee-on-transfer | Pin block; verify address source |
| Stack too deep in Service | Too many locals | Struct-ize params (`crane-code-style`) |
| Tests pass but consumer breaks | Missing Behavior / interface surface | Add interface + Behavior + Service coverage |

## Key files

```
contracts/test/CraneTest.sol
contracts/protocols/**/test/bases/TestBase_*.sol
contracts/protocols/**/stubs/
test/foundry/spec/protocols/
DEFI_PORTING_PRD.md          # per-protocol Verification bullets
AGENTS.md                    # testing + production-first rules
docs/development/testing.md
```

## See also

- `skill:crane-porting` — vendoring layout and dependency policy
- `skill:crane-testing` — TestBase / Behavior / Handler deep dive
- `skill:crane-adversarial-testing` — abuse catalogs
- `skill:crane-deployment` — factory usage inside tests
- Agent: `crane-porter`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…