@inco/lightning 0.8.0-devnet-13 → 0.8.0-devnet-20

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.
Files changed (52) hide show
  1. package/manifest.yaml +66 -0
  2. package/package.json +8 -8
  3. package/src/IncoLightning.sol +5 -0
  4. package/src/Lib.alphanet.sol +31 -35
  5. package/src/Lib.demonet.sol +31 -35
  6. package/src/Lib.devnet.sol +31 -35
  7. package/src/Lib.sol +31 -35
  8. package/src/Lib.template.sol +54 -35
  9. package/src/Lib.testnet.sol +31 -35
  10. package/src/Types.sol +18 -0
  11. package/src/interfaces/IIncoLightning.sol +2 -0
  12. package/src/libs/incoLightning_alphanet_v0_297966649.sol +31 -35
  13. package/src/libs/incoLightning_alphanet_v1_725458969.sol +31 -35
  14. package/src/libs/incoLightning_alphanet_v2_976644394.sol +31 -35
  15. package/src/libs/incoLightning_demonet_v0_863421733.sol +31 -35
  16. package/src/libs/incoLightning_demonet_v2_467437523.sol +31 -35
  17. package/src/libs/incoLightning_devnet_v0_340846814.sol +31 -35
  18. package/src/libs/incoLightning_devnet_v1_904635675.sol +31 -35
  19. package/src/libs/incoLightning_devnet_v2_295237520.sol +31 -35
  20. package/src/libs/incoLightning_devnet_v3_976859633.sol +31 -35
  21. package/src/libs/incoLightning_devnet_v4_409204766.sol +31 -35
  22. package/src/libs/incoLightning_devnet_v5_203964628.sol +31 -35
  23. package/src/libs/incoLightning_devnet_v6_281949651.sol +31 -35
  24. package/src/libs/incoLightning_devnet_v7_24560427.sol +1197 -0
  25. package/src/libs/incoLightning_devnet_v8_985328058.sol +1197 -0
  26. package/src/libs/incoLightning_devnet_v9_269218568.sol +1197 -0
  27. package/src/libs/incoLightning_testnet_v0_183408998.sol +31 -35
  28. package/src/libs/incoLightning_testnet_v2_889158349.sol +31 -35
  29. package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +4 -3
  30. package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +0 -16
  31. package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +1 -1
  32. package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +0 -1
  33. package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +3 -1
  34. package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +0 -43
  35. package/src/lightning-parts/DecryptionAttester.sol +2 -2
  36. package/src/lightning-parts/DecryptionAttester.types.sol +3 -3
  37. package/src/lightning-parts/EList.sol +105 -25
  38. package/src/lightning-parts/EncryptedOperations.sol +18 -8
  39. package/src/lightning-parts/Fee.sol +29 -0
  40. package/src/lightning-parts/interfaces/IDecryptionAttester.sol +2 -2
  41. package/src/lightning-parts/interfaces/IEList.sol +11 -8
  42. package/src/lightning-parts/interfaces/IEncryptedInput.sol +2 -2
  43. package/src/lightning-parts/test/Elist.t.sol +160 -9
  44. package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +41 -13
  45. package/src/periphery/IncoUtils.sol +1 -1
  46. package/src/test/EListTester.sol +31 -13
  47. package/src/test/FakeIncoInfra/FakeComputeServer.sol +2 -2
  48. package/src/test/TestDeploy.t.sol +45 -1
  49. package/src/test/TestFakeInfra.t.sol +32 -6
  50. package/src/test/TestLib.t.sol +840 -19
  51. package/src/test/TestReceive.t.sol +42 -0
  52. package/src/version/IncoLightningConfig.sol +1 -1
@@ -5,10 +5,12 @@ import {
5
5
  ETypes,
6
6
  EOps,
7
7
  typeToBitMask,
8
+ typeBitSize,
8
9
  isTypeSupported,
9
10
  IndexOutOfRange,
10
11
  InvalidRange,
11
12
  ListTypeMismatch,
13
+ ListTooLong,
12
14
  UnsupportedType,
13
15
  elist
14
16
  } from "../Types.sol";
@@ -17,6 +19,9 @@ import {EncryptedInput} from "./EncryptedInput.sol";
17
19
  import {EListHandleGeneration} from "./primitives/EListHandleGeneration.sol";
18
20
  import {IEList} from "./interfaces/IEList.sol";
19
21
 
22
+ /// @dev Maximum number of elements allowed in an encrypted list.
23
+ uint16 constant MAX_LIST_LENGTH = type(uint16).max;
24
+
20
25
  /// @title EList
21
26
  /// @notice Provides operations for encrypted lists (elist) - ordered collections of encrypted values.
22
27
  /// @dev Encrypted lists are immutable; all operations return new list handles rather than modifying in place.
@@ -45,6 +50,11 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
45
50
  event EListShuffle(elist indexed list, uint256 indexed counter, elist indexed result, uint256 eventId);
46
51
  event EListReverse(elist indexed list, elist indexed result, uint256 eventId);
47
52
 
53
+ /// @dev Returns the total bit size of an elist: length * typeBitSize(elementType).
54
+ function _elistBits(bytes32 handle) internal pure returns (uint256) {
55
+ return uint256(lengthOf(handle)) * typeBitSize(listTypeOf(handle));
56
+ }
57
+
48
58
  /// @notice Creates a new encrypted list from client-encrypted inputs.
49
59
  /// @dev Internal function that processes multiple encrypted inputs without individual payment.
50
60
  /// Payment should be handled by the caller for the batch.
@@ -56,6 +66,7 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
56
66
  internal
57
67
  returns (elist newList)
58
68
  {
69
+ require(inputs.length <= MAX_LIST_LENGTH, ListTooLong(uint32(inputs.length), MAX_LIST_LENGTH));
59
70
  require(isTypeSupported(listType), UnsupportedType(listType));
60
71
 
61
72
  // TODO: Add a new event to create new elist from inputs, can be done as an upgrade to optimize for gas and castore.
@@ -73,6 +84,7 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
73
84
  /// @param listType The type of elements in the list (must match handle types).
74
85
  /// @return newList The new encrypted list handle.
75
86
  function newEListFromHandles(bytes32[] memory handles, ETypes listType) internal returns (elist newList) {
87
+ require(handles.length <= MAX_LIST_LENGTH, ListTooLong(uint32(handles.length), MAX_LIST_LENGTH));
76
88
  require(isTypeSupported(listType), UnsupportedType(listType));
77
89
  for (uint256 i = 0; i < handles.length; i++) {
78
90
  checkInput(handles[i], typeToBitMask(listType));
@@ -81,9 +93,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
81
93
  bytes32 newHandle = createListInputHandle(handles, listType);
82
94
 
83
95
  allowTransientInternal(newHandle, msg.sender);
84
-
85
- emit NewEList(newHandle, listType, handles, getNewEventId());
86
-
96
+ uint256 id = getNextEventId();
97
+ setDigest(abi.encodePacked(newHandle, id));
98
+ emit NewEList(newHandle, listType, handles, id);
87
99
  return elist.wrap(newHandle);
88
100
  }
89
101
 
@@ -92,7 +104,12 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
92
104
  /// @param handles Array of encrypted value handles to include in the list.
93
105
  /// @param listType The type of elements in the list.
94
106
  /// @return newList The new encrypted list handle.
95
- function newEList(bytes32[] memory handles, ETypes listType) external returns (elist newList) {
107
+ function newEList(bytes32[] memory handles, ETypes listType)
108
+ external
109
+ payable
110
+ payingElistFee(uint256(handles.length) * typeBitSize(listType))
111
+ returns (elist newList)
112
+ {
96
113
  return newEListFromHandles(handles, listType);
97
114
  }
98
115
 
@@ -105,7 +122,7 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
105
122
  function newEList(bytes[] calldata inputs, ETypes listType, address user)
106
123
  external
107
124
  payable
108
- payingMultiple(inputs.length)
125
+ payingElistFee(uint256(inputs.length) * typeBitSize(listType))
109
126
  returns (elist newList)
110
127
  {
111
128
  return newEListFromInputs(inputs, listType, user);
@@ -124,7 +141,12 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
124
141
  /// @param list The encrypted list to append to.
125
142
  /// @param value The encrypted value to append (must match list element type).
126
143
  /// @return result A new encrypted list with the value appended.
127
- function listAppend(elist list, bytes32 value) external returns (elist result) {
144
+ function listAppend(elist list, bytes32 value)
145
+ external
146
+ payable
147
+ payingElistFee(_elistBits(elist.unwrap(list)) + typeBitSize(listTypeOf(elist.unwrap(list))))
148
+ returns (elist result)
149
+ {
128
150
  checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
129
151
  checkInput(value, typeToBitMask(listTypeOf(elist.unwrap(list))));
130
152
 
@@ -136,8 +158,10 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
136
158
  abi.encodePacked(elist.unwrap(list), value)
137
159
  )
138
160
  );
161
+ uint256 id = getNextEventId();
139
162
  allowTransientInternal(elist.unwrap(result), msg.sender);
140
- emit EListAppend(list, value, result, getNewEventId());
163
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
164
+ emit EListAppend(list, value, result, id);
141
165
  }
142
166
 
143
167
  /// @notice Retrieves an encrypted element at a specific index.
@@ -151,7 +175,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
151
175
 
152
176
  result =
153
177
  createResultHandle(EOps.EListGet, listTypeOf(elist.unwrap(list)), abi.encodePacked(elist.unwrap(list), i));
154
- emit EListGet(list, i, result, getNewEventId());
178
+ uint256 id = getNextEventId();
179
+ setDigest(abi.encodePacked(result, id));
180
+ emit EListGet(list, i, result, id);
155
181
  }
156
182
 
157
183
  /// @notice Retrieves an encrypted element at an encrypted index, with a default value for out-of-range access.
@@ -168,17 +194,27 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
168
194
  result = createResultHandle(
169
195
  EOps.EListGetOr, listTypeOf(elist.unwrap(list)), abi.encodePacked(elist.unwrap(list), index, defaultValue)
170
196
  );
171
- emit EListGetOr(list, index, defaultValue, result, getNewEventId());
197
+ uint256 id = getNextEventId();
198
+ setDigest(abi.encodePacked(result, id));
199
+ emit EListGetOr(list, index, defaultValue, result, id);
172
200
  }
173
201
 
174
202
  /// @notice Sets an encrypted element at an encrypted index.
175
203
  /// @dev Returns a new list with the element replaced; original list is unchanged.
176
- /// Index must be euint256. Out-of-range behavior is handled by the covalidator.
204
+ /// Index must be euint256. If the encrypted index is out of bounds, the operation
205
+ /// is silently ignored by the covalidator and the returned list is identical to the input.
206
+ /// This is by design: because the index is encrypted, reverting would leak information
207
+ /// about whether the index was valid.
177
208
  /// @param list The encrypted list to modify.
178
209
  /// @param index The encrypted index to set.
179
210
  /// @param value The new encrypted value (must match list element type).
180
- /// @return result A new encrypted list with the element replaced.
181
- function listSet(elist list, bytes32 index, bytes32 value) external returns (elist result) {
211
+ /// @return result A new encrypted list with the element replaced, or unchanged if index is out of bounds.
212
+ function listSet(elist list, bytes32 index, bytes32 value)
213
+ external
214
+ payable
215
+ payingElistFee(_elistBits(elist.unwrap(list)))
216
+ returns (elist result)
217
+ {
182
218
  checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
183
219
  checkInput(index, typeToBitMask(ETypes.Uint256)); //Currently we only support euint256 for index
184
220
  checkInput(value, typeToBitMask(listTypeOf(elist.unwrap(list))));
@@ -192,7 +228,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
192
228
  )
193
229
  );
194
230
  allowTransientInternal(elist.unwrap(result), msg.sender);
195
- emit EListSet(list, index, value, result, getNewEventId());
231
+ uint256 id = getNextEventId();
232
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
233
+ emit EListSet(list, index, value, result, id);
196
234
  }
197
235
 
198
236
  /// @notice Inserts an encrypted element at an encrypted index, shifting subsequent elements.
@@ -201,7 +239,12 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
201
239
  /// @param index The encrypted index at which to insert.
202
240
  /// @param value The encrypted value to insert (must match list element type).
203
241
  /// @return result A new encrypted list with the element inserted.
204
- function listInsert(elist list, bytes32 index, bytes32 value) external returns (elist result) {
242
+ function listInsert(elist list, bytes32 index, bytes32 value)
243
+ external
244
+ payable
245
+ payingElistFee(_elistBits(elist.unwrap(list)) + typeBitSize(listTypeOf(elist.unwrap(list))))
246
+ returns (elist result)
247
+ {
205
248
  checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
206
249
  checkInput(index, typeToBitMask(ETypes.Uint256)); //Currently we only support euint256 for index
207
250
  checkInput(value, typeToBitMask(listTypeOf(elist.unwrap(list))));
@@ -215,7 +258,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
215
258
  )
216
259
  );
217
260
  allowTransientInternal(elist.unwrap(result), msg.sender);
218
- emit EListInsert(list, index, value, result, getNewEventId());
261
+ uint256 id = getNextEventId();
262
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
263
+ emit EListInsert(list, index, value, result, id);
219
264
  }
220
265
 
221
266
  /// @notice Concatenates two encrypted lists into a new list.
@@ -223,7 +268,12 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
223
268
  /// @param lhs The first encrypted list.
224
269
  /// @param rhs The second encrypted list (must have same element type as lhs).
225
270
  /// @return result A new encrypted list containing all elements from both lists.
226
- function listConcat(elist lhs, elist rhs) external returns (elist result) {
271
+ function listConcat(elist lhs, elist rhs)
272
+ external
273
+ payable
274
+ payingElistFee(_elistBits(elist.unwrap(lhs)) + _elistBits(elist.unwrap(rhs)))
275
+ returns (elist result)
276
+ {
227
277
  checkInput(elist.unwrap(lhs), typeToBitMask(ETypes.List));
228
278
  checkInput(elist.unwrap(rhs), typeToBitMask(ETypes.List));
229
279
  ETypes lhsType = listTypeOf(elist.unwrap(lhs));
@@ -239,7 +289,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
239
289
  )
240
290
  );
241
291
  allowTransientInternal(elist.unwrap(result), msg.sender);
242
- emit EListConcat(lhs, rhs, result, getNewEventId());
292
+ uint256 id = getNextEventId();
293
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
294
+ emit EListConcat(lhs, rhs, result, id);
243
295
  }
244
296
 
245
297
  /// @notice Extracts a slice from an encrypted list starting at an encrypted index.
@@ -249,7 +301,12 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
249
301
  /// @param len The number of elements to include in the slice.
250
302
  /// @param defaultValue The encrypted value to use for out-of-range positions.
251
303
  /// @return result A new encrypted list containing the slice.
252
- function listSlice(elist list, bytes32 start, uint16 len, bytes32 defaultValue) external returns (elist result) {
304
+ function listSlice(elist list, bytes32 start, uint16 len, bytes32 defaultValue)
305
+ external
306
+ payable
307
+ payingElistFee(uint256(len) * typeBitSize(listTypeOf(elist.unwrap(list))))
308
+ returns (elist result)
309
+ {
253
310
  checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
254
311
  checkInput(defaultValue, typeToBitMask(listTypeOf(elist.unwrap(list))));
255
312
  checkInput(start, typeToBitMask(ETypes.Uint256));
@@ -263,7 +320,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
263
320
  )
264
321
  );
265
322
  allowTransientInternal(elist.unwrap(result), msg.sender);
266
- emit EListSlice(list, start, len, defaultValue, result, getNewEventId());
323
+ uint256 id = getNextEventId();
324
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
325
+ emit EListSlice(list, start, len, defaultValue, result, id);
267
326
  }
268
327
 
269
328
  /// @notice Creates an encrypted list containing a range of encrypted integers.
@@ -271,14 +330,21 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
271
330
  /// @param start The starting value (inclusive).
272
331
  /// @param end The ending value (exclusive). Must be >= start.
273
332
  /// @return result A new encrypted list containing the range [start, end).
274
- function listRange(uint16 start, uint16 end) external returns (elist result) {
333
+ function listRange(uint16 start, uint16 end)
334
+ external
335
+ payable
336
+ payingElistFee(uint256(end - start) * typeBitSize(ETypes.Uint256))
337
+ returns (elist result)
338
+ {
275
339
  require(start <= end, InvalidRange(start, end));
276
340
 
277
341
  result = elist.wrap(
278
342
  createListResultHandle(EOps.EListRange, ETypes.Uint256, end - start, abi.encodePacked(start, end))
279
343
  );
280
344
  allowTransientInternal(elist.unwrap(result), msg.sender);
281
- emit EListRange(start, end, result, getNewEventId());
345
+ uint256 id = getNextEventId();
346
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
347
+ emit EListRange(start, end, result, id);
282
348
  }
283
349
 
284
350
  /// @notice Randomly shuffles the elements of an encrypted list.
@@ -286,7 +352,12 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
286
352
  /// The shuffle is cryptographically secure, computed by the covalidator.
287
353
  /// @param list The encrypted list to shuffle.
288
354
  /// @return result A new encrypted list with elements in random order.
289
- function listShuffle(elist list) external payable paying returns (elist result) {
355
+ function listShuffle(elist list)
356
+ external
357
+ payable
358
+ payingElistFee(_elistBits(elist.unwrap(list)))
359
+ returns (elist result)
360
+ {
290
361
  checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
291
362
  randCounter++;
292
363
  result = elist.wrap(
@@ -298,14 +369,21 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
298
369
  )
299
370
  );
300
371
  allowTransientInternal(elist.unwrap(result), msg.sender);
301
- emit EListShuffle(list, randCounter, result, getNewEventId());
372
+ uint256 id = getNextEventId();
373
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
374
+ emit EListShuffle(list, randCounter, result, id);
302
375
  }
303
376
 
304
377
  /// @notice Reverses the order of elements in an encrypted list.
305
378
  /// @dev Returns a new list with elements in reverse order; original list is unchanged.
306
379
  /// @param list The encrypted list to reverse.
307
380
  /// @return result A new encrypted list with elements in reverse order.
308
- function listReverse(elist list) external returns (elist result) {
381
+ function listReverse(elist list)
382
+ external
383
+ payable
384
+ payingElistFee(_elistBits(elist.unwrap(list)))
385
+ returns (elist result)
386
+ {
309
387
  checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
310
388
 
311
389
  result = elist.wrap(
@@ -317,7 +395,9 @@ abstract contract EList is IEList, EncryptedOperations, EncryptedInput, EListHan
317
395
  )
318
396
  );
319
397
  allowTransientInternal(elist.unwrap(result), msg.sender);
320
- emit EListReverse(list, result, getNewEventId());
398
+ uint256 id = getNextEventId();
399
+ setDigest(abi.encodePacked(elist.unwrap(result), id));
400
+ emit EListReverse(list, result, id);
321
401
  }
322
402
 
323
403
  }
@@ -1,7 +1,16 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
- import {euint256, ebool, EOps, SenderNotAllowedForHandle, ETypes, isTypeSupported, typeToBitMask} from "../Types.sol";
4
+ import {
5
+ euint256,
6
+ ebool,
7
+ EOps,
8
+ SenderNotAllowedForHandle,
9
+ ETypes,
10
+ isTypeSupported,
11
+ canCastTo,
12
+ typeToBitMask
13
+ } from "../Types.sol";
5
14
  import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
6
15
  import {HandleGeneration} from "./primitives/HandleGeneration.sol";
7
16
  import {IEncryptedOperations} from "./interfaces/IEncryptedOperations.sol";
@@ -135,7 +144,7 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
135
144
  }
136
145
 
137
146
  /// @notice Divides one encrypted uint256 by another.
138
- /// @dev Division by zero returns zero.
147
+ /// @dev Division by zero returns encrypted type(uint256).max.
139
148
  /// @param lhs The dividend (encrypted).
140
149
  /// @param rhs The divisor (encrypted).
141
150
  /// @return result The encrypted quotient (lhs / rhs).
@@ -149,7 +158,7 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
149
158
  }
150
159
 
151
160
  /// @notice Computes the remainder of dividing one encrypted uint256 by another.
152
- /// @dev Remainder by zero returns zero.
161
+ /// @dev Remainder by zero returns the encrypted dividend (lhs).
153
162
  /// @param lhs The dividend (encrypted).
154
163
  /// @param rhs The divisor (encrypted).
155
164
  /// @return result The encrypted remainder (lhs % rhs).
@@ -382,13 +391,13 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
382
391
  }
383
392
 
384
393
  /// @notice Casts an encrypted value to a different encrypted type.
385
- /// @dev Supports casting between euint256, ebool, and eaddress.
394
+ /// @dev Supports casting to euint256 and eaddress. Casting to ebool is not supported, only from ebool to a larger type.
386
395
  /// @param ct The encrypted value to cast.
387
396
  /// @param toType The target type to cast to.
388
397
  /// @return result The casted encrypted value.
389
398
  function eCast(bytes32 ct, ETypes toType) external returns (bytes32 result) {
390
399
  checkInput(ct, SUPPORTED_TYPES_MASK);
391
- require(isTypeSupported(toType), UnsupportedType(toType));
400
+ require(canCastTo(toType), UnsupportedType(toType));
392
401
  result = createResultHandle(EOps.Cast, toType, abi.encodePacked(ct));
393
402
  allowTransientInternal(result, msg.sender);
394
403
  uint256 id = getNextEventId();
@@ -411,12 +420,13 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
411
420
 
412
421
  /// @notice Generates an encrypted random value bounded by an upper limit.
413
422
  /// @dev This is a paid operation. The result is in the range [0, upperBound).
414
- /// @param upperBound The encrypted upper bound (exclusive).
415
- /// @param randType The type of random value to generate.
423
+ /// @param upperBound The encrypted upper bound (exclusive). If the upper bound is e(0), the whole bit width of randType is sampled.
424
+ /// @param randType The type of random value to generate. If upperBound is larger than the maximum value of randType, the function will revert.
416
425
  /// @return result An encrypted random value less than upperBound.
417
426
  function eRandBounded(bytes32 upperBound, ETypes randType) external payable paying returns (bytes32 result) {
418
427
  require(isTypeSupported(randType), UnsupportedType(randType));
419
- checkInput(upperBound, typeToBitMask(ETypes.Uint256));
428
+ require(typeOf(upperBound) <= randType, UnexpectedType(typeOf(upperBound), typeToBitMask(randType)));
429
+ checkInput(upperBound, SUPPORTED_TYPES_MASK);
420
430
  randCounter++;
421
431
  result = createResultHandle(EOps.RandBounded, randType, abi.encodePacked(bytes32(randCounter), upperBound));
422
432
  uint256 id = getNextEventId();
@@ -1,11 +1,15 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
+ import {ETypes, typeBitSize} from "../Types.sol";
5
+
4
6
  /// @dev The current fee required for paid encryption operations.
5
7
  /// This constant may be modified through contract upgrades.
6
8
  /// Developers should call getFee() rather than hardcoding this value.
7
9
  uint256 constant FEE = 0.000001 ether;
8
10
 
11
+ uint256 constant BIT_FEE = FEE / 256;
12
+
9
13
  /// @title Fee
10
14
  /// @notice Fee management utilities for encryption operations that require payment
11
15
  /// @dev Certain operations (encrypted inputs, randomness) require a fee to cover covalidator costs.
@@ -48,6 +52,31 @@ abstract contract Fee {
48
52
  _;
49
53
  }
50
54
 
55
+ /// @notice Modifier that requires payment proportional to elist bit size
56
+ /// @dev Fee = totalBits * BIT_FEE. totalBits is the sum of bit sizes across all elist inputs and outputs.
57
+ /// @param totalBits The total elist bit count for the operation
58
+ modifier payingElistFee(uint256 totalBits) {
59
+ require(msg.value == totalBits * BIT_FEE, FeeNotPaid());
60
+ _;
61
+ }
62
+
63
+ /// @notice Returns the per-bit fee for elist operations
64
+ /// @dev The fee may change through contract upgrades. Always query this function
65
+ /// to get the current fee rather than caching the value.
66
+ /// @return The per-bit fee amount in wei
67
+ function getBitFee() public pure returns (uint256) {
68
+ return BIT_FEE;
69
+ }
70
+
71
+ /// @notice Returns the fee for an elist operation given element count and type
72
+ /// @dev Fee = BIT_FEE * nOfElements * typeBitSize(elType)
73
+ /// @param nOfElements The number of elements in the resulting list
74
+ /// @param elType The element type of the list
75
+ /// @return The fee amount in wei
76
+ function getEListFee(uint16 nOfElements, ETypes elType) public pure returns (uint256) {
77
+ return BIT_FEE * uint256(nOfElements) * typeBitSize(elType);
78
+ }
79
+
51
80
  /// @notice Withdraws all accumulated fees to the specified recipient
52
81
  /// @dev Internal function called by IncoLightning.withdrawFees(). Transfers the entire
53
82
  /// contract balance to the recipient.
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
- import {DecryptionAttestation, ElementDecryptionProof} from "../DecryptionAttester.types.sol";
4
+ import {DecryptionAttestation, ElementAttestationWithProof} from "../DecryptionAttester.types.sol";
5
5
 
6
6
  interface IDecryptionAttester {
7
7
 
@@ -12,7 +12,7 @@ interface IDecryptionAttester {
12
12
  returns (bool);
13
13
  function isValidEListDecryptionAttestation(
14
14
  bytes32 elistHandle,
15
- ElementDecryptionProof[] memory proofElements,
15
+ ElementAttestationWithProof[] memory proofElements,
16
16
  bytes32 proof,
17
17
  bytes[] memory signatures
18
18
  ) external view returns (bool);
@@ -8,28 +8,31 @@ import {IEncryptedInput} from "./IEncryptedInput.sol";
8
8
 
9
9
  interface IEList is IEncryptedOperations, IEncryptedInput, IEListHandleMetadata {
10
10
 
11
- function newEList(bytes32[] memory handles, ETypes listType) external returns (elist newList);
11
+ function newEList(bytes32[] memory handles, ETypes listType) external payable returns (elist newList);
12
12
 
13
13
  function newEList(bytes[] calldata inputs, ETypes listType, address user) external payable returns (elist newList);
14
14
 
15
- function listAppend(elist list, bytes32 value) external returns (elist result);
15
+ function listAppend(elist list, bytes32 value) external payable returns (elist result);
16
16
 
17
17
  function listGet(elist list, uint16 i) external returns (bytes32 result);
18
18
 
19
19
  function listGetOr(elist list, bytes32 i, bytes32 defaultValue) external returns (bytes32 result);
20
20
 
21
- function listSet(elist list, bytes32 i, bytes32 value) external returns (elist result);
21
+ function listSet(elist list, bytes32 i, bytes32 value) external payable returns (elist result);
22
22
 
23
- function listInsert(elist list, bytes32 i, bytes32 value) external returns (elist result);
23
+ function listInsert(elist list, bytes32 i, bytes32 value) external payable returns (elist result);
24
24
 
25
- function listConcat(elist lhs, elist rhs) external returns (elist result);
25
+ function listConcat(elist lhs, elist rhs) external payable returns (elist result);
26
26
 
27
- function listSlice(elist list, bytes32 start, uint16 len, bytes32 defaultValue) external returns (elist result);
27
+ function listSlice(elist list, bytes32 start, uint16 len, bytes32 defaultValue)
28
+ external
29
+ payable
30
+ returns (elist result);
28
31
 
29
- function listRange(uint16 start, uint16 end) external returns (elist result);
32
+ function listRange(uint16 start, uint16 end) external payable returns (elist result);
30
33
 
31
34
  function listShuffle(elist list) external payable returns (elist result);
32
35
 
33
- function listReverse(elist list) external returns (elist result);
36
+ function listReverse(elist list) external payable returns (elist result);
34
37
 
35
38
  }
@@ -10,8 +10,8 @@ interface IEncryptedInput is IBaseAccessControlList, IHandleGeneration {
10
10
  error InvalidInputVersion(uint16 version);
11
11
  error InputLengthTooShort(uint256 length);
12
12
 
13
- event VersionAccepted(uint16 version);
14
- event VersionRemoved(uint16 version);
13
+ event VersionAccepted(uint16 indexed version);
14
+ event VersionRemoved(uint16 indexed version);
15
15
 
16
16
  function newEuint256(bytes calldata ciphertext, address user) external payable returns (euint256 newValue);
17
17
  function newEbool(bytes calldata ciphertext, address user) external payable returns (ebool newValue);