Skip to content
Closed
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
43 changes: 43 additions & 0 deletions .claude/context/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Architecture

## Diamond proxy

`contracts/Diamond.sol` plus the standard `DiamondCutFacet` / `DiamondLoupeFacet` / `OwnershipFacet` / `DiamondInit`, pulled in through `hardhat-dependency-compiler` from `@mudgen/diamond-1`.

- Protocol logic: `contracts/facets/*Facet.sol`
- External API declarations: `contracts/interfaces/`
- `contracts/IexecInterfaceToken.sol` aggregates them into the single interface downstream tools compile against
- Shared helpers: `contracts/abstract/` (`FacetBase`, `IexecPocoCommon`, `SignatureVerifier`, …)
- Storage lives in one struct accessed through `contracts/libs/PocoStorageLib.sol`, shared by every facet: **never reorder or remove an existing variable, only append**. `npm run check-storage-layout` is the CI gate.
- Adding or removing a facet means editing two hand-maintained lists: `utils/proxy-tools.ts#getAllLocalFacetFunctions` (selector-to-name map used by upgrades) and the facet groups in `scripts/tools/sol-to-uml.mjs`.

Three solc versions: `0.8.21` with `viaIR` for PoCo contracts, `0.6.12` for the `@amxx/factory` dependency, `0.4.24` for RLC. A `docgen` task override in `hardhat.config.ts` temporarily hides 0.4 build-info files because docgen cannot parse them.

## Deployment

`deploy/0_deploy.ts` is the single source of truth.

Boost facets (`IexecPocoBoostFacet`, `IexecPocoBoostAccessorsFacet`) are deliberately **not** deployed on Arbitrum mainnet/Sepolia — see the `isArbitrumMainnetOrSepolia` branch in `deploy/0_deploy.ts`.

Changing `SALT` changes every derived address, which breaks integrations that rely on deterministic addresses.

## Chain config

- `token: null` makes the deployment deploy a fresh RLC mock; a real address makes it reuse that token.
- Registries are looked up before deployment, so several marketplaces on one chain share them.

## Orders

Off-chain EIP-712 orders (app / dataset / workerpool / request) are matched on-chain by `IexecPoco1Facet` (`matchOrders` plus sponsored variants) or, in the Boost flow, by `IexecPocoBoostFacet`. Structs and hashing live in the linked library `contracts/libs/IexecLibOrders_v5.sol`. The TypeScript side is `utils/createOrders.ts` (builders) and `utils/odb-tools.ts` (signing).

## Task lifecycle

`IexecPoco2Facet` implements initialize → contribute → reveal → finalize, with reopen and claim paths. Escrow and staking are in `IexecEscrowTokenFacet`: deposited RLC is tracked as an internal, non-transferable ERC-20-like balance. Enums and helpers mirroring on-chain state are in `utils/poco-tools.ts` (`TaskStatusEnum`, `ContributionStatusEnum`, `PocoMode`, `getDealId`, `getTaskId`, enclave/authorization signing, `getIexecAccounts`).

## Registries

`contracts/registries/` holds ERC-721 registries for apps, datasets and workerpools. Entries are minimal proxies (`RegistryEntry`, `InitializableUpgradeabilityProxy`) at create2-predictable addresses.

## Token-only

Native-asset mode and Bellecour (chain 134) support were removed across PRs #341-#344: no native escrow facet, no `IexecInterfaceNative`, no `asset` field in the chain config, and no `setName` ENS stubs on the registries. Only the token escrow path exists.
21 changes: 21 additions & 0 deletions .claude/context/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Commands and CI

`package.json#scripts` is the command list.

## Generated, never hand-edit

| Output | Regenerated by |
| ------------------------ | ----------------------------- |
| `abis/**` | every compile (`clear: true`) |
| `typechain/` | every compile |
| `docs/solidity/index.md` | `npm run doc`, from NatSpec |
| `docs/uml/*.svg` | `npm run uml` |

Edit the NatSpec or the generator config instead.

## CI

- `.github/workflows/main.yml` runs, in order: `format:check`, `doc:check`, `build`, `check-storage-layout`, `deploy`, `coverage`, then Slither on `contracts/tools/testing/slither/`.
- Any NatSpec change must be followed by `npm run doc`, or `doc:check` fails.
- `doc:check` diffs the whole `docs/` directory, so a regenerated UML SVG left uncommitted also fails it.
- `npm run doc` starts with `hardhat clean`, so it wipes and rebuilds `artifacts/` and `typechain/`.
39 changes: 39 additions & 0 deletions .claude/context/conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Conventions

## Every file

- Solidity and TypeScript files open with the header pair:

```
// SPDX-FileCopyrightText: <years> IEXEC BLOCKCHAIN TECH <contact@iex.ec>
// SPDX-License-Identifier: Apache-2.0
```

- `npm run format` (Prettier, with `prettier-plugin-solidity` and `prettier-plugin-organize-import`) is the formatter. CI runs `format:check`.
- Solidity imports are named (`import {Foo} from "./Foo.sol";`), not bare. The Solidity plugin does not sort them, so keep the existing grouping by hand.

## Published surface

`package.json#files` publishes `abis/`, `contracts/`, `deployments/` and `artifacts/contracts`. Consumers are the iExec SDK and the subgraph, so **any ABI, artifact path or artifact name change is a public API change**. A breaking one needs a `feat!:` or `refactor!:` PR title and a note for those two consumers.

Event signatures are part of that surface twice over: changing one moves its `topic0` and silently breaks the subgraph.

## Storage

Every facet shares one struct behind `contracts/libs/PocoStorageLib.sol`. Never reorder or remove an existing variable, only append. `npm run check-storage-layout` is the gate.

## Generated, never hand-edit

`abis/**`, `typechain/`, `docs/solidity/index.md`, `docs/uml/*.svg`. Edit the NatSpec or the generator config, then regenerate.

## Hand-maintained lists

Two lists are not generated and must be edited when a facet is added, removed or renamed:

- `utils/proxy-tools.ts#getAllLocalFacetFunctions`
- the facet groups in `scripts/tools/sol-to-uml.mjs`

## Git

- Trunk-based, squash merges only. The PR title becomes the commit message, so it must follow Conventional Commits.
- Historical records are not rewritten: `CHANGELOG.md`, the upgrade reports under `scripts/upgrades/*.md` and the `deployments/` artifacts describe what was actually released and deployed, including names that have since changed.
19 changes: 19 additions & 0 deletions .claude/context/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Tests

## Layout

- `test/0xx_fullchain*.test.ts` — end-to-end deal/task flows: classic, Boost, BoT, multi-orders, reopen.
- `test/byContract/**` — per-facet suites, one directory per facet family.
- `test/utils/` — shared helpers, described below.

## Helpers

- `test/utils/hardhat-fixture-deployer.ts` — runs the real `deploy/0_deploy.ts` inside a `loadFixture` snapshot. Every suite starts from it, so tests exercise production deployment code rather than a test-only setup.
- `test/utils/IexecWrapper.ts` — high-level actions.
- `test/utils/fixture-helpers.ts` — account funding and ownership transfers, used by fork-mode runs.
- `utils/poco-tools.ts` — `getIexecAccounts`, deal/task id derivation, result digest/hash builders, enclave and authorization message signing.
- `utils/createOrders.ts` / `utils/odb-tools.ts` — order builders and EIP-712 signing.

## Timeouts and fork mode

Mocha timeout is 300s in `hardhat.config.ts` (40s in `.mocharc.json`, which only applies to direct mocha runs). Fork tests copy `deployments/arbitrumSepolia` in via a `test` task override in `hardhat.config.ts` and clean it up afterwards; drive them with `npm run test:arbitrumSepolia` (`ARBITRUM_SEPOLIA_FORK=true`).
9 changes: 9 additions & 0 deletions .claude/context/upgrades.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Facet upgrades

Full human-facing procedure: `scripts/upgrades/README.md`.

## Traps

- `getAllLocalFacetFunctions` in the same file is hand-maintained: a facet added or deleted without editing it leaves selectors unresolved during the upgrade.
- `npm run check-storage-layout` compares layouts found in `artifacts/build-info`; storage stays append-only across versions.
- After a mainnet upgrade, refresh the facet list on the block explorer ("Is this a proxy?") so the proxy reads correctly.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ deployments/dev-*

# Flattened Solidity file used to generate diagrams.
flatten.sol

# Agent worktrees.
.claude/worktrees
13 changes: 13 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# CLAUDE.md

Solidity implementation of iExec's Proof of Contribution (PoCo) protocol: Hardhat 2 + TypeScript, deployed behind an ERC-2535 Diamond proxy, shipped as the `@iexec/poco` npm package. Live on Arbitrum One (42161) and Arbitrum Sepolia (421614).

## Read when relevant

| When you are… | Read |
| ------------------------------------------------------------------------------------------ | --------------------------------- |
| creating or editing any file, committing, or opening a PR | `.claude/context/conventions.md` |
| changing contracts, storage, facets, deployment, chain config, orders or registries | `.claude/context/architecture.md` |
| running a command beyond `package.json#scripts`, or reasoning about CI and generated files | `.claude/context/commands.md` |
| writing or debugging tests, or using the test helpers | `.claude/context/testing.md` |
| scripting or executing a facet upgrade | `.claude/context/upgrades.md` |
Loading