Skip to content

Commit c0c4dab

Browse files
Phancoclaude
andauthored
feat(contracts): add UUPS-upgradeable fork of OpenZeppelin BatcherConfidential (PRO-290) (#117)
* feat(contracts): add UUPS-upgradeable fork of OpenZeppelin BatcherConfidential (PRO-290) Introduces a new `confidential-batcher-upgradeable` package containing an upgradeable fork of `BatcherConfidential` from OpenZeppelin Confidential Contracts v0.4.0-rc.0. The only structural change from upstream is splitting the constructor into immutable assignments + `__BatcherConfidential_init` initializer for UUPS proxy compatibility; all other logic is identical. Includes a minimal test harness exercising deployment behind ERC1967Proxy, interface validation, initializer state, and re-initialization guards. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(contracts): move BatcherConfidentialUpgradeable out of openzeppelin subfolder Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(contracts): restore upstream NatSpec and formatting in BatcherConfidentialUpgradeable Preserves the original comments, pragma, and layout from OpenZeppelin's finance/BatcherConfidential.sol v0.4.0; fork diff is limited to the constructor/initializer split, Initializable inheritance, and __gap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(contracts): add UUPS upgrade coverage for BatcherConfidentialUpgradeable Harness now inherits OwnableUpgradeable + UUPSUpgradeable with an owner-gated _authorizeUpgrade. Introduces a V2 harness with a version() getter to verify upgrade swaps bytecode while preserving initializer state and storage layout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(contracts): address PR-117 review for confidential-batcher - rename package confidential-batcher-upgradeable -> confidential-batcher - migrate state to ERC-7201 namespaced storage; drop immutables and __gap - split __BatcherConfidential_init into _init / _init_unchained; init now takes fromToken and toToken as arguments and runs ERC-165 validation + token approvals inside the initializer - fix misleading NatSpec: initializer runs during proxy deployment - drop dead Makefile targets (get-accounts, test-tasks) - tighten file header NatSpec - harness V2 overrides routeDescription instead of exposing version() - delete ERC1967ProxyMock; tests now use hardhat-upgrades deployProxy - append batcher selectors to contracts/selectors.txt - add local .prettierrc mirroring sibling packages Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(contracts): port upstream BatcherConfidential test suite Adds a full port of OpenZeppelin confidential-contracts' BatcherConfidential test suite, adapted to the UUPS-upgradeable fork introduced in PR #117. Solidity additions: - `fhevm/ZamaEthereumConfigUpgradeable.sol` — upgradeable sibling of ZamaEthereumConfig, mirroring the wrapper package. - `mocks/ExchangeMock.sol` — verbatim port of upstream's fixed-rate ERC-20 swap (used by the swap mock's _executeRoute). - `mocks/BatcherConfidentialSwapMockUpgradeable.sol` — upgradeable port of upstream's BatcherConfidentialSwapMock. Concrete UUPS subclass with real _executeRoute that routes through the ExchangeMock. Uses ERC-7201 namespaced storage (slot 0xf57b...ec00) for exchange/admin/outcome. - `mocks/ERC7984ERC20WrapperMock.sol` — now inherits ZamaEthereumConfig so the FHE coprocessor is configured on deployment; exposes plaintext `$_mint(address,uint64)` / `$_burn(address,uint64)` helpers the ported test suite relies on. Test port (new file `BatcherConfidential.test.ts`, 41 tests): - join via callback / directly (5 tests each) - claim (7 tests) + on-behalf-of relayer (3 tests) - quit (5 tests) - dispatchBatchCallback (8 tests covering Complete / Partial / Cancel branches, invalid exchange rate, unwrap finalization) - dispatchBatch (1 test) - batch state transitions (5 tests) - invalid fromToken / toToken rejection at init (2 tests) - end-to-end "cancel and quit takes tokens from the next batch" Deployment switched to `upgrades.deployProxy(..., { kind: 'uups' })`. Selectors regenerated for the batcher package. The existing `BatcherConfidentialUpgradeable.test.ts` is retained for upgrade-mechanics coverage (V2 upgrade path, initializer guards) that upstream does not exercise. Total test count: 11 (existing) + 41 (ported) = 52 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(contracts): inherit ZamaEthereumConfigUpgradeable in abstract batcher Addresses reviewer feedback on PR #117 asking to move FHE coprocessor setup into the abstract base so derived contracts can't forget to wire it. Changes: - `BatcherConfidentialUpgradeable` now inherits `ZamaEthereumConfigUpgradeable` and calls `__ZamaEthereumConfig_init()` inside `__BatcherConfidential_init`, before the unchained init. This also gives the `_init` / `_init_unchained` split a principled reason to exist: `_init` chains the config setup while `_init_unchained` skips it (useful for diamond-pattern inheritance). - `BatcherConfidentialSwapMockUpgradeable` drops redundant `ZamaEthereumConfigUpgradeable` from its inheritance list and removes the explicit `__ZamaEthereumConfig_init()` call from `initialize` since both are now covered by the abstract's chain. Also addresses a smaller reviewer comment on the ported test file: - `ERC7984ERC20WrapperMock.sol` constructor now takes a `uri` argument rather than hardcoding "". - `BatcherConfidential.test.ts` deploys `$ERC7984ERC20WrapperMock` (hardhat-exposed variant) instead of plain `ERC7984ERC20WrapperMock`, matching upstream's test pattern. Cast to the base `$ERC7984ERC20Wrapper` type following upstream. Selectors: +10 lines for the new `confidentialProtocolId()` and `ZamaProtocolUnsupported()` entries on the abstract base and its harnesses. Tests: 52 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(contracts): use meaningful uri strings in upgrade-mechanics test Follow-up to the previous commit: the existing BatcherConfidentialUpgradeable test was still passing "" as the uri arg when deploying the wrapper mocks. Replace with descriptive URLs so all wrapper deployments match the reviewer's ask ("keep some uri argument inside constructor of ERC7984ERC20WrapperMock ... instead of enforcing an empty string, I think it makes tests clearer"). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(contracts): split ERC7984Mock out of wrapper mock Mirror upstream's file layout. The plaintext `$_mint(address,uint64)` and `$_burn(address,uint64)` helpers (used by the 'should track failed claims properly' test) now live in a new `ERC7984Mock.sol` and reach `ERC7984ERC20WrapperMock` via inheritance. The wrapper mock becomes a thin diamond-resolution shim (supportsInterface / decimals / _update overrides), exactly matching upstream's shape. Closes jatZama's PR #117 feedback about removing the manual helpers from the wrapper mock file. `ERC7984Mock.sol` is a minimal subset — just the two plaintext helpers our tests actually use. Other upstream helpers (createEncryptedAmount, _OWNER pattern, encrypted-input variants) are omitted until a test needs them. Selectors: +81 lines for the new `ERC7984Mock` section. No other sections change. Tests: 52 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 19c3ff1 commit c0c4dab

22 files changed

Lines changed: 14379 additions & 0 deletions
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Authentication (use one of these)
2+
MNEMONIC=
3+
PRIVATE_KEY=
4+
5+
# RPC URLs
6+
MAINNET_RPC_URL=
7+
SEPOLIA_RPC_URL=
8+
9+
# API Keys
10+
ETHERSCAN_API_KEY=
11+
12+
# Gas Reporter
13+
REPORT_GAS=false
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build artifacts
5+
artifacts/
6+
cache/
7+
cache_forge/
8+
out/
9+
types/
10+
contracts-exposed/
11+
12+
# Coverage
13+
coverage/
14+
coverage.json
15+
16+
# Environment
17+
.env
18+
.env.local
19+
.env.*.local
20+
21+
# IDE
22+
.idea/
23+
.vscode/
24+
*.swp
25+
*.swo
26+
.DS_Store
27+
28+
# Logs
29+
*.log
30+
npm-debug.log*
31+
32+
# Typechain
33+
typechain-types/
34+
35+
# Hardhat
36+
deployments/
37+
38+
# OpenZeppelin
39+
.openzeppelin/
40+
41+
# Foundry
42+
broadcast/
43+
44+
# Fhevm
45+
fhevmTemp/
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"printWidth": 120,
3+
"singleQuote": true,
4+
"trailingComma": "all",
5+
"arrowParens": "avoid",
6+
"overrides": [
7+
{
8+
"files": "*.sol",
9+
"options": {
10+
"singleQuote": false
11+
}
12+
}
13+
],
14+
"plugins": ["prettier-plugin-solidity"]
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
include .env.example
2+
3+
ENV_PATH=.env.example
4+
5+
prettier:
6+
npx prettier . --write
7+
8+
lint:
9+
npm run lint
10+
11+
compile:
12+
npx hardhat compile
13+
14+
clean:
15+
npx hardhat clean
16+
17+
# Define it as a phony target to avoid conflicts with the test directory
18+
.PHONY: test
19+
test: clean
20+
DOTENV_CONFIG_PATH=$(ENV_PATH) npx hardhat test --network hardhat $(if $(GREP),--grep '$(GREP)',)
21+
22+
# Conform to pre-commit checks
23+
conformance: prettier lint

0 commit comments

Comments
 (0)