@iexec-nox/nox-protocol-contracts 0.1.0-beta.3 → 0.1.0-beta.5

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 CHANGED
@@ -4,9 +4,8 @@ Smart contracts for the Nox protocol, including on-chain access control for encr
4
4
 
5
5
  ## What’s inside
6
6
 
7
- - `IACL`: access control list for encrypted handles (admins, viewers, public decryption flags).
8
7
  - `INoxCompute`: TEE compute entry point (handle validation, plaintext → encrypted conversion, arithmetic ops).
9
- - `Nox` SDK library: convenience wrapper for app contracts that call `NoxCompute` and `ACL`.
8
+ - `Nox` SDK library: convenience wrapper for app contracts that call `NoxCompute`.
10
9
 
11
10
  ## Requirements
12
11
 
@@ -1,18 +1,31 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.0;
3
3
 
4
- import {IErrors} from "./IErrors.sol";
5
- import {IACL} from "./IACL.sol";
6
4
  import {TEEType} from "../shared/TypeUtils.sol";
7
5
 
8
6
  /**
9
7
  * @title INoxCompute
10
8
  * @notice Interface for the Nox compute contract powered by TEE.
11
9
  */
12
- interface INoxCompute is IErrors {
10
+ interface INoxCompute {
11
+ /// Error thrown when account address is zero
12
+ error InvalidZeroAddress();
13
+ /// Error thrown when bytes parameter is empty
14
+ error InvalidEmptyBytes();
15
+ /// Error thrown when sender doesn't have access to the handle
16
+ error UnauthorizedSender(address sender);
17
+ /// Error thrown when an account is not allowed to use a handle
18
+ error NotAllowed(bytes32 handle, address account);
13
19
  error InvalidProof(bytes proof, string reason);
20
+ error UnsupportedType();
14
21
  error IncompatibleTypes();
15
22
 
23
+ /// Emitted when admin role is granted
24
+ event Allowed(address indexed sender, address indexed account, bytes32 indexed handle);
25
+ /// Emitted when viewer role is granted
26
+ event ViewerAdded(address indexed sender, address indexed viewer, bytes32 indexed handle);
27
+ /// Emitted when a handle is marked as publicly decryptable
28
+ event MarkedAsPubliclyDecryptable(address indexed sender, bytes32 indexed handle);
16
29
  event KmsPublicKeyUpdated(bytes newKmsPublicKey);
17
30
  event GatewayUpdated(address indexed newGateway);
18
31
  event ProofExpirationDurationUpdated(uint256 newDuration);
@@ -152,19 +165,83 @@ interface INoxCompute is IErrors {
152
165
  Burn
153
166
  }
154
167
 
168
+ // ------------- ACL functions -------------
169
+
155
170
  /**
156
- * @notice Sets the KMS public key used for ECIES encryption
157
- * @param newKmsPublicKey The compressed SEC1 secp256k1 public key (33 bytes)
171
+ * Grant admin role to another address for a specific handle
172
+ * @dev Caller must have access (transient OR persistent) to the handle
173
+ * @param handle The handle identifier
174
+ * @param account The address to grant admin role
158
175
  */
159
- function setKmsPublicKey(bytes calldata newKmsPublicKey) external;
176
+ function allow(bytes32 handle, address account) external;
160
177
 
161
- function setGateway(address gatewayAddress) external;
178
+ /**
179
+ * Allows the use of `handle` by address `account` for this transaction.
180
+ * @param handle Handle.
181
+ * @param account Address of the account.
182
+ */
183
+ function allowTransient(bytes32 handle, address account) external;
162
184
 
163
185
  /**
164
- * @notice Sets the proof expiration duration
165
- * @param newDuration The new expiration duration in seconds
186
+ * Removes all transient authorizations. This is useful for integration with Account Abstraction
187
+ * when bundling several UserOps calling the NoxCompute.
188
+ * @dev Can be called by anyone (typically by AA bundlers between UserOps).
166
189
  */
167
- function setProofExpirationDuration(uint256 newDuration) external;
190
+ function cleanTransientStorage() external;
191
+
192
+ /**
193
+ * Returns whether the account is allowed to use the `handle`, either due to
194
+ * allowTransient() or allow().
195
+ * @param handle Handle.
196
+ * @param account Address of the account.
197
+ * @return Whether the account can access the handle (persistent or transient).
198
+ */
199
+ function isAllowed(bytes32 handle, address account) external view returns (bool);
200
+
201
+ /**
202
+ * Checks whether the account is allowed to use all provided handles.
203
+ * Reverts with NotAllowed if any handle is not allowed.
204
+ * @param account Address of the account.
205
+ * @param handles Array of handles to check.
206
+ */
207
+ function validateAllowedForAll(address account, bytes32[] calldata handles) external view;
208
+
209
+ /**
210
+ * Add a viewer for a specific handle
211
+ * @dev Only an admin can add a viewer. The viewer address cannot be address(0).
212
+ * @param handle The handle identifier
213
+ * @param viewer The address to grant viewer role
214
+ */
215
+ function addViewer(bytes32 handle, address viewer) external;
216
+
217
+ /**
218
+ * Returns whether the account can view the handle.
219
+ * @dev Returns true if any of the following conditions are met:
220
+ * - The handle is publicly decryptable
221
+ * - The account was added as a viewer via `addViewer`
222
+ * - The account has persistent access (is allowed) on the handle
223
+ * @param handle Handle.
224
+ * @param viewer Address of the viewer.
225
+ * @return Whether the account can view the handle.
226
+ */
227
+ function isViewer(bytes32 handle, address viewer) external view returns (bool);
228
+
229
+ /**
230
+ * Mark a handle as publicly decryptable.
231
+ * @dev The caller must be allowed to use the handle.
232
+ * If not, the function reverts.
233
+ * @param handle Handle to mark as publicly decryptable.
234
+ */
235
+ function allowPublicDecryption(bytes32 handle) external;
236
+
237
+ /**
238
+ * Checks whether a handle is publicly decryptable.
239
+ * @param handle Handle.
240
+ * @return Whether the handle is publicly decryptable.
241
+ */
242
+ function isPubliclyDecryptable(bytes32 handle) external view returns (bool);
243
+
244
+ // ------------- Compute functions -------------
168
245
 
169
246
  /**
170
247
  * @notice Converts a plaintext value into an encrypted value
@@ -175,7 +252,21 @@ interface INoxCompute is IErrors {
175
252
  function plaintextToEncrypted(bytes32 value, TEEType teeType) external returns (bytes32);
176
253
 
177
254
  /**
178
- * @notice Computes TEE Add operation
255
+ * @notice Validates a handle proof for a given owner and type.
256
+ * @param handle handle to validate
257
+ * @param owner owner of the provided handle
258
+ * @param proof proof data
259
+ * @param teeType expected handle type
260
+ */
261
+ function validateProof(
262
+ bytes32 handle,
263
+ address owner,
264
+ bytes calldata proof,
265
+ TEEType teeType
266
+ ) external;
267
+
268
+ /**
269
+ * @notice Performs an addition between two encrypted values without overflow check.
179
270
  * @param leftHandOperand Left-hand side operand handle
180
271
  * @param rightHandOperand Right-hand side operand handle
181
272
  * @return result Result handle
@@ -186,7 +277,7 @@ interface INoxCompute is IErrors {
186
277
  ) external returns (bytes32 result);
187
278
 
188
279
  /**
189
- * @notice Performs a subtraction between two encrypted values without safety checks.
280
+ * @notice Performs a subtraction between two encrypted values without underflow check.
190
281
  * @param leftHandOperand Left-hand side operand handle
191
282
  * @param rightHandOperand Right-hand side operand handle
192
283
  * @return result Result handle
@@ -197,7 +288,21 @@ interface INoxCompute is IErrors {
197
288
  ) external returns (bytes32 result);
198
289
 
199
290
  /**
200
- * @notice Performs a division between two encrypted values
291
+ * @notice Performs a multiplication between two encrypted values without overflow check.
292
+ * @param leftHandOperand Left-hand side operand handle
293
+ * @param rightHandOperand Right-hand side operand handle
294
+ * @return result Result handle
295
+ */
296
+ function mul(
297
+ bytes32 leftHandOperand,
298
+ bytes32 rightHandOperand
299
+ ) external returns (bytes32 result);
300
+
301
+ /**
302
+ * @notice Performs a division between two encrypted values without safety checks.
303
+ * In the case of a division by zero, the result will be as follows:
304
+ * - For unsigned integers uintN: encrypted MAX_UintN (i.e., 2^N - 1)
305
+ * - For signed integers intN: encrypted MAX_IntN (i.e., 2^(N-1) - 1)
201
306
  * @param numerator Value to be divided
202
307
  * @param denominator Value to divide by
203
308
  * @return result Result handle
@@ -205,15 +310,47 @@ interface INoxCompute is IErrors {
205
310
  function div(bytes32 numerator, bytes32 denominator) external returns (bytes32 result);
206
311
 
207
312
  /**
208
- * @notice Performs a multiplication between two encrypted values
313
+ * @notice Performs an addition between two encrypted values with overflow check.
314
+ * If the operation succeeds, the value of the success handle will be an encrypted
315
+ * `true` and the result handle's value will be the encrypted sum.
316
+ * If the operation fails (e.g., due to overflow), the success handle will contain
317
+ * an encrypted `false` and the result handle will contain an encrypted `0`.
209
318
  * @param leftHandOperand Left-hand side operand handle
210
319
  * @param rightHandOperand Right-hand side operand handle
320
+ * @return success Whether the operation was successful
211
321
  * @return result Result handle
212
322
  */
213
- function mul(
323
+ function safeAdd(
214
324
  bytes32 leftHandOperand,
215
325
  bytes32 rightHandOperand
216
- ) external returns (bytes32 result);
326
+ ) external returns (bytes32 success, bytes32 result);
327
+
328
+ /**
329
+ * @notice Performs a subtraction between two encrypted values with underflow check.
330
+ * If the operation succeeds, the value of the success handle will be an encrypted
331
+ * `true` and the result handle's value will be the encrypted difference.
332
+ * If the operation fails (e.g., due to underflow), the success handle will contain
333
+ * an encrypted `false` and the result handle will contain an encrypted `0`.
334
+ * @param leftHandOperand Left-hand side operand handle
335
+ * @param rightHandOperand Right-hand side operand handle
336
+ * @return success Whether the operation was successful
337
+ * @return result Result handle
338
+ */
339
+ function safeSub(
340
+ bytes32 leftHandOperand,
341
+ bytes32 rightHandOperand
342
+ ) external returns (bytes32 success, bytes32 result);
343
+
344
+ // TODO add safeMul and safeDiv
345
+
346
+ /**
347
+ * @notice Selects between two encrypted values based on a condition
348
+ * @param condition Condition handle
349
+ * @param ifTrue Value handle if condition is true
350
+ * @param ifFalse Value handle if condition is false
351
+ * @return result Selected value handle
352
+ */
353
+ function select(bytes32 condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32);
217
354
 
218
355
  /**
219
356
  * @notice Checks equality between two encrypted values
@@ -281,45 +418,12 @@ interface INoxCompute is IErrors {
281
418
  bytes32 rightHandOperand
282
419
  ) external returns (bytes32 result);
283
420
 
284
- // TODO for all safe operations, determine which cyphertexte linked to the new handle to return
285
- // as result in case of failure.
286
- /**
287
- * @notice Performs an addition between two encrypted values with safety checks.
288
- * The operation fails in the case of overflows.
289
- * @param leftHandOperand Left-hand side operand handle
290
- * @param rightHandOperand Right-hand side operand handle
291
- * @return success Whether the operation was successful
292
- * @return result Result handle
293
- */
294
- function safeAdd(
295
- bytes32 leftHandOperand,
296
- bytes32 rightHandOperand
297
- ) external returns (bytes32 success, bytes32 result);
298
-
299
- /**
300
- * @notice Performs a subtraction between two encrypted values with safety checks.
301
- * The operation fails in the case of underflow.
302
- * @param leftHandOperand Left-hand side operand handle
303
- * @param rightHandOperand Right-hand side operand handle
304
- * @return success Whether the operation was successful
305
- * @return result Result handle
306
- */
307
- function safeSub(
308
- bytes32 leftHandOperand,
309
- bytes32 rightHandOperand
310
- ) external returns (bytes32 success, bytes32 result);
311
-
312
- /**
313
- * @notice Selects between two encrypted values based on a condition
314
- * @param condition Condition handle
315
- * @param ifTrue Value handle if condition is true
316
- * @param ifFalse Value handle if condition is false
317
- * @return result Selected value handle
318
- */
319
- function select(bytes32 condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32);
320
-
321
421
  /**
322
422
  * @notice Computes a confidential transfer between two balances.
423
+ * The transfer will succeed if the sender has sufficient balance and fail otherwise.
424
+ * If the transfer fails, the success handle will contain an encrypted `false`, the
425
+ * newBalanceFrom and newBalanceTo handles will contain the same values as the input
426
+ * balanceFrom and balanceTo handles.
323
427
  * @param balanceFrom Sender's current balance handle
324
428
  * @param balanceTo Recipient's current balance handle
325
429
  * @param amount Amount handle to transfer
@@ -335,6 +439,9 @@ interface INoxCompute is IErrors {
335
439
 
336
440
  /**
337
441
  * @notice Computes a confidential mint operation.
442
+ * If the minting operation fails (e.g., due to overflow), the success handle will
443
+ * contain an encrypted `false` and the newBalanceTo and newTotalSupply handles will
444
+ * contain the same values as the input balanceTo and totalSupply handles.
338
445
  * @param balanceTo Recipient's current balance handle
339
446
  * @param amount Amount handle to mint
340
447
  * @param totalSupply Current total supply handle
@@ -350,6 +457,9 @@ interface INoxCompute is IErrors {
350
457
 
351
458
  /**
352
459
  * @notice Computes a confidential burn operation.
460
+ * If the burn operation fails (e.g., due to underflow), the success handle will
461
+ * contain an encrypted `false` and the newBalanceFrom and newTotalSupply handles will
462
+ * contain the same values as the input balanceFrom and totalSupply handles.
353
463
  * @param balanceFrom Sender's current balance handle
354
464
  * @param amount Amount handle to burn
355
465
  * @param totalSupply Current total supply handle
@@ -363,25 +473,27 @@ interface INoxCompute is IErrors {
363
473
  bytes32 totalSupply
364
474
  ) external returns (bytes32 success, bytes32 newBalanceFrom, bytes32 newTotalSupply);
365
475
 
366
- function validateProof(
367
- bytes32 handle,
368
- address owner,
369
- bytes calldata proof,
370
- TEEType teeType
371
- ) external;
476
+ // ------------- Admin functions -------------
372
477
 
373
- function domainSeparator() external view returns (bytes32);
374
- function ACL() external view returns (IACL);
375
- function gateway() external view returns (address);
376
- function proofExpirationDuration() external view returns (uint256);
377
- function kmsPublicKey() external view returns (bytes memory);
478
+ /**
479
+ * @notice Sets the KMS public key used for ECIES encryption.
480
+ * @param newKmsPublicKey The compressed SEC1 secp256k1 public key (33 bytes)
481
+ */
482
+ function setKmsPublicKey(bytes calldata newKmsPublicKey) external;
378
483
 
379
- /// @dev See {IACL-isAllowed}
380
- function isAllowed(bytes32 handle, address account) external view returns (bool);
484
+ /**
485
+ * @notice Sets the gateway address in the contract's config.
486
+ * @param gatewayAddress The address of the gateway
487
+ */
488
+ function setGateway(address gatewayAddress) external;
381
489
 
382
- /// @dev See {IACL-isViewer}
383
- function isViewer(bytes32 handle, address viewer) external view returns (bool);
490
+ /**
491
+ * @notice Sets the proof expiration duration.
492
+ * @param newDuration The new expiration duration in seconds
493
+ */
494
+ function setProofExpirationDuration(uint256 newDuration) external;
384
495
 
385
- /// @dev See {IACL-isPubliclyDecryptable}
386
- function isPubliclyDecryptable(bytes32 handle) external view returns (bool);
496
+ function kmsPublicKey() external view returns (bytes memory);
497
+ function gateway() external view returns (address);
498
+ function proofExpirationDuration() external view returns (uint256);
387
499
  }