@iexec-nox/nox-protocol-contracts 0.1.0-beta.4 → 0.1.0-beta.6

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);
@@ -97,6 +110,20 @@ interface INoxCompute is IErrors {
97
110
  bytes32 success,
98
111
  bytes32 result
99
112
  );
113
+ event SafeMul(
114
+ address indexed caller,
115
+ bytes32 leftHandOperand,
116
+ bytes32 rightHandOperand,
117
+ bytes32 success,
118
+ bytes32 result
119
+ );
120
+ event SafeDiv(
121
+ address indexed caller,
122
+ bytes32 numerator,
123
+ bytes32 denominator,
124
+ bytes32 success,
125
+ bytes32 result
126
+ );
100
127
  event Select(
101
128
  address indexed caller,
102
129
  bytes32 condition,
@@ -140,6 +167,8 @@ interface INoxCompute is IErrors {
140
167
  Div,
141
168
  SafeAdd,
142
169
  SafeSub,
170
+ SafeMul,
171
+ SafeDiv,
143
172
  Select,
144
173
  Eq,
145
174
  Ne,
@@ -152,19 +181,83 @@ interface INoxCompute is IErrors {
152
181
  Burn
153
182
  }
154
183
 
184
+ // ------------- ACL functions -------------
185
+
155
186
  /**
156
- * @notice Sets the KMS public key used for ECIES encryption
157
- * @param newKmsPublicKey The compressed SEC1 secp256k1 public key (33 bytes)
187
+ * Grant admin role to another address for a specific handle
188
+ * @dev Caller must have access (transient OR persistent) to the handle
189
+ * @param handle The handle identifier
190
+ * @param account The address to grant admin role
158
191
  */
159
- function setKmsPublicKey(bytes calldata newKmsPublicKey) external;
192
+ function allow(bytes32 handle, address account) external;
160
193
 
161
- function setGateway(address gatewayAddress) external;
194
+ /**
195
+ * Allows the use of `handle` by address `account` for this transaction.
196
+ * @param handle Handle.
197
+ * @param account Address of the account.
198
+ */
199
+ function allowTransient(bytes32 handle, address account) external;
162
200
 
163
201
  /**
164
- * @notice Sets the proof expiration duration
165
- * @param newDuration The new expiration duration in seconds
202
+ * Removes all transient authorizations. This is useful for integration with Account Abstraction
203
+ * when bundling several UserOps calling the NoxCompute.
204
+ * @dev Can be called by anyone (typically by AA bundlers between UserOps).
166
205
  */
167
- function setProofExpirationDuration(uint256 newDuration) external;
206
+ function cleanTransientStorage() external;
207
+
208
+ /**
209
+ * Returns whether the account is allowed to use the `handle`, either due to
210
+ * allowTransient() or allow().
211
+ * @param handle Handle.
212
+ * @param account Address of the account.
213
+ * @return Whether the account can access the handle (persistent or transient).
214
+ */
215
+ function isAllowed(bytes32 handle, address account) external view returns (bool);
216
+
217
+ /**
218
+ * Checks whether the account is allowed to use all provided handles.
219
+ * Reverts with NotAllowed if any handle is not allowed.
220
+ * @param account Address of the account.
221
+ * @param handles Array of handles to check.
222
+ */
223
+ function validateAllowedForAll(address account, bytes32[] calldata handles) external view;
224
+
225
+ /**
226
+ * Add a viewer for a specific handle
227
+ * @dev Only an admin can add a viewer. The viewer address cannot be address(0).
228
+ * @param handle The handle identifier
229
+ * @param viewer The address to grant viewer role
230
+ */
231
+ function addViewer(bytes32 handle, address viewer) external;
232
+
233
+ /**
234
+ * Returns whether the account can view the handle.
235
+ * @dev Returns true if any of the following conditions are met:
236
+ * - The handle is publicly decryptable
237
+ * - The account was added as a viewer via `addViewer`
238
+ * - The account has persistent access (is allowed) on the handle
239
+ * @param handle Handle.
240
+ * @param viewer Address of the viewer.
241
+ * @return Whether the account can view the handle.
242
+ */
243
+ function isViewer(bytes32 handle, address viewer) external view returns (bool);
244
+
245
+ /**
246
+ * Mark a handle as publicly decryptable.
247
+ * @dev The caller must be allowed to use the handle.
248
+ * If not, the function reverts.
249
+ * @param handle Handle to mark as publicly decryptable.
250
+ */
251
+ function allowPublicDecryption(bytes32 handle) external;
252
+
253
+ /**
254
+ * Checks whether a handle is publicly decryptable.
255
+ * @param handle Handle.
256
+ * @return Whether the handle is publicly decryptable.
257
+ */
258
+ function isPubliclyDecryptable(bytes32 handle) external view returns (bool);
259
+
260
+ // ------------- Compute functions -------------
168
261
 
169
262
  /**
170
263
  * @notice Converts a plaintext value into an encrypted value
@@ -175,7 +268,21 @@ interface INoxCompute is IErrors {
175
268
  function plaintextToEncrypted(bytes32 value, TEEType teeType) external returns (bytes32);
176
269
 
177
270
  /**
178
- * @notice Computes TEE Add operation
271
+ * @notice Validates a handle proof for a given owner and type.
272
+ * @param handle handle to validate
273
+ * @param owner owner of the provided handle
274
+ * @param proof proof data
275
+ * @param teeType expected handle type
276
+ */
277
+ function validateProof(
278
+ bytes32 handle,
279
+ address owner,
280
+ bytes calldata proof,
281
+ TEEType teeType
282
+ ) external;
283
+
284
+ /**
285
+ * @notice Performs an addition between two encrypted values without overflow check.
179
286
  * @param leftHandOperand Left-hand side operand handle
180
287
  * @param rightHandOperand Right-hand side operand handle
181
288
  * @return result Result handle
@@ -186,7 +293,7 @@ interface INoxCompute is IErrors {
186
293
  ) external returns (bytes32 result);
187
294
 
188
295
  /**
189
- * @notice Performs a subtraction between two encrypted values without safety checks.
296
+ * @notice Performs a subtraction between two encrypted values without underflow check.
190
297
  * @param leftHandOperand Left-hand side operand handle
191
298
  * @param rightHandOperand Right-hand side operand handle
192
299
  * @return result Result handle
@@ -197,7 +304,21 @@ interface INoxCompute is IErrors {
197
304
  ) external returns (bytes32 result);
198
305
 
199
306
  /**
200
- * @notice Performs a division between two encrypted values
307
+ * @notice Performs a multiplication between two encrypted values without overflow check.
308
+ * @param leftHandOperand Left-hand side operand handle
309
+ * @param rightHandOperand Right-hand side operand handle
310
+ * @return result Result handle
311
+ */
312
+ function mul(
313
+ bytes32 leftHandOperand,
314
+ bytes32 rightHandOperand
315
+ ) external returns (bytes32 result);
316
+
317
+ /**
318
+ * @notice Performs a division between two encrypted values without safety checks.
319
+ * In the case of a division by zero, the result will be as follows:
320
+ * - For unsigned integers uintN: encrypted MAX_UintN (i.e., 2^N - 1)
321
+ * - For signed integers intN: encrypted MAX_IntN (i.e., 2^(N-1) - 1)
201
322
  * @param numerator Value to be divided
202
323
  * @param denominator Value to divide by
203
324
  * @return result Result handle
@@ -205,15 +326,77 @@ interface INoxCompute is IErrors {
205
326
  function div(bytes32 numerator, bytes32 denominator) external returns (bytes32 result);
206
327
 
207
328
  /**
208
- * @notice Performs a multiplication between two encrypted values
329
+ * @notice Performs an addition between two encrypted values with overflow 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 sum.
332
+ * If the operation fails (e.g., due to overflow), 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 safeAdd(
340
+ bytes32 leftHandOperand,
341
+ bytes32 rightHandOperand
342
+ ) external returns (bytes32 success, bytes32 result);
343
+
344
+ /**
345
+ * @notice Performs a subtraction between two encrypted values with underflow check.
346
+ * If the operation succeeds, the value of the success handle will be an encrypted
347
+ * `true` and the result handle's value will be the encrypted difference.
348
+ * If the operation fails (e.g., due to underflow), the success handle will contain
349
+ * an encrypted `false` and the result handle will contain an encrypted `0`.
209
350
  * @param leftHandOperand Left-hand side operand handle
210
351
  * @param rightHandOperand Right-hand side operand handle
352
+ * @return success Whether the operation was successful
211
353
  * @return result Result handle
212
354
  */
213
- function mul(
355
+ function safeSub(
214
356
  bytes32 leftHandOperand,
215
357
  bytes32 rightHandOperand
216
- ) external returns (bytes32 result);
358
+ ) external returns (bytes32 success, bytes32 result);
359
+
360
+ /**
361
+ * @notice Performs a multiplication between two encrypted values with overflow check.
362
+ * If the operation succeeds, the value of the success handle will be an encrypted
363
+ * `true` and the result handle's value will be the encrypted product.
364
+ * If the operation fails (e.g., due to overflow), the success handle will contain
365
+ * an encrypted `false` and the result handle will contain an encrypted `0`.
366
+ * @param leftHandOperand Left-hand side operand handle
367
+ * @param rightHandOperand Right-hand side operand handle
368
+ * @return success Whether the operation was successful
369
+ * @return result Result handle
370
+ */
371
+ function safeMul(
372
+ bytes32 leftHandOperand,
373
+ bytes32 rightHandOperand
374
+ ) external returns (bytes32 success, bytes32 result);
375
+
376
+ /**
377
+ * @notice Performs a division between two encrypted values with division-by-zero check.
378
+ * If the operation succeeds, the value of the success handle will be an encrypted
379
+ * `true` and the result handle's value will be the encrypted quotient.
380
+ * If the operation fails (e.g., due to division by zero), the success handle will contain
381
+ * an encrypted `false` and the result handle will contain an encrypted `0`.
382
+ * @param numerator Value to be divided
383
+ * @param denominator Value to divide by
384
+ * @return success Whether the operation was successful
385
+ * @return result Result handle
386
+ */
387
+ function safeDiv(
388
+ bytes32 numerator,
389
+ bytes32 denominator
390
+ ) external returns (bytes32 success, bytes32 result);
391
+
392
+ /**
393
+ * @notice Selects between two encrypted values based on a condition
394
+ * @param condition Condition handle
395
+ * @param ifTrue Value handle if condition is true
396
+ * @param ifFalse Value handle if condition is false
397
+ * @return result Selected value handle
398
+ */
399
+ function select(bytes32 condition, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32);
217
400
 
218
401
  /**
219
402
  * @notice Checks equality between two encrypted values
@@ -281,45 +464,12 @@ interface INoxCompute is IErrors {
281
464
  bytes32 rightHandOperand
282
465
  ) external returns (bytes32 result);
283
466
 
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
467
  /**
322
468
  * @notice Computes a confidential transfer between two balances.
469
+ * The transfer will succeed if the sender has sufficient balance and fail otherwise.
470
+ * If the transfer fails, the success handle will contain an encrypted `false`, the
471
+ * newBalanceFrom and newBalanceTo handles will contain the same values as the input
472
+ * balanceFrom and balanceTo handles.
323
473
  * @param balanceFrom Sender's current balance handle
324
474
  * @param balanceTo Recipient's current balance handle
325
475
  * @param amount Amount handle to transfer
@@ -335,6 +485,9 @@ interface INoxCompute is IErrors {
335
485
 
336
486
  /**
337
487
  * @notice Computes a confidential mint operation.
488
+ * If the minting operation fails (e.g., due to overflow), the success handle will
489
+ * contain an encrypted `false` and the newBalanceTo and newTotalSupply handles will
490
+ * contain the same values as the input balanceTo and totalSupply handles.
338
491
  * @param balanceTo Recipient's current balance handle
339
492
  * @param amount Amount handle to mint
340
493
  * @param totalSupply Current total supply handle
@@ -350,6 +503,9 @@ interface INoxCompute is IErrors {
350
503
 
351
504
  /**
352
505
  * @notice Computes a confidential burn operation.
506
+ * If the burn operation fails (e.g., due to underflow), the success handle will
507
+ * contain an encrypted `false` and the newBalanceFrom and newTotalSupply handles will
508
+ * contain the same values as the input balanceFrom and totalSupply handles.
353
509
  * @param balanceFrom Sender's current balance handle
354
510
  * @param amount Amount handle to burn
355
511
  * @param totalSupply Current total supply handle
@@ -363,25 +519,27 @@ interface INoxCompute is IErrors {
363
519
  bytes32 totalSupply
364
520
  ) external returns (bytes32 success, bytes32 newBalanceFrom, bytes32 newTotalSupply);
365
521
 
366
- function validateProof(
367
- bytes32 handle,
368
- address owner,
369
- bytes calldata proof,
370
- TEEType teeType
371
- ) external;
522
+ // ------------- Admin functions -------------
372
523
 
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);
524
+ /**
525
+ * @notice Sets the KMS public key used for ECIES encryption.
526
+ * @param newKmsPublicKey The compressed SEC1 secp256k1 public key (33 bytes)
527
+ */
528
+ function setKmsPublicKey(bytes calldata newKmsPublicKey) external;
378
529
 
379
- /// @dev See {IACL-isAllowed}
380
- function isAllowed(bytes32 handle, address account) external view returns (bool);
530
+ /**
531
+ * @notice Sets the gateway address in the contract's config.
532
+ * @param gatewayAddress The address of the gateway
533
+ */
534
+ function setGateway(address gatewayAddress) external;
381
535
 
382
- /// @dev See {IACL-isViewer}
383
- function isViewer(bytes32 handle, address viewer) external view returns (bool);
536
+ /**
537
+ * @notice Sets the proof expiration duration.
538
+ * @param newDuration The new expiration duration in seconds
539
+ */
540
+ function setProofExpirationDuration(uint256 newDuration) external;
384
541
 
385
- /// @dev See {IACL-isPubliclyDecryptable}
386
- function isPubliclyDecryptable(bytes32 handle) external view returns (bool);
542
+ function kmsPublicKey() external view returns (bytes memory);
543
+ function gateway() external view returns (address);
544
+ function proofExpirationDuration() external view returns (uint256);
387
545
  }