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

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 +88 -2
  36. package/src/lightning-parts/DecryptionAttester.types.sol +9 -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 +11 -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
@@ -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(0xA95EAbCE575f5f1e52605358Ee893F6536166378);
12
+ IncoLightning constant inco = IncoLightning(payable(0xA95EAbCE575f5f1e52605358Ee893F6536166378));
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
  }
@@ -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(0x3B22be60Ae699933959CA3cE147C96caa88Ccd3D);
12
+ IncoLightning constant inco = IncoLightning(payable(0x3B22be60Ae699933959CA3cE147C96caa88Ccd3D));
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
  }