diff --git a/.agents/context/architecture.md b/.agents/context/architecture.md new file mode 100644 index 00000000..b1c3b2f2 --- /dev/null +++ b/.agents/context/architecture.md @@ -0,0 +1,39 @@ +# 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. diff --git a/.agents/context/commands.md b/.agents/context/commands.md new file mode 100644 index 00000000..d817d65a --- /dev/null +++ b/.agents/context/commands.md @@ -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/`. diff --git a/.agents/context/conventions.md b/.agents/context/conventions.md new file mode 100644 index 00000000..6283e273 --- /dev/null +++ b/.agents/context/conventions.md @@ -0,0 +1,13 @@ +# Conventions + +## Public API surface + +`abis/`, `contracts/`, `deployments/` and `artifacts/contracts` ship in the npm package (`package.json#files`), so **ABI and deployment-artifact changes are public API changes** — consumers are the iExec SDK and the subgraph. A breaking one needs a `feat!:` / `refactor!:` PR title. + +## Headers + +Every Solidity and TypeScript file opens with the `SPDX-FileCopyrightText` / `SPDX-License-Identifier: Apache-2.0` header pair. + +## Git + +Trunk-based, squash merges only. The PR title becomes the commit message and must follow Conventional Commits (`conventional-commits.yml` enforces it). Releases are cut by Release Please; prereleases by `npm run prerelease`, which requires `package.json` and the git tag to agree. diff --git a/.agents/context/testing.md b/.agents/context/testing.md new file mode 100644 index 00000000..37d8a5a4 --- /dev/null +++ b/.agents/context/testing.md @@ -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`). diff --git a/.agents/context/upgrades.md b/.agents/context/upgrades.md new file mode 100644 index 00000000..74b09367 --- /dev/null +++ b/.agents/context/upgrades.md @@ -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. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..5b61d681 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,13 @@ +# AGENTS.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 | `.agents/context/conventions.md` | +| changing contracts, storage, facets, deployment, chain config, orders or registries | `.agents/context/architecture.md` | +| running a command beyond `package.json#scripts`, or reasoning about CI and generated files | `.agents/context/commands.md` | +| writing or debugging tests, or using the test helpers | `.agents/context/testing.md` | +| scripting or executing a facet upgrade | `.agents/context/upgrades.md` | diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..43c994c2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md