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
8 changes: 0 additions & 8 deletions .gas-snapshot

This file was deleted.

9 changes: 0 additions & 9 deletions .github/workflows/manual-sol-artifacts.yaml

This file was deleted.

12 changes: 4 additions & 8 deletions .github/workflows/package-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ jobs:
release:
uses: rainlanguage/rainix/.github/workflows/rainix-autopublish.yaml@main
with:
# `foundry.toml` version is the NEXT (in-development) release. On merge,
# publish that version and bump to the next — the bump no longer generates
# artifacts. A version's deploy-pin snapshot is built by the PR that changes
# the bytecode: run `forge script ./script/BuildPointers.sol` and commit the
# new `src/generated/<tag>/` snapshot + LibCloneFactoryDeploy. The
# LibCloneFactoryDeploy fork/deploy tests fail if that snapshot is stale, and
# the rainix append-only check rejects any change to a snapshot already on
# main, so snapshots stay frozen once merged.
# Library repo: the ICloneable* interface surface. `foundry.toml` version is
# the NEXT (in-development) release; on a content change on merge, autopublish
# publishes it and bumps to the next. The deploy half (concrete + deploy-pin
# snapshots) lives in rain.factory.deploy (rainlanguage/rain.factory#46).
soldeer-package: rain-factory
secrets: inherit
77 changes: 45 additions & 32 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ code in this repository.

## Project Overview

rain.factory is a Solidity library providing EIP1167 minimal proxy (clone)
factory contracts for the Rain ecosystem. The core contract `CloneFactory`
clones any contract implementing `ICloneableV2` and atomically initializes it.
rain.factory is a Solidity **library** repo: the `ICloneable*` interface surface
for EIP1167 minimal proxy (clone) factories in the Rain ecosystem. It is the
library half of the library/deploy split (rainlanguage/rain.factory#46) and holds
interfaces only — no concrete contract, no deploy pins, no deploy script, and no
tests.

The concrete `CloneFactory` that implements these interfaces, its deployed
address + codehash pins (`LibCloneFactoryDeploy`), the frozen
`src/generated/<tag>/` deploy-pin snapshots and `script/Deploy.sol` all live in
[`rain.factory.deploy`](https://github.com/rainlanguage/rain.factory.deploy) and
publish as the `rain-factory-deploy` Soldeer package. Consumers that need only
the interfaces depend on `rain-factory`; consumers that need the deployed
address/codehash pins depend on `rain-factory-deploy`.

License: LicenseRef-DCL-1.0 (DecentraLicense). All source files must include
SPDX headers.
Expand All @@ -23,9 +33,6 @@ nix develop
Then use rainix tasks:

```bash
# Run all tests
nix develop -c rainix-sol-test

# Static analysis (Slither)
nix develop -c rainix-sol-static

Expand All @@ -34,20 +41,16 @@ nix develop -c rainix-sol-legal

# Prelude (dependency setup, run before other tasks)
nix develop -c rainix-sol-prelude

# Runs, but there is no test suite here: the interfaces have no behaviour to
# test. The tests that exercise them live in rain.factory.deploy, against the
# concrete.
nix develop -c rainix-sol-test
```

Direct Forge commands also work inside the nix shell:

```bash
# Run all tests
forge test

# Run a specific test
forge test --match-test testCloneDeterministic

# Run tests in a specific file
forge test --match-path test/src/concrete/CloneFactoryCloneDeterministic.t.sol

# Build
forge build
```
Expand All @@ -59,42 +62,52 @@ forge build
success.
- `src/interface/ICloneableFactoryV2.sol` — Legacy factory interface: the
nonce-dependent `clone(address, bytes)` and `NewClone` event. Superseded by
`ICloneableFactoryV3` for `CloneFactory`; still published for other consumers.
`ICloneableFactoryV3` for the concrete factory in rain.factory.deploy; still
published for other consumers.
- `src/interface/ICloneableFactoryV3.sol` — Current factory interface.
Deterministic-only: `cloneDeterministic(address, bytes, bytes32)` +
`predictDeterministicAddress(address, bytes32, address)` (CREATE2, salt
namespaced by `msg.sender`) and its own `NewClone` event. Standalone — does
NOT extend `ICloneableFactoryV2`, because the non-deterministic `clone()` was
intentionally dropped.
- `src/concrete/CloneFactory.sol` — The single concrete implementation of
`ICloneableFactoryV3`. Uses OpenZeppelin `Clones.cloneDeterministic()`; there
is no plain `clone()`.
- `src/lib/LibCloneFactoryDeploy.sol` — Deterministic deployment address and
codehash constants (generated; aliases the current tag's
`src/generated/<tag>/` snapshot).
- `src/interface/deprecated/` — Legacy interfaces (`ICloneableV1`,
`ICloneableFactoryV1`, `IFactory`). Do not use for new work.

`src/` holds nothing else. The interfaces import nothing — not each other, not a
third-party library — which is what makes this half a standalone publish.

## Solidity Conventions

- Solidity version: concrete contracts pin `=0.8.25` (exact); interface and
library files float `^` (the interfaces use `^0.8.18`) so downstream soldeer
consumers on a different `0.8.x` can still compile them
- Solidity version: every file here is an interface and floats `^` (the
interfaces use `^0.8.18`) so downstream soldeer consumers on a different
`0.8.x` can still compile them. The `=0.8.25` exact-pin rule applies to
concrete contracts, scripts and tests, which live in rain.factory.deploy.
- EVM target: Cancun
- Optimizer: enabled, 100,000 runs
- No CBOR metadata (`cbor_metadata = false`, `bytecode_hash = "none"`)
- Dependencies are managed with Soldeer (`[dependencies]` in `foundry.toml` +
`soldeer.lock`, vendored under `dependencies/`): forge-std,
@openzeppelin-contracts, rain-extrospection, rain-deploy, rain-sol-codegen
`soldeer.lock`, vendored under `dependencies/`). The interfaces import nothing,
so the only entry is forge-std. `@openzeppelin-contracts`, `rain-extrospection`,
`rain-deploy` and `rain-sol-codegen` went with the deploy half and must not
come back: adding one here means concrete code has landed in a library repo.

## Deployment

Deployed via deterministic Zoltu deployer (from `rain.deploy`). The canonical
deployment address and codehash are committed in `LibCloneFactoryDeploy.sol`.
Deployment scripts are in `script/Deploy.sol` targeting Arbitrum, Base, Base
Sepolia, Flare, and Polygon.
Nothing in this repo is deployed. The deterministic Zoltu deploy of the concrete
`CloneFactory`, its canonical address and codehash, and the deploy scripts
targeting Arbitrum, Base, Base Sepolia, Flare and Polygon are all in
rain.factory.deploy.

## Releases

Library repo, so `package-release.yaml` runs `rainix-autopublish`:
`[package].version` in `foundry.toml` is the NEXT, unpublished version, and a
content change on merge publishes it and bumps to the next. Nothing here is
tag-released, and no snapshot is frozen — that lifecycle belongs to the deploy
half.

## CI

GitHub Actions runs three parallel jobs on every push: `rainix-sol-test`,
`rainix-sol-static`, `rainix-sol-legal`. Fork tests require RPC URL secrets.
`rainix-sol-static`, `rainix-sol-legal`. There are no fork tests and no RPC
secrets are needed.
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,24 @@

Docs at https://rainprotocol.github.io/rain.factory

This repo is the **library** half of the library/deploy split
([#46](https://github.com/rainlanguage/rain.factory/issues/46)): the
`ICloneable*` interface surface, and nothing else. It publishes to Soldeer as
`rain-factory`.

## Concrete implementations

`CloneFactory` implements `ICloneableFactoryV2` allowing any
compatible `ICloneableV2` contract to be cloned as an EIP1167 proxy and
initialized.
`CloneFactory` — the concrete that implements these interfaces, letting any
compatible `ICloneableV2` contract be cloned as an EIP1167 proxy and initialized
— lives in
[`rain.factory.deploy`](https://github.com/rainlanguage/rain.factory.deploy),
together with its deployed address + codehash pins, its frozen per-release
deploy-pin snapshots and its deploy script. That repo publishes as
`rain-factory-deploy`.

Depend on `rain-factory` if you need only the interfaces. Depend on
`rain-factory-deploy` if you need the deployed address or codehash of a live
`CloneFactory`.

## Interfaces

Expand All @@ -32,8 +45,14 @@ The onchain tooling for analysis is found at https://github.com/rainprotocol/rai

The current interfaces in this repository are for

- `ICloneableFactoryV3`, the current factory interface: deterministic-only
(`cloneDeterministic` + `predictDeterministicAddress`, CREATE2 with the salt
namespaced by `msg.sender`). Standalone rather than extending
`ICloneableFactoryV2`, because the non-deterministic `clone()` was
intentionally dropped
- `ICloneableFactoryV2` that is expected to clone proxies from a reference
implementation
implementation. Superseded by `ICloneableFactoryV3` for the concrete factory,
still published for other consumers
- A small interface `ICloneableV2` designed for cloneable proxy contracts to
expose an `initialize` function that the factory can call to act like a
constructor
Expand Down
1 change: 0 additions & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ version = 1

[[annotations]]
path = [
".gas-snapshot",
".github/workflows/**/",
".vscode/**/",
".coderabbitai.yaml",
Expand Down
31 changes: 4 additions & 27 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,17 @@ evm_version = "cancun"
bytecode_hash = "none"
cbor_metadata = false

# Build metadata used for testing rain meta aware contracts in this folder rather
# than expose ffi to forge.
fs_permissions = [
{ access = "read", path = "./meta" },
# BuildPointers reads the version from foundry.toml and writes the generated
# per-tag snapshots + the current-pin lib under src/.
{ access = "read", path = "./foundry.toml" },
{ access = "read-write", path = "./src" },
]
libs = ["dependencies"]

[fuzz]
runs = 2048

# Library repo: the ICloneable* interface surface only. The concrete CloneFactory,
# its deploy-pin snapshots and deploy scripts live in rain.factory.deploy
# (rainlanguage/rain.factory#46). Interfaces import nothing, so there are no
# Solidity dependencies beyond the test harness.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
[dependencies]
forge-std = "1.16.1"
"@openzeppelin-contracts" = "5.6.1"
"rain-extrospection" = "0.1.1"
"rain-deploy" = "0.1.3"
"rain-sol-codegen" = "0.1.0"

[soldeer]
recursive_deps = false

[rpc_endpoints]
arbitrum = "${ARBITRUM_RPC_URL}"
base = "${BASE_RPC_URL}"
base_sepolia = "${BASE_SEPOLIA_RPC_URL}"
flare = "${FLARE_RPC_URL}"
polygon = "${POLYGON_RPC_URL}"

[etherscan]
arbitrum = { key = "${CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY}" }
base = { key = "${CI_DEPLOY_BASE_ETHERSCAN_API_KEY}" }
base_sepolia = { key = "${CI_DEPLOY_BASE_SEPOLIA_ETHERSCAN_API_KEY}" }
flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}" }
polygon = { key = "${CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY}" }
118 changes: 0 additions & 118 deletions script/BuildPointers.sol

This file was deleted.

Loading
Loading