@iexec-nox/nox-protocol-contracts 0.1.0-beta.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -37
- package/contracts/sdk/Nox.sol +5 -4
- package/contracts/shared/HandleUtils.sol +35 -0
- package/contracts/shared/TypeUtils.sol +5 -33
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -1,63 +1,100 @@
|
|
|
1
|
-
# Nox
|
|
1
|
+
# Nox · nox-protocol-contracts
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](./LICENSE)
|
|
4
|
+
[](https://docs.iex.ec)
|
|
5
|
+
[](https://discord.com/invite/5TewNUnJHN)
|
|
6
|
+
[](https://github.com/iExec-Nox/nox-protocol-contracts/releases)
|
|
7
|
+
[](https://www.npmjs.com/package/@iexec-nox/nox-protocol-contracts)
|
|
8
|
+
[](https://codecov.io/gh/iExec-Nox/nox-protocol-contracts)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
> Solidity contracts for the Nox protocol: manage encrypted handles, validate proofs, and trigger confidential computations.
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
- `Nox` SDK library: convenience wrapper for app contracts that call `NoxCompute`.
|
|
12
|
+
## Table of Contents
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
- [Nox · nox-protocol-contracts](#nox--nox-protocol-contracts)
|
|
15
|
+
- [Table of Contents](#table-of-contents)
|
|
16
|
+
- [Overview](#overview)
|
|
17
|
+
- [Prerequisites](#prerequisites)
|
|
18
|
+
- [Getting Started](#getting-started)
|
|
19
|
+
- [Environment Variables](#environment-variables)
|
|
20
|
+
- [Testing](#testing)
|
|
21
|
+
- [Deployment](#deployment)
|
|
22
|
+
- [Verification](#verification)
|
|
23
|
+
- [Configuration notes](#configuration-notes)
|
|
24
|
+
- [Related Repositories](#related-repositories)
|
|
25
|
+
- [Contributing](#contributing)
|
|
26
|
+
- [Code style](#code-style)
|
|
27
|
+
- [License](#license)
|
|
11
28
|
|
|
12
|
-
|
|
13
|
-
- `pnpm` (see `packageManager` in `package.json`)
|
|
29
|
+
## Overview
|
|
14
30
|
|
|
15
|
-
|
|
31
|
+
**nox-protocol-contracts** is the Solidity layer of the Nox protocol. It provides:
|
|
32
|
+
|
|
33
|
+
- **NoxCompute**: the main UUPS-upgradeable contract that manages the Access Control List (ACL) for encrypted handles, validates handle proofs issued by a trusted gateway, facilitates plaintext-to-encrypted conversions, and triggers off-chain TEE computations through event emissions.
|
|
34
|
+
- **INoxCompute**: the public interface consumed by application contracts and off-chain services.
|
|
35
|
+
- **Nox SDK library** (`contracts/sdk/Nox.sol`): a convenience wrapper that resolves the NoxCompute proxy address per chain and exposes typed helper functions for application contracts.
|
|
36
|
+
|
|
37
|
+
## Prerequisites
|
|
38
|
+
|
|
39
|
+
- Node.js >= 24 (see `.nvmrc`)
|
|
40
|
+
- pnpm >= 10 (see `packageManager` in `package.json`)
|
|
41
|
+
- Hardhat >= 3
|
|
42
|
+
|
|
43
|
+
## Getting Started
|
|
16
44
|
|
|
17
45
|
```bash
|
|
46
|
+
git clone https://github.com/iExec-Nox/nox-protocol-contracts.git
|
|
47
|
+
cd nox-protocol-contracts
|
|
48
|
+
|
|
49
|
+
# Use the correct Node version
|
|
18
50
|
nvm install && nvm use
|
|
19
|
-
pnpm install
|
|
20
|
-
```
|
|
21
51
|
|
|
22
|
-
|
|
52
|
+
# Install dependencies
|
|
53
|
+
pnpm install
|
|
23
54
|
|
|
24
|
-
|
|
55
|
+
# Build contracts
|
|
25
56
|
pnpm run build
|
|
26
57
|
```
|
|
27
58
|
|
|
28
|
-
##
|
|
59
|
+
## Environment Variables
|
|
29
60
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
61
|
+
| Variable | Description | Required | Default |
|
|
62
|
+
| ------------------- | ---------------------------------------------- | ----------------- | ------- |
|
|
63
|
+
| `RPC_URL` | JSON-RPC endpoint for the target network | For remote deploy | - |
|
|
64
|
+
| `PRIVATE_KEY` | Deployer private key | For remote deploy | - |
|
|
65
|
+
| `ETHERSCAN_API_KEY` | API key for contract verification on Etherscan | For verification | - |
|
|
33
66
|
|
|
34
|
-
##
|
|
67
|
+
## Testing
|
|
35
68
|
|
|
36
69
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
70
|
+
# Run all tests (unit + integration)
|
|
71
|
+
pnpm run test
|
|
39
72
|
|
|
40
|
-
|
|
73
|
+
# Run tests with gas stats
|
|
74
|
+
pnpm run test:gas
|
|
41
75
|
|
|
42
|
-
|
|
43
|
-
pnpm run
|
|
44
|
-
pnpm run format:check
|
|
76
|
+
# Run coverage
|
|
77
|
+
pnpm run coverage
|
|
45
78
|
```
|
|
46
79
|
|
|
47
80
|
## Deployment
|
|
48
81
|
|
|
49
|
-
The default network is a local EDR simulation. For external networks,
|
|
50
|
-
|
|
51
|
-
- `RPC_URL`
|
|
52
|
-
- `PRIVATE_KEY`
|
|
82
|
+
The default network is a local EDR simulation. For external networks, set `RPC_URL` and `PRIVATE_KEY`:
|
|
53
83
|
|
|
54
84
|
```bash
|
|
85
|
+
# Local deploy
|
|
55
86
|
pnpm run deploy
|
|
87
|
+
|
|
88
|
+
# Production deploy (optimizer + viaIR)
|
|
89
|
+
pnpm run deploy:production
|
|
90
|
+
|
|
91
|
+
# Upgrade an existing proxy
|
|
92
|
+
pnpm run upgrade
|
|
56
93
|
```
|
|
57
94
|
|
|
58
|
-
##
|
|
95
|
+
## Verification
|
|
59
96
|
|
|
60
|
-
Verify deployed contracts on Etherscan. Requires `ETHERSCAN_API_KEY
|
|
97
|
+
Verify deployed contracts on Etherscan. Requires `ETHERSCAN_API_KEY`:
|
|
61
98
|
|
|
62
99
|
```bash
|
|
63
100
|
pnpm run verify arbitrumSepolia --network arbitrumSepolia
|
|
@@ -65,18 +102,46 @@ pnpm run verify arbitrumSepolia --network arbitrumSepolia
|
|
|
65
102
|
|
|
66
103
|
## Configuration notes
|
|
67
104
|
|
|
68
|
-
-
|
|
69
|
-
- Default owner addresses and KMS public keys per network are also defined in [config/config.ts](config/config.ts).
|
|
70
|
-
- The SDK constants in [contracts/sdk/Nox.sol](contracts/sdk/Nox.sol) must match the deployed proxy addresses.
|
|
105
|
+
- CREATE2 salt is defined in [`config/config.ts`](config/config.ts).
|
|
106
|
+
- Default owner addresses and KMS public keys per network are also defined in [`config/config.ts`](config/config.ts).
|
|
107
|
+
- The SDK constants in [`contracts/sdk/Nox.sol`](contracts/sdk/Nox.sol) must match the deployed proxy addresses.
|
|
108
|
+
- OpenZeppelin manifest files in `.openzeppelin/` track proxy deployments.
|
|
109
|
+
|
|
110
|
+
## Related Repositories
|
|
111
|
+
|
|
112
|
+
| Repository | Description |
|
|
113
|
+
| ------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
114
|
+
| [nox-handle-sdk](https://github.com/iExec-Nox/nox-handle-sdk) | TypeScript SDK for handle encryption/decryption |
|
|
115
|
+
| [nox-offchain-deployment](https://github.com/iExec-Nox/nox-offchain-deployment) | Off-chain services (gateway, KMS, runner, ingestor) |
|
|
116
|
+
|
|
117
|
+
## Contributing
|
|
118
|
+
|
|
119
|
+
Contributions are welcome. Please open an issue first to discuss your proposed changes.
|
|
120
|
+
|
|
121
|
+
1. Fork the repository
|
|
122
|
+
2. Create your feature branch (`git checkout -b feature/my-feature`)
|
|
123
|
+
3. Commit your changes
|
|
124
|
+
4. Push to the branch (`git push origin feature/my-feature`)
|
|
125
|
+
5. Open a Pull Request
|
|
126
|
+
|
|
127
|
+
### Code style
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Format all files
|
|
131
|
+
pnpm run format
|
|
132
|
+
|
|
133
|
+
# Check formatting
|
|
134
|
+
pnpm run format:check
|
|
135
|
+
```
|
|
71
136
|
|
|
72
137
|
## License
|
|
73
138
|
|
|
74
|
-
The Nox Protocol source code is released under the Business Source License 1.1 (BUSL-1.1).
|
|
139
|
+
The Nox Protocol source code is released under the [Business Source License 1.1 (BUSL-1.1)](./LICENSE).
|
|
75
140
|
|
|
76
141
|
The license will automatically convert to the MIT License under the conditions described in the LICENSE file.
|
|
77
142
|
|
|
78
|
-
The full text of the MIT License is provided in the LICENSE-MIT file.
|
|
143
|
+
The full text of the MIT License is provided in the [LICENSE-MIT](./LICENSE-MIT) file.
|
|
79
144
|
|
|
80
|
-
|
|
145
|
+
Some files are dual-licensed under MIT:
|
|
81
146
|
|
|
82
|
-
- All files in `contracts/interfaces/`, `contracts/shared/`, `contracts/sdk/` may also be licensed under
|
|
147
|
+
- All files in `contracts/interfaces/`, `contracts/shared/`, `contracts/sdk/` may also be licensed under MIT (as indicated in their SPDX headers).
|
package/contracts/sdk/Nox.sol
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.27;
|
|
3
3
|
|
|
4
|
+
import {HandleUtils} from "../shared/HandleUtils.sol";
|
|
4
5
|
import {TEEType, TypeUtils} from "../shared/TypeUtils.sol";
|
|
5
6
|
import {INoxCompute} from "../interfaces/INoxCompute.sol";
|
|
6
7
|
import "encrypted-types/EncryptedTypes.sol";
|
|
@@ -47,7 +48,7 @@ library Nox {
|
|
|
47
48
|
* Public handles are already accessible by everyone and don't need ACL.
|
|
48
49
|
*/
|
|
49
50
|
function _allowIfNotPublic(bytes32 handle, address account) private {
|
|
50
|
-
if (!
|
|
51
|
+
if (!HandleUtils.isPublicHandle(handle)) {
|
|
51
52
|
_noxComputeContract().allow(handle, account);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -57,7 +58,7 @@ library Nox {
|
|
|
57
58
|
* Public handles are already accessible by everyone and don't need ACL.
|
|
58
59
|
*/
|
|
59
60
|
function _allowTransientIfNotPublic(bytes32 handle, address account) private {
|
|
60
|
-
if (!
|
|
61
|
+
if (!HandleUtils.isPublicHandle(handle)) {
|
|
61
62
|
_noxComputeContract().allowTransient(handle, account);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
@@ -67,7 +68,7 @@ library Nox {
|
|
|
67
68
|
* Public handles are already accessible by everyone and don't need ACL.
|
|
68
69
|
*/
|
|
69
70
|
function _disallowTransientIfNotPublic(bytes32 handle, address account) private {
|
|
70
|
-
if (!
|
|
71
|
+
if (!HandleUtils.isPublicHandle(handle)) {
|
|
71
72
|
_noxComputeContract().disallowTransient(handle, account);
|
|
72
73
|
}
|
|
73
74
|
}
|
|
@@ -1402,6 +1403,6 @@ library Nox {
|
|
|
1402
1403
|
bytes32 handle,
|
|
1403
1404
|
TEEType teeType
|
|
1404
1405
|
) private view returns (bytes32) {
|
|
1405
|
-
return handle == bytes32(0) ?
|
|
1406
|
+
return handle == bytes32(0) ? HandleUtils.zeroHandle(teeType) : handle;
|
|
1406
1407
|
}
|
|
1407
1408
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.27;
|
|
3
|
+
|
|
4
|
+
import {TEEType} from "./TypeUtils.sol";
|
|
5
|
+
|
|
6
|
+
library HandleUtils {
|
|
7
|
+
/// @dev Bit 0 of the attrs byte. When set, the handle is guaranteed unique on-chain.
|
|
8
|
+
bytes1 internal constant ATTR_IS_UNIQUE_HANDLE = 0x01;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @notice Checks if a handle is a public handle (isUniqueHandle bit == 0).
|
|
12
|
+
* A public handle wraps a plaintext value known on-chain, has no ACL,
|
|
13
|
+
* and is accessible by everyone.
|
|
14
|
+
* @param handle The handle to check
|
|
15
|
+
* @return True if the handle is a public handle
|
|
16
|
+
*/
|
|
17
|
+
function isPublicHandle(bytes32 handle) internal pure returns (bool) {
|
|
18
|
+
return (handle[6] & ATTR_IS_UNIQUE_HANDLE) == 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @notice Returns the zero handle for the given TEE type on the current chain.
|
|
23
|
+
* The zero handle represents the default zero value for a given type and is a public handle.
|
|
24
|
+
* It follows the standard handle format but with a zeroed pre-handle:
|
|
25
|
+
* [0]=version(0x00) [1-4]=chainId [5]=teeType [6]=attrs(0x00) [7-31]=0x00..00
|
|
26
|
+
* @param teeType The TEE type to encode
|
|
27
|
+
* @return The typed null handle
|
|
28
|
+
*/
|
|
29
|
+
function zeroHandle(TEEType teeType) internal view returns (bytes32) {
|
|
30
|
+
return
|
|
31
|
+
// [0]=version is implicitly 0x00
|
|
32
|
+
(bytes32(bytes4(uint32(block.chainid))) >> (1 * 8)) |
|
|
33
|
+
(bytes32(bytes1(uint8(teeType))) >> (5 * 8));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -116,9 +116,6 @@ error NonArithmeticType();
|
|
|
116
116
|
error UnsupportedArithmeticType();
|
|
117
117
|
|
|
118
118
|
library TypeUtils {
|
|
119
|
-
/// @dev Bit 0 of the attrs byte. When set, the handle is guaranteed unique on-chain.
|
|
120
|
-
bytes1 internal constant ATTR_IS_UNIQUE_HANDLE = 0x01;
|
|
121
|
-
|
|
122
119
|
/**
|
|
123
120
|
* @notice Extracts the TEE type from a handle.
|
|
124
121
|
* The type is stored at byte position 5 in the handle.
|
|
@@ -129,17 +126,6 @@ library TypeUtils {
|
|
|
129
126
|
return TEEType(uint8(handle[5]));
|
|
130
127
|
}
|
|
131
128
|
|
|
132
|
-
/**
|
|
133
|
-
* @notice Checks if a handle is a public handle (isUniqueHandle bit == 0).
|
|
134
|
-
* A public handle wraps a plaintext value known on-chain, has no ACL,
|
|
135
|
-
* and is accessible by everyone.
|
|
136
|
-
* @param handle The handle to check
|
|
137
|
-
* @return True if the handle is a public handle
|
|
138
|
-
*/
|
|
139
|
-
function isPublicHandle(bytes32 handle) internal pure returns (bool) {
|
|
140
|
-
return (handle[6] & ATTR_IS_UNIQUE_HANDLE) == 0;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
129
|
/**
|
|
144
130
|
* @notice Validates that a TEE type is supported for arithmetic operations.
|
|
145
131
|
* Only the following arithmetic types are supported:
|
|
@@ -154,25 +140,11 @@ library TypeUtils {
|
|
|
154
140
|
function validateArithmeticType(TEEType teeType) internal pure {
|
|
155
141
|
uint8 t = uint8(teeType);
|
|
156
142
|
require(t >= uint8(TEEType.Uint8) && t <= uint8(TEEType.Int256), NonArithmeticType());
|
|
157
|
-
bool supportedType =
|
|
158
|
-
teeType == TEEType.
|
|
159
|
-
|
|
160
|
-
|
|
143
|
+
bool supportedType =
|
|
144
|
+
teeType == TEEType.Uint16 ||
|
|
145
|
+
teeType == TEEType.Uint256 ||
|
|
146
|
+
teeType == TEEType.Int16 ||
|
|
147
|
+
teeType == TEEType.Int256;
|
|
161
148
|
require(supportedType, UnsupportedArithmeticType());
|
|
162
149
|
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* @notice Returns the zero handle for the given TEE type on the current chain.
|
|
166
|
-
* The zero handle represents the default zero value for a given type.
|
|
167
|
-
* It follows the standard handle format but with a zeroed pre-handle:
|
|
168
|
-
* [0]=version(0x00) [1-4]=chainId [5]=teeType [6]=attrs(0x00) [7-31]=0x00..00
|
|
169
|
-
* @param teeType The TEE type to encode
|
|
170
|
-
* @return The typed null handle
|
|
171
|
-
*/
|
|
172
|
-
function zeroHandle(TEEType teeType) internal view returns (bytes32) {
|
|
173
|
-
return
|
|
174
|
-
// [0]=version is implicitly 0x00
|
|
175
|
-
(bytes32(bytes4(uint32(block.chainid))) >> (1 * 8)) |
|
|
176
|
-
(bytes32(bytes1(uint8(teeType))) >> (5 * 8));
|
|
177
|
-
}
|
|
178
150
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iexec-nox/nox-protocol-contracts",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Nox protocol smart contracts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Nox",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"deploy:production": "pnpm hardhat run scripts/deploy.ts --build-profile production",
|
|
27
27
|
"set-gateway": "pnpm hardhat run scripts/set-gateway.ts",
|
|
28
28
|
"set-kms-public-key": "pnpm hardhat run scripts/set-kms-public-key.ts",
|
|
29
|
-
"upgrade": "
|
|
30
|
-
"upgrade:production": "
|
|
29
|
+
"upgrade": "bash scripts/upgrade.sh",
|
|
30
|
+
"upgrade:production": "bash scripts/upgrade.sh --build-profile production",
|
|
31
31
|
"verify": "pnpm hardhat ignition verify",
|
|
32
32
|
"format": "pnpm prettier --write .",
|
|
33
33
|
"format:check": "pnpm prettier --check ."
|
|
@@ -44,19 +44,19 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@nomicfoundation/hardhat-ethers": "^4.0.6",
|
|
47
|
-
"@nomicfoundation/hardhat-ignition": "^3.0
|
|
48
|
-
"@nomicfoundation/hardhat-toolbox-viem": "^5.0.
|
|
47
|
+
"@nomicfoundation/hardhat-ignition": "^3.1.0",
|
|
48
|
+
"@nomicfoundation/hardhat-toolbox-viem": "^5.0.3",
|
|
49
49
|
"@openzeppelin/hardhat-upgrades": "4.0.0-alpha.0",
|
|
50
|
-
"@types/node": "^
|
|
50
|
+
"@types/node": "^25.5.0",
|
|
51
51
|
"ethers": "^6.16.0",
|
|
52
52
|
"forge-std": "github:foundry-rs/forge-std#v1.15.0",
|
|
53
|
-
"hardhat": "^3.
|
|
53
|
+
"hardhat": "^3.2.0",
|
|
54
54
|
"husky": "^9.1.7",
|
|
55
|
-
"lint-staged": "^16.
|
|
55
|
+
"lint-staged": "^16.4.0",
|
|
56
56
|
"prettier": "^3.8.1",
|
|
57
|
-
"prettier-plugin-solidity": "^2.
|
|
58
|
-
"typescript": "^
|
|
59
|
-
"viem": "^2.
|
|
57
|
+
"prettier-plugin-solidity": "^2.3.1",
|
|
58
|
+
"typescript": "^6.0.2",
|
|
59
|
+
"viem": "^2.47.6"
|
|
60
60
|
},
|
|
61
61
|
"homepage": "https://github.com/iExec-Nox/nox-protocol-contracts#readme",
|
|
62
62
|
"repository": {
|