@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
@@ -14,10 +14,10 @@ import {
14
14
  SliceOutOfRange,
15
15
  UnsupportedListType
16
16
  } from "./Types.sol";
17
- import {DecryptionAttestation, ElementDecryptionProof} from "./lightning-parts/DecryptionAttester.types.sol";
17
+ import {DecryptionAttestation, ElementAttestationWithProof} from "./lightning-parts/DecryptionAttester.types.sol";
18
18
 
19
19
  // forge-lint: disable-next-line(screaming-snake-case-const)
20
- IncoLightning constant inco = IncoLightning(0x000000000000000000000000000000000000baBe);
20
+ IncoLightning constant inco = IncoLightning(payable(0x000000000000000000000000000000000000baBe));
21
21
  // forge-lint: disable-next-line(screaming-snake-case-const)
22
22
  address constant deployedBy = 0x000000000000000000000000000000000000baBe;
23
23
 
@@ -700,7 +700,7 @@ library e {
700
700
 
701
701
  /// @notice Generates a random encrypted uint256 less than a plaintext upper bound (costs the inco fee)
702
702
  /// @dev costs the inco fee
703
- /// @param upperBound The plaintext upper bound
703
+ /// @param upperBound The plaintext upper bound (exclusive). If the upper bound is 0, the whole 256bit range is sampled, equivalent to providing type(uint256).max as upper bound.
704
704
  /// @return The encrypted random value
705
705
  function randBounded(uint256 upperBound) internal returns (euint256) {
706
706
  bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
@@ -711,7 +711,7 @@ library e {
711
711
 
712
712
  /// @notice Generates a random encrypted uint256 less than an encrypted upper bound (costs the inco fee)
713
713
  /// @dev costs the inco fee
714
- /// @param upperBound The encrypted upper bound
714
+ /// @param upperBound The encrypted upper bound (exclusive). If the upper bound is e(0), the whole 256bit range is sampled, equivalent to providing e(type(uint256).max) as upper bound.
715
715
  /// @return The encrypted random value
716
716
  function randBounded(euint256 upperBound) internal returns (euint256) {
717
717
  bytes32 boundHandle = euint256.unwrap(s(upperBound));
@@ -741,13 +741,6 @@ library e {
741
741
  return inco.asEaddress(a);
742
742
  }
743
743
 
744
- /// @notice Casts an encrypted uint256 to an encrypted bool
745
- /// @param a The encrypted uint256 value
746
- /// @return The encrypted bool value
747
- function asEbool(euint256 a) internal returns (ebool) {
748
- return ebool.wrap(inco.eCast(euint256.unwrap(a), ETypes.Bool));
749
- }
750
-
751
744
  /// @notice Casts an encrypted bool to an encrypted uint256
752
745
  /// @param a The encrypted bool value
753
746
  /// @return The encrypted uint256 value
@@ -978,7 +971,7 @@ library e {
978
971
  /// @param listType Type of each element in the list.
979
972
  /// @return ret A new elist handle
980
973
  function newEList(bytes32[] memory handles, ETypes listType) internal returns (elist ret) {
981
- return inco.newEList(handles, listType);
974
+ return inco.newEList{value: inco.getEListFee(uint16(handles.length), listType)}(handles, listType);
982
975
  }
983
976
 
984
977
  /// @notice Takes an array of user encrypted ciphertexts and returns a new elist handle.
@@ -988,7 +981,7 @@ library e {
988
981
  /// @return ret A new elist handle
989
982
  /// @dev each ciphertext costs the inco fee
990
983
  function newEList(bytes[] memory ciphertexts, ETypes listType, address user) internal returns (elist ret) {
991
- return inco.newEList{value: inco.getFee() * ciphertexts.length}(ciphertexts, listType, user);
984
+ return inco.newEList{value: inco.getEListFee(uint16(ciphertexts.length), listType)}(ciphertexts, listType, user);
992
985
  }
993
986
 
994
987
  /// @notice Appends an ebool element at the end of a list.
@@ -996,7 +989,7 @@ library e {
996
989
  /// @param b Element value to be appended.
997
990
  /// @return ret A new elist handle with length len(a)+1.
998
991
  function append(elist a, ebool b) internal returns (elist ret) {
999
- return inco.listAppend(a, ebool.unwrap(s(b)));
992
+ return inco.listAppend{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, ebool.unwrap(s(b)));
1000
993
  }
1001
994
 
1002
995
  /// @notice Appends an euint256 element at the end of a list.
@@ -1004,25 +997,34 @@ library e {
1004
997
  /// @param b Element value to be appended.
1005
998
  /// @return ret A new elist handle with length len(a)+1.
1006
999
  function append(elist a, euint256 b) internal returns (elist ret) {
1007
- return inco.listAppend(a, euint256.unwrap(s(b)));
1000
+ return inco.listAppend{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(s(b)));
1008
1001
  }
1009
1002
 
1010
1003
  /// @notice Replaces an element at some hidden index "i" (ebool variant).
1004
+ /// @dev If the encrypted index is out of bounds, the operation is silently ignored
1005
+ /// and the returned list is identical to the input. This avoids leaking index validity.
1011
1006
  /// @param a EList handle to modify element in.
1012
1007
  /// @param i Hidden index position of an element to modify.
1013
1008
  /// @param b Element value to be changed.
1014
1009
  /// @return ret A new elist handle
1015
1010
  function set(elist a, euint256 i, ebool b) internal returns (elist ret) {
1016
- return inco.listSet(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
1011
+ return
1012
+ inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1013
+ a, euint256.unwrap(s(i)), ebool.unwrap(s(b))
1014
+ );
1017
1015
  }
1018
1016
 
1019
1017
  /// @notice Replaces an element at some hidden index "i" (euint256 variant).
1018
+ /// @dev If the encrypted index is out of bounds, the operation is silently ignored
1019
+ /// and the returned list is identical to the input. This avoids leaking index validity.
1020
1020
  /// @param a EList handle to modify element in.
1021
1021
  /// @param i Hidden index position of an element to modify.
1022
1022
  /// @param b Element value to be changed.
1023
1023
  /// @return ret A new elist handle
1024
1024
  function set(elist a, euint256 i, euint256 b) internal returns (elist ret) {
1025
- return inco.listSet(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
1025
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1026
+ a, euint256.unwrap(s(i)), euint256.unwrap(s(b))
1027
+ );
1026
1028
  }
1027
1029
 
1028
1030
  /// @notice Replaces an element at plaintext index "i" (ebool variant). Reverts if out of range.
@@ -1032,7 +1034,9 @@ library e {
1032
1034
  /// @return ret A new elist handle
1033
1035
  function set(elist a, uint16 i, ebool b) internal returns (elist ret) {
1034
1036
  require(i < length(a), IndexOutOfRange(i, length(a)));
1035
- return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
1037
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1038
+ a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b))
1039
+ );
1036
1040
  }
1037
1041
 
1038
1042
  /// @notice Replaces an element at plaintext index "i" (euint256 variant). Reverts if out of range.
@@ -1042,7 +1046,9 @@ library e {
1042
1046
  /// @return ret A new elist handle
1043
1047
  function set(elist a, uint16 i, euint256 b) internal returns (elist ret) {
1044
1048
  require(i < length(a), IndexOutOfRange(i, length(a)));
1045
- return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
1049
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(
1050
+ a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b))
1051
+ );
1046
1052
  }
1047
1053
 
1048
1054
  /// @notice Return hidden element at some hidden position (ebool variant).
@@ -1085,7 +1091,9 @@ library e {
1085
1091
  /// @param b Element value to be inserted.
1086
1092
  /// @return ret A new elist handle with length len(a)+1.
1087
1093
  function insert(elist a, euint256 i, ebool b) internal returns (elist ret) {
1088
- return inco.listInsert(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
1094
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1095
+ a, euint256.unwrap(s(i)), ebool.unwrap(s(b))
1096
+ );
1089
1097
  }
1090
1098
 
1091
1099
  /// @notice Inserts an ebool element at a known position. Reverts if out of range.
@@ -1095,7 +1103,9 @@ library e {
1095
1103
  /// @return ret A new elist handle with length len(a)+1.
1096
1104
  function insert(elist a, uint16 i, ebool b) internal returns (elist ret) {
1097
1105
  require(i < length(a), IndexOutOfRange(i, length(a)));
1098
- return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
1106
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1107
+ a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b))
1108
+ );
1099
1109
  }
1100
1110
 
1101
1111
  /// @notice Inserts a hidden element at a desired hidden position (euint256, hidden index).
@@ -1104,7 +1114,9 @@ library e {
1104
1114
  /// @param b Element value to be inserted.
1105
1115
  /// @return ret A new elist handle with length len(a)+1.
1106
1116
  function insert(elist a, euint256 i, euint256 b) internal returns (elist ret) {
1107
- return inco.listInsert(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
1117
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1118
+ a, euint256.unwrap(s(i)), euint256.unwrap(s(b))
1119
+ );
1108
1120
  }
1109
1121
 
1110
1122
  /// @notice Inserts a euint256 element at a known position. Reverts if out of range.
@@ -1114,7 +1126,9 @@ library e {
1114
1126
  /// @return ret A new elist handle with length len(a)+1.
1115
1127
  function insert(elist a, uint16 i, euint256 b) internal returns (elist ret) {
1116
1128
  require(i < length(a), IndexOutOfRange(i, length(a)));
1117
- return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
1129
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(
1130
+ a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b))
1131
+ );
1118
1132
  }
1119
1133
 
1120
1134
  /// @notice Concatenates two elists into one.
@@ -1122,7 +1136,7 @@ library e {
1122
1136
  /// @param b EList handle to be appended
1123
1137
  /// @return ret A new elist handle with length len(a)+len(b).
1124
1138
  function concat(elist a, elist b) internal returns (elist ret) {
1125
- return inco.listConcat(a, b);
1139
+ return inco.listConcat{value: inco.getEListFee(length(a) + length(b), listTypeOf(a))}(a, b);
1126
1140
  }
1127
1141
 
1128
1142
  /// @notice Slices a list from plaintext start to plaintext end.
@@ -1142,7 +1156,9 @@ library e {
1142
1156
  } else {
1143
1157
  revert UnsupportedListType(listTypeOf(a));
1144
1158
  }
1145
- return inco.listSlice(a, euint256.unwrap(asEuint256(start)), end - start, defaultValue);
1159
+ return inco.listSlice{value: inco.getEListFee(end - start, listTypeOf(a))}(
1160
+ a, euint256.unwrap(asEuint256(start)), end - start, defaultValue
1161
+ );
1146
1162
  }
1147
1163
 
1148
1164
  /// @notice Slices at a hidden index with a specified length (euint256 default).
@@ -1152,7 +1168,9 @@ library e {
1152
1168
  /// @param defaultValue Default value if out of range.
1153
1169
  /// @return ret A new sliced list with length "len".
1154
1170
  function sliceLen(elist a, euint256 start, uint16 len, euint256 defaultValue) internal returns (elist ret) {
1155
- return inco.listSlice(a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue)));
1171
+ return inco.listSlice{value: inco.getEListFee(len, listTypeOf(a))}(
1172
+ a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue))
1173
+ );
1156
1174
  }
1157
1175
 
1158
1176
  /// @notice Slices at a hidden index with a specified length (ebool default).
@@ -1162,7 +1180,9 @@ library e {
1162
1180
  /// @param defaultValue Default value if out of range.
1163
1181
  /// @return ret A new sliced list with length "len".
1164
1182
  function sliceLen(elist a, euint256 start, uint16 len, ebool defaultValue) internal returns (elist ret) {
1165
- return inco.listSlice(a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue)));
1183
+ return inco.listSlice{value: inco.getEListFee(len, listTypeOf(a))}(
1184
+ a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue))
1185
+ );
1166
1186
  }
1167
1187
 
1168
1188
  /// @notice Creates a new list populated with ordered values from within range.
@@ -1170,7 +1190,7 @@ library e {
1170
1190
  /// @param end End of the range, exclusive. Must be >= start.
1171
1191
  /// @return ret A new elist handle with length "end-start"
1172
1192
  function range(uint16 start, uint16 end) internal returns (elist ret) {
1173
- return inco.listRange(start, end);
1193
+ return inco.listRange{value: inco.getEListFee(end - start, ETypes.Uint256)}(start, end);
1174
1194
  }
1175
1195
 
1176
1196
  /// @notice Deterministically shuffles elements within a list.
@@ -1178,8 +1198,7 @@ library e {
1178
1198
  /// @param a elist handle to be shuffled
1179
1199
  /// @return ret A new elist handle with elements shuffled
1180
1200
  function shuffle(elist a) internal returns (elist ret) {
1181
- bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, a));
1182
- return elist.wrap(result);
1201
+ return inco.listShuffle{value: inco.getEListFee(length(a), listTypeOf(a))}(a);
1183
1202
  }
1184
1203
 
1185
1204
  /// @notice A convenience function equivalent to range() followed by shuffle().
@@ -1188,16 +1207,16 @@ library e {
1188
1207
  /// @param end End of the range, exclusive. Must be >= start.
1189
1208
  /// @return ret A new elist handle in random order with length "end-start".
1190
1209
  function shuffledRange(uint16 start, uint16 end) internal returns (elist ret) {
1191
- elist rangeList = inco.listRange(start, end);
1192
- bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, rangeList));
1193
- return elist.wrap(result);
1210
+ uint256 fee = inco.getEListFee(end - start, ETypes.Uint256);
1211
+ elist rangeList = inco.listRange{value: fee}(start, end);
1212
+ return inco.listShuffle{value: fee}(rangeList);
1194
1213
  }
1195
1214
 
1196
1215
  /// @notice Reverses the order of elements in a list.
1197
1216
  /// @param a Elist handle to be reversed
1198
1217
  /// @return ret A new elist handle with elements in reverse order
1199
1218
  function reverse(elist a) internal returns (elist ret) {
1200
- return inco.listReverse(a);
1219
+ return inco.listReverse{value: inco.getEListFee(length(a), listTypeOf(a))}(a);
1201
1220
  }
1202
1221
 
1203
1222
  /// @notice Returns the length of the list in plaintext. Pure function, no gas cost.
@@ -1218,7 +1237,7 @@ library e {
1218
1237
  */
1219
1238
  function verifyEListDecryption(
1220
1239
  elist elistHandle,
1221
- ElementDecryptionProof[] memory proofElements,
1240
+ ElementAttestationWithProof[] memory proofElements,
1222
1241
  bytes32 proof,
1223
1242
  bytes[] memory signatures
1224
1243
  ) internal view returns (bool) {
@@ -7,9 +7,9 @@ pragma solidity ^0.8;
7
7
 
8
8
  import { IncoLightning } from "./IncoLightning.sol";
9
9
  import { ebool, euint256, eaddress, ETypes, elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType } from "./Types.sol";
10
- import { DecryptionAttestation, ElementDecryptionProof } from "./lightning-parts/DecryptionAttester.types.sol";
10
+ import { DecryptionAttestation, ElementAttestationWithProof } from "./lightning-parts/DecryptionAttester.types.sol";
11
11
 
12
- IncoLightning constant inco = IncoLightning(0x168FDc3Ae19A5d5b03614578C58974FF30FCBe92);
12
+ IncoLightning constant inco = IncoLightning(payable(0x168FDc3Ae19A5d5b03614578C58974FF30FCBe92));
13
13
  address constant deployedBy = 0x8202D2D747784Cb7D48868E44C42C4bf162a70BC;
14
14
 
15
15
  /// @notice Returns the ETypes enum value encoded in a handle
@@ -693,7 +693,7 @@ library e {
693
693
 
694
694
  /// @notice Generates a random encrypted uint256 less than a plaintext upper bound (costs the inco fee)
695
695
  /// @dev costs the inco fee
696
- /// @param upperBound The plaintext upper bound
696
+ /// @param upperBound The plaintext upper bound (exclusive). If the upper bound is 0, the whole 256bit range is sampled, equivalent to providing type(uint256).max as upper bound.
697
697
  /// @return The encrypted random value
698
698
  function randBounded(uint256 upperBound) internal returns (euint256) {
699
699
  bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
@@ -703,7 +703,7 @@ library e {
703
703
 
704
704
  /// @notice Generates a random encrypted uint256 less than an encrypted upper bound (costs the inco fee)
705
705
  /// @dev costs the inco fee
706
- /// @param upperBound The encrypted upper bound
706
+ /// @param upperBound The encrypted upper bound (exclusive). If the upper bound is e(0), the whole 256bit range is sampled, equivalent to providing e(type(uint256).max) as upper bound.
707
707
  /// @return The encrypted random value
708
708
  function randBounded(euint256 upperBound) internal returns (euint256) {
709
709
  bytes32 boundHandle = euint256.unwrap(s(upperBound));
@@ -732,13 +732,6 @@ library e {
732
732
  return inco.asEaddress(a);
733
733
  }
734
734
 
735
- /// @notice Casts an encrypted uint256 to an encrypted bool
736
- /// @param a The encrypted uint256 value
737
- /// @return The encrypted bool value
738
- function asEbool(euint256 a) internal returns (ebool) {
739
- return ebool.wrap(inco.eCast(euint256.unwrap(a), ETypes.Bool));
740
- }
741
-
742
735
  /// @notice Casts an encrypted bool to an encrypted uint256
743
736
  /// @param a The encrypted bool value
744
737
  /// @return The encrypted uint256 value
@@ -959,7 +952,7 @@ library e {
959
952
  /// @param listType Type of each element in the list.
960
953
  /// @return ret A new elist handle
961
954
  function newEList(bytes32[] memory handles, ETypes listType) internal returns (elist ret) {
962
- return inco.newEList(handles, listType);
955
+ return inco.newEList{value: inco.getEListFee(uint16(handles.length), listType)}(handles, listType);
963
956
  }
964
957
 
965
958
  /// @notice Takes an array of user encrypted ciphertexts and returns a new elist handle.
@@ -969,7 +962,7 @@ library e {
969
962
  /// @return ret A new elist handle
970
963
  /// @dev each ciphertext costs the inco fee
971
964
  function newEList(bytes[] memory ciphertexts, ETypes listType, address user) internal returns (elist ret) {
972
- return inco.newEList{value: inco.getFee() * ciphertexts.length}(ciphertexts, listType, user);
965
+ return inco.newEList{value: inco.getEListFee(uint16(ciphertexts.length), listType)}(ciphertexts, listType, user);
973
966
  }
974
967
 
975
968
  /// @notice Appends an ebool element at the end of a list.
@@ -977,7 +970,7 @@ library e {
977
970
  /// @param b Element value to be appended.
978
971
  /// @return ret A new elist handle with length len(a)+1.
979
972
  function append(elist a, ebool b) internal returns (elist ret) {
980
- return inco.listAppend(a, ebool.unwrap(s(b)));
973
+ return inco.listAppend{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, ebool.unwrap(s(b)));
981
974
  }
982
975
 
983
976
  /// @notice Appends an euint256 element at the end of a list.
@@ -985,25 +978,29 @@ library e {
985
978
  /// @param b Element value to be appended.
986
979
  /// @return ret A new elist handle with length len(a)+1.
987
980
  function append(elist a, euint256 b) internal returns (elist ret) {
988
- return inco.listAppend(a, euint256.unwrap(s(b)));
981
+ return inco.listAppend{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(s(b)));
989
982
  }
990
983
 
991
984
  /// @notice Replaces an element at some hidden index "i" (ebool variant).
985
+ /// @dev If the encrypted index is out of bounds, the operation is silently ignored
986
+ /// and the returned list is identical to the input. This avoids leaking index validity.
992
987
  /// @param a EList handle to modify element in.
993
988
  /// @param i Hidden index position of an element to modify.
994
989
  /// @param b Element value to be changed.
995
990
  /// @return ret A new elist handle
996
991
  function set(elist a, euint256 i, ebool b) internal returns (elist ret) {
997
- return inco.listSet(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
992
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
998
993
  }
999
994
 
1000
995
  /// @notice Replaces an element at some hidden index "i" (euint256 variant).
996
+ /// @dev If the encrypted index is out of bounds, the operation is silently ignored
997
+ /// and the returned list is identical to the input. This avoids leaking index validity.
1001
998
  /// @param a EList handle to modify element in.
1002
999
  /// @param i Hidden index position of an element to modify.
1003
1000
  /// @param b Element value to be changed.
1004
1001
  /// @return ret A new elist handle
1005
1002
  function set(elist a, euint256 i, euint256 b) internal returns (elist ret) {
1006
- return inco.listSet(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
1003
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
1007
1004
  }
1008
1005
 
1009
1006
  /// @notice Replaces an element at plaintext index "i" (ebool variant). Reverts if out of range.
@@ -1013,7 +1010,7 @@ library e {
1013
1010
  /// @return ret A new elist handle
1014
1011
  function set(elist a, uint16 i, ebool b) internal returns (elist ret) {
1015
1012
  require(i < length(a), IndexOutOfRange(i, length(a)));
1016
- return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
1013
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
1017
1014
  }
1018
1015
 
1019
1016
  /// @notice Replaces an element at plaintext index "i" (euint256 variant). Reverts if out of range.
@@ -1023,7 +1020,7 @@ library e {
1023
1020
  /// @return ret A new elist handle
1024
1021
  function set(elist a, uint16 i, euint256 b) internal returns (elist ret) {
1025
1022
  require(i < length(a), IndexOutOfRange(i, length(a)));
1026
- return inco.listSet(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
1023
+ return inco.listSet{value: inco.getEListFee(length(a), listTypeOf(a))}(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
1027
1024
  }
1028
1025
 
1029
1026
  /// @notice Return hidden element at some hidden position (ebool variant).
@@ -1066,7 +1063,7 @@ library e {
1066
1063
  /// @param b Element value to be inserted.
1067
1064
  /// @return ret A new elist handle with length len(a)+1.
1068
1065
  function insert(elist a, euint256 i, ebool b) internal returns (elist ret) {
1069
- return inco.listInsert(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
1066
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(s(i)), ebool.unwrap(s(b)));
1070
1067
  }
1071
1068
 
1072
1069
  /// @notice Inserts an ebool element at a known position. Reverts if out of range.
@@ -1076,7 +1073,7 @@ library e {
1076
1073
  /// @return ret A new elist handle with length len(a)+1.
1077
1074
  function insert(elist a, uint16 i, ebool b) internal returns (elist ret) {
1078
1075
  require(i < length(a), IndexOutOfRange(i, length(a)));
1079
- return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
1076
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(asEuint256(uint256(i))), ebool.unwrap(s(b)));
1080
1077
  }
1081
1078
 
1082
1079
  /// @notice Inserts a hidden element at a desired hidden position (euint256, hidden index).
@@ -1085,7 +1082,7 @@ library e {
1085
1082
  /// @param b Element value to be inserted.
1086
1083
  /// @return ret A new elist handle with length len(a)+1.
1087
1084
  function insert(elist a, euint256 i, euint256 b) internal returns (elist ret) {
1088
- return inco.listInsert(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
1085
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(s(i)), euint256.unwrap(s(b)));
1089
1086
  }
1090
1087
 
1091
1088
  /// @notice Inserts a euint256 element at a known position. Reverts if out of range.
@@ -1095,7 +1092,7 @@ library e {
1095
1092
  /// @return ret A new elist handle with length len(a)+1.
1096
1093
  function insert(elist a, uint16 i, euint256 b) internal returns (elist ret) {
1097
1094
  require(i < length(a), IndexOutOfRange(i, length(a)));
1098
- return inco.listInsert(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
1095
+ return inco.listInsert{value: inco.getEListFee(length(a) + 1, listTypeOf(a))}(a, euint256.unwrap(asEuint256(uint256(i))), euint256.unwrap(s(b)));
1099
1096
  }
1100
1097
 
1101
1098
  /// @notice Concatenates two elists into one.
@@ -1103,7 +1100,7 @@ library e {
1103
1100
  /// @param b EList handle to be appended
1104
1101
  /// @return ret A new elist handle with length len(a)+len(b).
1105
1102
  function concat(elist a, elist b) internal returns (elist ret) {
1106
- return inco.listConcat(a, b);
1103
+ return inco.listConcat{value: inco.getEListFee(length(a) + length(b), listTypeOf(a))}(a, b);
1107
1104
  }
1108
1105
 
1109
1106
  /// @notice Slices a list from plaintext start to plaintext end.
@@ -1123,7 +1120,7 @@ library e {
1123
1120
  } else {
1124
1121
  revert UnsupportedListType(listTypeOf(a));
1125
1122
  }
1126
- return inco.listSlice(a, euint256.unwrap(asEuint256(start)), end - start, defaultValue);
1123
+ return inco.listSlice{value: inco.getEListFee(end - start, listTypeOf(a))}(a, euint256.unwrap(asEuint256(start)), end - start, defaultValue);
1127
1124
  }
1128
1125
 
1129
1126
  /// @notice Slices at a hidden index with a specified length (euint256 default).
@@ -1133,7 +1130,7 @@ library e {
1133
1130
  /// @param defaultValue Default value if out of range.
1134
1131
  /// @return ret A new sliced list with length "len".
1135
1132
  function sliceLen(elist a, euint256 start, uint16 len, euint256 defaultValue) internal returns (elist ret) {
1136
- return inco.listSlice(a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue)));
1133
+ return inco.listSlice{value: inco.getEListFee(len, listTypeOf(a))}(a, euint256.unwrap(s(start)), len, euint256.unwrap(s(defaultValue)));
1137
1134
  }
1138
1135
 
1139
1136
  /// @notice Slices at a hidden index with a specified length (ebool default).
@@ -1143,7 +1140,7 @@ library e {
1143
1140
  /// @param defaultValue Default value if out of range.
1144
1141
  /// @return ret A new sliced list with length "len".
1145
1142
  function sliceLen(elist a, euint256 start, uint16 len, ebool defaultValue) internal returns (elist ret) {
1146
- return inco.listSlice(a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue)));
1143
+ return inco.listSlice{value: inco.getEListFee(len, listTypeOf(a))}(a, euint256.unwrap(s(start)), len, ebool.unwrap(s(defaultValue)));
1147
1144
  }
1148
1145
 
1149
1146
  /// @notice Creates a new list populated with ordered values from within range.
@@ -1151,7 +1148,7 @@ library e {
1151
1148
  /// @param end End of the range, exclusive. Must be >= start.
1152
1149
  /// @return ret A new elist handle with length "end-start"
1153
1150
  function range(uint16 start, uint16 end) internal returns (elist ret) {
1154
- return inco.listRange(start, end);
1151
+ return inco.listRange{value: inco.getEListFee(end - start, ETypes.Uint256)}(start, end);
1155
1152
  }
1156
1153
 
1157
1154
  /// @notice Deterministically shuffles elements within a list.
@@ -1159,8 +1156,7 @@ library e {
1159
1156
  /// @param a elist handle to be shuffled
1160
1157
  /// @return ret A new elist handle with elements shuffled
1161
1158
  function shuffle(elist a) internal returns (elist ret) {
1162
- bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, a));
1163
- return elist.wrap(result);
1159
+ return inco.listShuffle{value: inco.getEListFee(length(a), listTypeOf(a))}(a);
1164
1160
  }
1165
1161
 
1166
1162
  /// @notice A convenience function equivalent to range() followed by shuffle().
@@ -1169,16 +1165,16 @@ library e {
1169
1165
  /// @param end End of the range, exclusive. Must be >= start.
1170
1166
  /// @return ret A new elist handle in random order with length "end-start".
1171
1167
  function shuffledRange(uint16 start, uint16 end) internal returns (elist ret) {
1172
- elist rangeList = inco.listRange(start, end);
1173
- bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.listShuffle.selector, rangeList));
1174
- return elist.wrap(result);
1168
+ uint256 fee = inco.getEListFee(end - start, ETypes.Uint256);
1169
+ elist rangeList = inco.listRange{value: fee}(start, end);
1170
+ return inco.listShuffle{value: fee}(rangeList);
1175
1171
  }
1176
1172
 
1177
1173
  /// @notice Reverses the order of elements in a list.
1178
1174
  /// @param a Elist handle to be reversed
1179
1175
  /// @return ret A new elist handle with elements in reverse order
1180
1176
  function reverse(elist a) internal returns (elist ret) {
1181
- return inco.listReverse(a);
1177
+ return inco.listReverse{value: inco.getEListFee(length(a), listTypeOf(a))}(a);
1182
1178
  }
1183
1179
 
1184
1180
  /// @notice Returns the length of the list in plaintext. Pure function, no gas cost.
@@ -1195,7 +1191,7 @@ library e {
1195
1191
  /// @param signatures Array of signatures from attesters
1196
1192
  /// @return bool True if verification succeeds
1197
1193
  /// @dev For privacy, publish only pairHash. For transparency, publish commitment+value. Can mix both in the same array.
1198
- function verifyEListDecryption(elist elistHandle, ElementDecryptionProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
1194
+ function verifyEListDecryption(elist elistHandle, ElementAttestationWithProof[] memory proofElements, bytes32 proof, bytes[] memory signatures) internal view returns (bool) {
1199
1195
  return inco.incoVerifier().isValidEListDecryptionAttestation(elist.unwrap(elistHandle), proofElements, proof, signatures);
1200
1196
  }
1201
1197
  }
package/src/Types.sol CHANGED
@@ -246,15 +246,24 @@ function isTypeSupported(ETypes t) pure returns (bool) {
246
246
  return t == ETypes.Uint256 || t == ETypes.Bool || t == ETypes.AddressOrUint160OrBytes20;
247
247
  }
248
248
 
249
+ /// Checks whether we can cast to the given type
250
+ /// @param t the type to check
251
+ /// @dev Casting to ebool is not supported in order to not confuse developers coming from other languages where anything above 0 becomes true.
252
+ function canCastTo(ETypes t) pure returns (bool) {
253
+ return t == ETypes.Uint256 || t == ETypes.AddressOrUint160OrBytes20;
254
+ }
255
+
249
256
  error SenderNotAllowedForHandle(bytes32 handle, address sender);
250
257
  error SharerNotAllowedForHandle(bytes32 handle, address sharer);
251
258
  error IndexOutOfRange(uint16 i, uint16 len);
252
259
  error SliceOutOfRange(uint16 start, uint16 end, uint16 len);
253
260
  error ZeroLength();
261
+ error ListTooLong(uint32 provided, uint16 max);
254
262
  error InvalidRange(uint16 start, uint16 end);
255
263
  error ListTypeMismatch(ETypes lhs, ETypes rhs);
256
264
  error UnsupportedListType(ETypes listType);
257
265
  error UnsupportedType(ETypes actual);
266
+ error UnexpectedType(ETypes actual, bytes32 expectedTypes);
258
267
 
259
268
  string constant EVM_HOST_CHAIN_PREFIX = "evm/";
260
269
  uint8 constant HANDLE_VERSION = 0;
@@ -268,6 +277,15 @@ bytes32 constant ALLOWANCE_GRANTED_MAGIC_VALUE = keccak256("Inco Read Access on
268
277
  // NOTE: this must be a uint8 to get hash agreement!
269
278
  uint8 constant HANDLE_INDEX = 0;
270
279
 
280
+ /// Returns the bit size of a supported element type.
281
+ /// @param t the type to get the bit size for
282
+ function typeBitSize(ETypes t) pure returns (uint256) {
283
+ if (t == ETypes.Bool) return 1;
284
+ if (t == ETypes.AddressOrUint160OrBytes20) return 160;
285
+ if (t == ETypes.Uint256) return 256;
286
+ revert UnsupportedType(t);
287
+ }
288
+
271
289
  /// Util function to convert an ETypes to a bit mask
272
290
  /// @param t the type to convert to a bit mask
273
291
  function typeToBitMask(ETypes t) pure returns (bytes32) {
@@ -7,6 +7,8 @@ import {IVersion} from "../version/interfaces/IVersion.sol";
7
7
 
8
8
  interface IIncoLightning is ITrivialEncryption, IEList, IVersion {
9
9
 
10
+ error EthInboundTransferUnsupported();
11
+
10
12
  function initialize(address owner) external;
11
13
 
12
14
  function withdrawFees() external;