@inco/lightning-preview 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Inco Lightning Preview
2
+
3
+ Reproducing the Inco Lightning file structure, here are the not yet public features fro Inco Lightning.
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@inco/lightning-preview",
3
+ "version": "0.7.9",
4
+ "repository": "https://github.com/Inco-fhevm/inco-monorepo",
5
+ "files": [
6
+ "src/",
7
+ "remappings.txt"
8
+ ],
9
+ "scripts": {
10
+ "lint": "forge lint && forge fmt --check",
11
+ "lint:fix": "forge fmt",
12
+ "build": "forge build",
13
+ "publish:github": "bun publish --registry=https://npm.pkg.github.com",
14
+ "publish:npm": "bun publish --access public"
15
+ },
16
+ "publishConfig": {
17
+ "registry": "https://npm.pkg.github.com"
18
+ },
19
+ "dependencies": {
20
+ "@inco/lightning": "0.0.0",
21
+ "@openzeppelin/contracts": "^5.3.0",
22
+ "@openzeppelin/contracts-upgradeable": "^5.3.0",
23
+ "ds-test": "https://github.com/dapphub/ds-test",
24
+ "forge-std": "https://github.com/foundry-rs/forge-std"
25
+ }
26
+ }
package/remappings.txt ADDED
@@ -0,0 +1,9 @@
1
+ @openzeppelin/=../../node_modules/@openzeppelin/
2
+ forge-std/=../../node_modules/forge-std/src/
3
+ ds-test/=../../node_modules/ds-test/src/
4
+ automata-dcap-attestation/=../../node_modules/automata-dcap-attestation/evm/contracts/
5
+ @automata-network/dcap-attestation/=../../node_modules/automata-dcap-attestation/evm/contracts/
6
+ automata-on-chain-pccs/=../../node_modules/automata-on-chain-pccs/src/
7
+ @automata-network/on-chain-pccs/=../../node_modules/automata-on-chain-pccs/src/
8
+ @inco/=../
9
+ solady/=../../node_modules/solady/src/
@@ -0,0 +1,7 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IIncoLightning} from "@inco/lightning/src/IIncoLightning.sol";
5
+ import {IEList} from "./lightning-parts/IEList.sol";
6
+
7
+ interface IIncoLightningPreview is IIncoLightning, IEList {}
@@ -0,0 +1,66 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IncoLightning} from "@inco/lightning/src/IncoLightning.sol";
5
+ import {
6
+ CONTRACT_NAME,
7
+ MAJOR_VERSION,
8
+ MINOR_VERSION,
9
+ PATCH_VERSION
10
+ } from "@inco/lightning/src/version/IncoLightningConfig.sol";
11
+ import {Version} from "@inco/lightning/src/version/Version.sol";
12
+ import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
13
+ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
14
+ import {EList} from "./lightning-parts/EList.sol";
15
+ import {VerifierAddressGetter} from "@inco/lightning/src/lightning-parts/primitives/VerifierAddressGetter.sol";
16
+
17
+ contract IncoLightningPreview is EList, UUPSUpgradeable, Version, OwnableUpgradeable {
18
+
19
+ IncoLightning private immutable LIGHTNING;
20
+
21
+ // Note passing in address rather than IncoLightning directly since the contracts mismatch due to different
22
+ // remappings
23
+ constructor(address _lightningAddress, address _verifierAddress)
24
+ VerifierAddressGetter(_verifierAddress)
25
+ Version(
26
+ MAJOR_VERSION,
27
+ MINOR_VERSION,
28
+ PATCH_VERSION,
29
+ IncoLightning(_lightningAddress).salt(),
30
+ string(abi.encodePacked(CONTRACT_NAME, "Preview"))
31
+ )
32
+ {
33
+ LIGHTNING = IncoLightning(_lightningAddress);
34
+ }
35
+
36
+ function includesPreviewFeatures() public pure returns (bool) {
37
+ return true;
38
+ }
39
+
40
+ function _authorizeUpgrade(address) internal view override {
41
+ require(msg.sender == owner());
42
+ }
43
+
44
+ function initialize(address owner) public initializer {
45
+ __Ownable_init(owner);
46
+ }
47
+
48
+ fallback() external {
49
+ // get facet from function selector
50
+ address logic = address(LIGHTNING);
51
+ // Execute external calls using delegatecall on core and return any value.
52
+ assembly {
53
+ // copy function selector and any arguments
54
+ calldatacopy(0, 0, calldatasize())
55
+ // execute function call using the facet
56
+ let result := delegatecall(gas(), logic, 0, calldatasize(), 0, 0)
57
+ // get any return value
58
+ returndatacopy(0, 0, returndatasize())
59
+ // return any return value or error back to the caller
60
+ switch result
61
+ case 0 { revert(0, returndatasize()) }
62
+ default { return(0, returndatasize()) }
63
+ }
64
+ }
65
+
66
+ }
@@ -0,0 +1,316 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IIncoLightningPreview} from "./IIncoLightningPreview.sol";
5
+ import {inco, ebool, euint256, e} from "@inco/lightning/src/Lib.sol";
6
+ import {ETypes} from "@inco/lightning/src/Types.sol";
7
+ import {elist, IndexOutOfRange, InvalidRange, SliceOutOfRange, UnsupportedListType} from "./TypesPreview.sol";
8
+
9
+ // forge-lint: disable-next-line(screaming-snake-case-const)
10
+ IIncoLightningPreview constant incoPreview = IIncoLightningPreview(address(inco));
11
+
12
+ /// @title Inco Lightning Preview Library
13
+ /// @author Inco
14
+ /// @notice You can use this library to try out experimental features before they get released
15
+ /// @dev If some library functions should be in preview, declare an ePreview lib here
16
+ /// @custom:experimental This library contains experimental features, and API may change or support can be dropped. Use at your own risk.
17
+ library ePreview {
18
+
19
+ /**
20
+ * @notice Returns the type of the elements contained within the list. This is a pure function that does not require any gas to call.
21
+ * @param handle EList handle to read contrainer type from.
22
+ * @return ret Type of each element in the list.
23
+ */
24
+ function listTypeOf(elist handle) public pure returns (ETypes ret) {
25
+ return ETypes(uint8(uint256(elist.unwrap(handle)) >> 16));
26
+ }
27
+
28
+ /**
29
+ * @notice Creates a new empty list and returns a new elist handle. Type must be specified ahead of time and can not be changed.
30
+ * @param listType Type of each element in the list. This can not be changed
31
+ * @return ret A new elist handle
32
+ */
33
+ function newEList(ETypes listType) public returns (elist ret) {
34
+ return incoPreview.newEList(new bytes32[](0), listType);
35
+ }
36
+
37
+ /**
38
+ * @notice Creates a new list from existing array of handles and returns a new elist handle. Type must be specified ahead of time and can not be changed. The handle's type must match the type of the list inner type, otherwise it will revert.
39
+ * @param handles An array of handles to create a new list from
40
+ * @param listType Type of each element in the list. This can not be changed and must match the type of each handle in the array.
41
+ * @return ret A new elist handle
42
+ */
43
+ function newEList(bytes32[] memory handles, ETypes listType) internal returns (elist ret) {
44
+ return incoPreview.newEList(handles, listType);
45
+ }
46
+
47
+ /**
48
+ * @notice Takes an array of user encrypted ciphertexts and returns a new elist handle. Expected type must be specified ahead of time and can not be changed. The ciphertext's type must match the type of the list inner type, otherwise it will revert.
49
+ * @param ciphertexts An array of encrypted user inputs to create a new list from
50
+ * @param listType Expected type of each element in the list. This can not be changed and must match the type of each ciphertext in the array.
51
+ * @param user Address of the user encrypting the ciphertexts.
52
+ * @return ret A new elist handle
53
+ * @dev each ciphertext costs the inco fee
54
+ */
55
+ function newEList(bytes[] memory ciphertexts, ETypes listType, address user) internal returns (elist ret) {
56
+ return incoPreview.newEList{value: inco.getFee() * ciphertexts.length}(ciphertexts, listType, user);
57
+ }
58
+
59
+ /**
60
+ * @notice Appends an element of type ETypes.Bool at the end of a list, returning a new modified list handle.
61
+ * @param a An elist handle to append to. Must contain values of type ETypes.Bool.
62
+ * @param b Element value to be appended to the list. Must match the elist's inner type ETypes.Bool.
63
+ * @return ret A new elist handle. The new list will have a length of len(a)+1.
64
+ */
65
+ function append(elist a, ebool b) internal returns (elist ret) {
66
+ return incoPreview.listAppend(a, ebool.unwrap(e.s(b)));
67
+ }
68
+
69
+ /**
70
+ * @notice Appends an element of type ETypes.Uint256 at the end of a list, returning a new modified list handle.
71
+ * @param a An elist handle to append to. Must contain values of type ETypes.Uint256.
72
+ * @param b Element value to be appended to the list. Must match the elist's inner type ETypes.Uint256.
73
+ * @return ret A new elist handle. The new list will have a length of len(a)+1.
74
+ */
75
+ function append(elist a, euint256 b) internal returns (elist ret) {
76
+ return incoPreview.listAppend(a, euint256.unwrap(e.s(b)));
77
+ }
78
+
79
+ /**
80
+ * @notice Replaces an element at some hidden index "i" and returns a new modified list.
81
+ * @param a EList handle to modify element in.
82
+ * @param i Hidden index position of an element to modify.
83
+ * @param b Element value to be changed if the index is within range. Will return the original list if the index is out of range. Must match the elist's inner type of type ETypes.Bool
84
+ * @return ret A new elist handle
85
+ */
86
+ function set(elist a, euint256 i, ebool b) internal returns (elist ret) {
87
+ return incoPreview.listSet(a, euint256.unwrap(e.s(i)), ebool.unwrap(e.s(b)));
88
+ }
89
+
90
+ /**
91
+ * @notice Replaces an element at some hidden index "i" and returns a new modified list.
92
+ * @param a EList handle to modify element in.
93
+ * @param i Hidden index position of an element to modify.
94
+ * @param b Element value to be changed if the index is within range. Will return the original list if the index is out of range. Must match the elist's inner type of type ETypes.Uint256
95
+ * @return ret A new elist handle
96
+ */
97
+ function set(elist a, euint256 i, euint256 b) internal returns (elist ret) {
98
+ return incoPreview.listSet(a, euint256.unwrap(e.s(i)), euint256.unwrap(e.s(b)));
99
+ }
100
+
101
+ /**
102
+ * @notice Replaces an element at index "i" and returns a new modified list.
103
+ * @param a EList handle to modify element in.
104
+ * @param i Index position of element to modify.
105
+ * @param b Element value to be changed if the index is within range. Will revert if the index is out of range. Must match the elist's inner type of type ETypes.Bool
106
+ * @return ret A new elist handle
107
+ */
108
+ function set(elist a, uint16 i, ebool b) internal returns (elist ret) {
109
+ require(i < length(a), IndexOutOfRange(i, length(a)));
110
+ return incoPreview.listSet(a, euint256.unwrap(e.asEuint256(uint256(i))), ebool.unwrap(e.s(b)));
111
+ }
112
+ /**
113
+ * @notice Replaces an element at index "i" and returns a new modified list.
114
+ * @param a EList handle to modify element in.
115
+ * @param i Index position of element to modify.
116
+ * @param b Element value to be changed if the index is within range. Will revert if the index is out of range. Must match the elist's inner type of type ETypes.Bool
117
+ * @return ret A new elist handle
118
+ */
119
+
120
+ function set(elist a, uint16 i, euint256 b) internal returns (elist ret) {
121
+ require(i < length(a), IndexOutOfRange(i, length(a)));
122
+ return incoPreview.listSet(a, euint256.unwrap(e.asEuint256(uint256(i))), euint256.unwrap(e.s(b)));
123
+ }
124
+
125
+ /**
126
+ * @notice Return hidden element at some hidden position. Returns a handle to the hidden element if the index is within range, otherwise returns the default value.
127
+ * @param a EList handle to get element from.
128
+ * @param i Hidden index position to get element at.
129
+ * @param defaultValue A default element value to be returned if index is out of range. Must match the elist's inner type of type ETypes.Bool.
130
+ * @return ret A new handle for the element or the defaultValue
131
+ */
132
+ function getOr(elist a, euint256 i, ebool defaultValue) internal returns (ebool ret) {
133
+ return ebool.wrap(incoPreview.listGetOr(a, euint256.unwrap(e.s(i)), ebool.unwrap(e.s(defaultValue))));
134
+ }
135
+ /**
136
+ * @notice Return hidden element at some hidden position. Returns a handle to the hidden element if the index is within range, otherwise returns the default value.
137
+ * @param a EList handle to get element from.
138
+ * @param i Hidden index position to get element at.
139
+ * @param defaultValue A default element value to be returned if index is out of range. Must match the elist's inner type of type ETypes.Uint256.
140
+ * @return ret A new handle for the element or the defaultValue
141
+ */
142
+
143
+ function getOr(elist a, euint256 i, euint256 defaultValue) internal returns (euint256 ret) {
144
+ return euint256.wrap(incoPreview.listGetOr(a, euint256.unwrap(e.s(i)), euint256.unwrap(e.s(defaultValue))));
145
+ }
146
+ /**
147
+ * @notice Return hidden element at a known position. Returns a handle to the hidden ETypes.Bool element if the index is within range, otherwise reverts.
148
+ * @param a EList handle to get element from.
149
+ * @param i Index position to get element at.
150
+ * @return ret Returns a handle for the element of type ETypes.Bool.
151
+ */
152
+
153
+ function getEbool(elist a, uint16 i) external returns (ebool ret) {
154
+ return ebool.wrap(incoPreview.listGet(a, i));
155
+ }
156
+ /**
157
+ * @notice Return hidden element at a known position. Returns a handle to the hidden ETypes.Uint256 element if the index is within range, otherwise reverts.
158
+ * @param a EList handle to get element from.
159
+ * @param i Index position to get element at.
160
+ * @return ret Returns a handle for the element of type ETypes.Uint256.
161
+ */
162
+
163
+ function getEuint256(elist a, uint16 i) external returns (euint256 ret) {
164
+ return euint256.wrap(incoPreview.listGet(a, i));
165
+ }
166
+
167
+ /**
168
+ * @notice Inserts a hidden element at a desired hidden position, returns a new modified list.
169
+ * @param a An elist handle to insert into.
170
+ * @param i Hidden index position to insert at. If the index is out of range, the element will be appended to the end of the list.
171
+ * @param b Element value to be inserted to the list. Must match the elist's inner type of type ETypes.Bool.
172
+ * @return ret A new elist handle. The new list will have a length of len(a)+1.
173
+ */
174
+ function insert(elist a, euint256 i, ebool b) internal returns (elist ret) {
175
+ return incoPreview.listInsert(a, euint256.unwrap(e.s(i)), ebool.unwrap(e.s(b)));
176
+ }
177
+ /**
178
+ * @notice Inserts a hidden element at a desired position, returns a new modified list.
179
+ * @param a An elist handle to insert into.
180
+ * @param i Index position to insert at. If the index is out of range, it will revert.
181
+ * @param b Element value to be inserted to the list. Must match the elist's inner type of type ETypes.Bool.
182
+ * @return ret A new elist handle. The new list will have a length of len(a)+1.
183
+ */
184
+
185
+ function insert(elist a, uint16 i, ebool b) internal returns (elist ret) {
186
+ require(i < length(a), IndexOutOfRange(i, length(a)));
187
+ return incoPreview.listInsert(a, euint256.unwrap(e.asEuint256(uint256(i))), ebool.unwrap(e.s(b)));
188
+ }
189
+ /**
190
+ * @notice Inserts a hidden element at a desired hidden position, returns a new modified list.
191
+ * @param a An elist handle to insert into.
192
+ * @param i Hidden index position to insert at. If the index is out of range, the element will be appended to the end of the list.
193
+ * @param b Element value to be inserted to the list. Must match the elist's inner type of type ETypes.Uint256.
194
+ * @return ret A new elist handle. The new list will have a length of len(a)+1.
195
+ */
196
+
197
+ function insert(elist a, euint256 i, euint256 b) internal returns (elist ret) {
198
+ return incoPreview.listInsert(a, euint256.unwrap(e.s(i)), euint256.unwrap(e.s(b)));
199
+ }
200
+ /**
201
+ * @notice Inserts a hidden element at a desired position, returns a new modified list.
202
+ * @param a An elist handle to insert into.
203
+ * @param i Index position to insert at. If the index is out of range, it will revert.
204
+ * @param b Element value to be inserted to the list. Must match the elist's inner type of type ETypes.Uint256.
205
+ * @return ret A new elist handle. The new list will have a length of len(a)+1.
206
+ */
207
+
208
+ function insert(elist a, uint16 i, euint256 b) internal returns (elist ret) {
209
+ require(i < length(a), IndexOutOfRange(i, length(a)));
210
+ return incoPreview.listInsert(a, euint256.unwrap(e.asEuint256(uint256(i))), euint256.unwrap(e.s(b)));
211
+ }
212
+
213
+ /**
214
+ * @notice Concatenates two elists into one, returns a new concatenated elist. Both lists must have the same inner type. The length of the new list will be length(list1)+length(list2)
215
+ * @param a EList handle to be prepended
216
+ * @param b EList handle to be appended
217
+ * @return ret A new elist handle containing elements from both A and B with length of len(list1)+len(list2).
218
+ */
219
+ function concat(elist a, elist b) external returns (elist ret) {
220
+ return incoPreview.listConcat(a, b);
221
+ }
222
+
223
+ /**
224
+ * @notice Takes in start and end positions both in plaintext. Returns a new sliced list of length “end-start”. If start or end are out of bounds, it will revert. The end index must be greater or equal the start index.
225
+ * @param a EList handle to be sliced
226
+ * @param start Starting index of the slice, in plaintext. Start is inclusive, meaning if start is 0, the first element will be included in the new slice.
227
+ * @param end End index of the slice, in plaintext. End is exclusive and must be greater or equal start and within the bounds of the list length.
228
+ * @return ret A new sliced list with a new length of “end-start”.
229
+ */
230
+ function slice(elist a, uint16 start, uint16 end) external returns (elist ret) {
231
+ require(end >= start, InvalidRange(start, end));
232
+ require(end <= length(a), SliceOutOfRange(start, end, length(a)));
233
+ require(start < length(a), SliceOutOfRange(start, end, length(a)));
234
+ bytes32 defaultValue;
235
+ if (ETypes.Uint256 == listTypeOf(a)) {
236
+ defaultValue = euint256.unwrap(e.asEuint256(0));
237
+ } else if (ETypes.Bool == listTypeOf(a)) {
238
+ defaultValue = ebool.unwrap(e.asEbool(false));
239
+ } else {
240
+ revert UnsupportedListType(listTypeOf(a));
241
+ }
242
+ return incoPreview.listSlice(a, euint256.unwrap(e.asEuint256(start)), end - start, defaultValue);
243
+ }
244
+ /**
245
+ * @notice sliceLen() is a variant of slice() but allows to slice at some hidden index specifying a length instead of end position. Returns a new sliced list of length of “len”.
246
+ * @param a EList handle to be sliced, must be of type ETypes.Uint256.
247
+ * @param start Hidden starting index of the slice. Start is inclusive, meaning if start is 0, the first element will be included in the new slice. If start is out of bounds, all elements in the returned slice will be the default element.
248
+ * @param len Length of the desired slice. If the length is out of bounds, remaining elements will be filled with the provided default value.
249
+ * @param defaultValue Default value to fill the remaining elements of the slice if out of range.
250
+ * @return ret a new sliced list with a new length of "len".
251
+ */
252
+
253
+ function sliceLen(elist a, euint256 start, uint16 len, euint256 defaultValue) internal returns (elist ret) {
254
+ return incoPreview.listSlice(a, euint256.unwrap(e.s(start)), len, euint256.unwrap(e.s(defaultValue)));
255
+ }
256
+ /**
257
+ * @notice sliceLen() is a variant of slice() but allows to slice at some hidden index specifying a length instead of end position. Returns a new sliced list of length of “len”.
258
+ * @param a EList handle to be sliced. List type must be of type ETypes.EBool.
259
+ * @param start Hidden starting index of the slice. Start is inclusive, meaning if start is 0, the first element will be included in the new slice.
260
+ * @param len Length of the desired slice. If the length is out of bounds, remaining elements will be filled with the provided default value.
261
+ * @param defaultValue Default value to fill the remaining elements of the slice if out of range.
262
+ * @return ret a new sliced list with a new length of "len".
263
+ */
264
+
265
+ function sliceLen(elist a, euint256 start, uint16 len, ebool defaultValue) internal returns (elist ret) {
266
+ return incoPreview.listSlice(a, euint256.unwrap(e.s(start)), len, ebool.unwrap(e.s(defaultValue)));
267
+ }
268
+
269
+ /**
270
+ * @notice Creates a new list (or a “set”) and populates it with ordered values from within range. The length of the new list will be equal to “end-start”.
271
+ * @param start Start value of the range, inclusive.
272
+ * @param end End of the range, exclusive. Must be greater or equal start.
273
+ * @return ret A new elist handle containing a range of unique elements with the length of “end-start”
274
+ */
275
+ function range(uint16 start, uint16 end) external returns (elist ret) {
276
+ return incoPreview.listRange(start, end);
277
+ }
278
+
279
+ /**
280
+ * @notice Deterministically shuffles elements within a list, returning a new shuffled list with the same length.
281
+ * @param a elist handle to be shuffled
282
+ * @return ret A new elist handle with elements shuffled where each element is equally likely to be in any position in the new list.
283
+ */
284
+ function shuffle(elist a) external returns (elist ret) {
285
+ return incoPreview.listShuffle(a);
286
+ }
287
+
288
+ /**
289
+ * @notice A convenience function equivalent to range() followed by shuffle(). It returns an elist containing the elements from start to end in a random order.
290
+ * @param start Start value of the range, inclusive.
291
+ * @param end End of the range, exclusive. Must be greater or equal start.
292
+ * @return ret A new elist handle containing a range of unique elements with the length of “end-start” in a random order.
293
+ */
294
+ function shuffledRange(uint16 start, uint16 end) external returns (elist ret) {
295
+ return incoPreview.listShuffle(incoPreview.listRange(start, end));
296
+ }
297
+
298
+ /**
299
+ * @notice Reverses the order of elements in a list, first element becomes last, and so on.
300
+ * @param a Elist handle to be reversed
301
+ * @return ret A new elist handle with elements in reverse order
302
+ */
303
+ function reverse(elist a) external returns (elist ret) {
304
+ return incoPreview.listReverse(a);
305
+ }
306
+
307
+ /**
308
+ * @notice Returns the length of the list in plaintext. It’s a pure function that doesn’t require any gas to call.
309
+ * @param a EList handle to read the length from
310
+ * @return len The length of the list in plaintext
311
+ */
312
+ function length(elist a) public pure returns (uint16 len) {
313
+ return incoPreview.lengthOf(elist.unwrap(a));
314
+ }
315
+
316
+ }
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IncoLightningPreview} from "./IncoLightningPreview.sol";
5
+ import {IIncoLightningPreview} from "./IIncoLightningPreview.sol";
6
+ import {DeployUtils} from "@inco/lightning/src/DeployUtils.sol";
7
+ import {IncoLightning} from "@inco/lightning/src/IncoLightning.sol";
8
+ import {IIncoLightning} from "@inco/lightning/src/interfaces/IIncoLightning.sol";
9
+ import {IIncoVerifier} from "@inco/lightning/src/interfaces/IIncoVerifier.sol";
10
+ import {IQuoteVerifier} from "@inco/lightning/src/interfaces/automata-interfaces/IQuoteVerifier.sol";
11
+ import {console} from "forge-std/console.sol";
12
+
13
+ contract PreviewDeployUtils is DeployUtils {
14
+
15
+ function deployLightningPreview(bytes32 lightningSalt, bytes32 verifierSalt, address deployer)
16
+ internal
17
+ returns (IIncoLightningPreview lightningPreview)
18
+ {
19
+ address verifierAddress = computeAddressFromSalt(verifierSalt);
20
+ IncoLightning lightningImplem = new IncoLightning(lightningSalt, IIncoVerifier(verifierAddress));
21
+ IncoLightningPreview lightningPreviewImplem =
22
+ new IncoLightningPreview(address(lightningImplem), address(lightningImplem.incoVerifier()));
23
+ lightningPreview = IIncoLightningPreview(
24
+ deployProxy({
25
+ salt: lightningSalt,
26
+ implem: address(lightningPreviewImplem),
27
+ initCall: abi.encodeWithSelector(
28
+ IIncoLightning.initialize.selector,
29
+ deployer // owner
30
+ )
31
+ })
32
+ );
33
+ }
34
+
35
+ function deployIncoLightningPreviewUsingConfig(address deployer, string memory pepper, IQuoteVerifier quoteVerifier)
36
+ internal
37
+ returns (IIncoLightningPreview lightningPreviewProxy, IIncoVerifier verifierProxy)
38
+ {
39
+ (bytes32 lightningSalt, bytes32 verifierSalt) = getIncoSalts(deployer, pepper);
40
+ console.log(
41
+ "Deploying Inco with preview features with deployerAddress: %s, lightning salt: %s",
42
+ vm.toString(deployer),
43
+ vm.toString(lightningSalt)
44
+ );
45
+ lightningPreviewProxy = deployLightningPreview(lightningSalt, verifierSalt, deployer);
46
+ verifierProxy =
47
+ deployVerifier(verifierSalt, IIncoLightning(address(lightningPreviewProxy)), deployer, quoteVerifier);
48
+ }
49
+
50
+ }
@@ -0,0 +1,18 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {ETypes} from "@inco/lightning/src/Types.sol";
5
+
6
+ type elist is bytes32;
7
+
8
+ error IndexOutOfRange(uint16 i, uint16 len);
9
+ error SliceOutOfRange(uint16 start, uint16 end, uint16 len);
10
+ error ZeroLength();
11
+ error InvalidRange(uint16 start, uint16 end);
12
+ error ListTypeMismatch(ETypes lhs, ETypes rhs);
13
+ error UnsupportedListType(ETypes listType);
14
+ error UnsupportedType(ETypes actual);
15
+
16
+ function isEList(ETypes t) pure returns (bool) {
17
+ return t == ETypes.List;
18
+ }
@@ -0,0 +1,232 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {ETypes, EOps, typeToBitMask, isTypeSupported} from "@inco/lightning/src/Types.sol";
5
+ import {IndexOutOfRange} from "../TypesPreview.sol";
6
+ import {AccessControlListStorage} from "@inco/lightning/src/lightning-parts/AccessControl/BaseAccessControlList.sol";
7
+ import {EncryptedOperations} from "@inco/lightning/src/lightning-parts/EncryptedOperations.sol";
8
+ import {EncryptedInput} from "@inco/lightning/src/lightning-parts/EncryptedInput.sol";
9
+ import {EListHandleGeneration} from "./primitives/EListHandleGeneration.sol";
10
+ import {IEList} from "./IEList.sol";
11
+ import {elist, ListTypeMismatch, InvalidRange} from "../TypesPreview.sol";
12
+
13
+ abstract contract EList is
14
+ AccessControlListStorage,
15
+ EListHandleGeneration,
16
+ EncryptedOperations,
17
+ EncryptedInput,
18
+ IEList
19
+ {
20
+
21
+ event NewEList(bytes32 indexed result, ETypes listType, bytes32[] handles, uint256 eventId);
22
+ event EListAppend(elist indexed list, bytes32 indexed value, elist indexed result, uint256 eventId);
23
+ event EListGet(elist indexed list, uint16 indexed index, bytes32 indexed result, uint256 eventId);
24
+ event EListGetOr(
25
+ elist indexed list, bytes32 index, bytes32 indexed defaultValue, bytes32 indexed result, uint256 eventId
26
+ );
27
+ event EListSet(elist list, bytes32 indexed index, bytes32 indexed value, elist indexed result, uint256 eventId);
28
+ event EListInsert(elist list, bytes32 indexed index, bytes32 indexed value, elist indexed result, uint256 eventId);
29
+ event EListConcat(elist indexed list1, elist indexed list2, elist indexed result, uint256 eventId);
30
+ event EListSlice(
31
+ elist list,
32
+ bytes32 indexed start,
33
+ uint16 length,
34
+ bytes32 indexed defaultValue,
35
+ elist indexed result,
36
+ uint256 eventId
37
+ );
38
+ event EListRange(uint256 indexed start, uint256 indexed end, elist indexed result, uint256 eventId);
39
+ event EListShuffle(elist indexed list, uint256 indexed counter, elist indexed result, uint256 eventId);
40
+ event EListReverse(elist indexed list, elist indexed result, uint256 eventId);
41
+
42
+ function newEListFromInputs(bytes[] memory inputs, ETypes listType, address user) internal returns (elist newList) {
43
+ require(isTypeSupported(listType), UnsupportedType(listType));
44
+
45
+ // TODO: Add a new event to create new elist from inputs, can be done as an upgrade to optimize for gas and castore.
46
+ bytes32[] memory handles = new bytes32[](inputs.length);
47
+ for (uint256 i = 0; i < inputs.length; i++) {
48
+ // we check payment for multiple inputs ahead of this func
49
+ handles[i] = newInputNotPaying(inputs[i], user, listType);
50
+ }
51
+ return newEListFromHandles(handles, listType);
52
+ }
53
+
54
+ function newEListFromHandles(bytes32[] memory handles, ETypes listType) internal returns (elist newList) {
55
+ require(isTypeSupported(listType), UnsupportedType(listType));
56
+ for (uint256 i = 0; i < handles.length; i++) {
57
+ checkInput(handles[i], typeToBitMask(listType));
58
+ }
59
+
60
+ bytes32 newHandle = createListInputHandle(handles, listType);
61
+
62
+ allowTransientInternal(newHandle, msg.sender);
63
+
64
+ emit NewEList(newHandle, listType, handles, getNewEventId());
65
+
66
+ return elist.wrap(newHandle);
67
+ }
68
+
69
+ function newEList(bytes32[] memory handles, ETypes listType) external returns (elist newList) {
70
+ return newEListFromHandles(handles, listType);
71
+ }
72
+
73
+ function newEList(bytes[] memory inputs, ETypes listType, address user)
74
+ external
75
+ payable
76
+ payingMultiple(inputs.length)
77
+ returns (elist newList)
78
+ {
79
+ return newEListFromInputs(inputs, listType, user);
80
+ }
81
+
82
+ function elementTypeOf(bytes32 handle) internal pure returns (ETypes) {
83
+ return ETypes(uint8(uint256(handle) >> 16));
84
+ }
85
+
86
+ function listAppend(elist list, bytes32 value) external returns (elist result) {
87
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
88
+ checkInput(value, typeToBitMask(listTypeOf(elist.unwrap(list))));
89
+
90
+ result = elist.wrap(
91
+ createListResultHandle(
92
+ EOps.EListAppend,
93
+ listTypeOf(elist.unwrap(list)),
94
+ lengthOf(elist.unwrap(list)) + 1,
95
+ abi.encodePacked(elist.unwrap(list), value)
96
+ )
97
+ );
98
+ allowTransientInternal(elist.unwrap(result), msg.sender);
99
+ emit EListAppend(list, value, result, getNewEventId());
100
+ }
101
+
102
+ function listGet(elist list, uint16 i) external returns (bytes32 result) {
103
+ require(i < lengthOf(elist.unwrap(list)), IndexOutOfRange(i, lengthOf(elist.unwrap(list))));
104
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
105
+
106
+ result =
107
+ createResultHandle(EOps.EListGet, listTypeOf(elist.unwrap(list)), abi.encodePacked(elist.unwrap(list), i));
108
+ emit EListGet(list, i, result, getNewEventId());
109
+ }
110
+
111
+ function listGetOr(elist list, bytes32 index, bytes32 defaultValue) external returns (bytes32 result) {
112
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
113
+ checkInput(defaultValue, typeToBitMask(listTypeOf(elist.unwrap(list))));
114
+ checkInput(index, typeToBitMask(ETypes.Uint256)); //Currently we only support euint256 for index
115
+
116
+ result = createResultHandle(
117
+ EOps.EListGetOr, listTypeOf(elist.unwrap(list)), abi.encodePacked(elist.unwrap(list), index, defaultValue)
118
+ );
119
+ emit EListGetOr(list, index, defaultValue, result, getNewEventId());
120
+ }
121
+
122
+ function listSet(elist list, bytes32 index, bytes32 value) external returns (elist result) {
123
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
124
+ checkInput(index, typeToBitMask(ETypes.Uint256)); //Currently we only support euint256 for index
125
+ checkInput(value, typeToBitMask(listTypeOf(elist.unwrap(list))));
126
+
127
+ result = elist.wrap(
128
+ createListResultHandle(
129
+ EOps.EListSet,
130
+ listTypeOf(elist.unwrap(list)),
131
+ lengthOf(elist.unwrap(list)),
132
+ abi.encodePacked(elist.unwrap(list), index, value)
133
+ )
134
+ );
135
+ allowTransientInternal(elist.unwrap(result), msg.sender);
136
+ emit EListSet(list, index, value, result, getNewEventId());
137
+ }
138
+
139
+ function listInsert(elist list, bytes32 index, bytes32 value) external returns (elist result) {
140
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
141
+ checkInput(index, typeToBitMask(ETypes.Uint256)); //Currently we only support euint256 for index
142
+ checkInput(value, typeToBitMask(listTypeOf(elist.unwrap(list))));
143
+
144
+ result = elist.wrap(
145
+ createListResultHandle(
146
+ EOps.EListInsert,
147
+ listTypeOf(elist.unwrap(list)),
148
+ lengthOf(elist.unwrap(list)) + 1,
149
+ abi.encodePacked(elist.unwrap(list), index, value)
150
+ )
151
+ );
152
+ allowTransientInternal(elist.unwrap(result), msg.sender);
153
+ emit EListInsert(list, index, value, result, getNewEventId());
154
+ }
155
+
156
+ function listConcat(elist lhs, elist rhs) external returns (elist result) {
157
+ checkInput(elist.unwrap(lhs), typeToBitMask(ETypes.List));
158
+ checkInput(elist.unwrap(rhs), typeToBitMask(ETypes.List));
159
+ ETypes lhsType = listTypeOf(elist.unwrap(lhs));
160
+ ETypes rhsType = listTypeOf(elist.unwrap(rhs));
161
+ require(lhsType == rhsType, ListTypeMismatch(lhsType, rhsType));
162
+
163
+ result = elist.wrap(
164
+ createListResultHandle(
165
+ EOps.EListConcat,
166
+ listTypeOf(elist.unwrap(lhs)),
167
+ lengthOf(elist.unwrap(lhs)) + lengthOf(elist.unwrap(rhs)),
168
+ abi.encodePacked(elist.unwrap(lhs), elist.unwrap(rhs))
169
+ )
170
+ );
171
+ allowTransientInternal(elist.unwrap(result), msg.sender);
172
+ emit EListConcat(lhs, rhs, result, getNewEventId());
173
+ }
174
+
175
+ function listSlice(elist list, bytes32 start, uint16 len, bytes32 defaultValue) external returns (elist result) {
176
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
177
+ checkInput(defaultValue, typeToBitMask(listTypeOf(elist.unwrap(list))));
178
+ checkInput(start, typeToBitMask(ETypes.Uint256));
179
+
180
+ result = elist.wrap(
181
+ createListResultHandle(
182
+ EOps.EListSlice,
183
+ listTypeOf(elist.unwrap(list)),
184
+ len,
185
+ abi.encodePacked(elist.unwrap(list), start, defaultValue)
186
+ )
187
+ );
188
+ allowTransientInternal(elist.unwrap(result), msg.sender);
189
+ emit EListSlice(list, start, len, defaultValue, result, getNewEventId());
190
+ }
191
+
192
+ function listRange(uint16 start, uint16 end) external returns (elist result) {
193
+ require(start <= end, InvalidRange(start, end));
194
+
195
+ result = elist.wrap(
196
+ createListResultHandle(EOps.EListRange, ETypes.Uint256, end - start, abi.encodePacked(start, end))
197
+ );
198
+ allowTransientInternal(elist.unwrap(result), msg.sender);
199
+ emit EListRange(start, end, result, getNewEventId());
200
+ }
201
+
202
+ function listShuffle(elist list) external payable paying returns (elist result) {
203
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
204
+ randCounter++;
205
+ result = elist.wrap(
206
+ createListResultHandle(
207
+ EOps.EListShuffle,
208
+ listTypeOf(elist.unwrap(list)),
209
+ lengthOf(elist.unwrap(list)),
210
+ abi.encodePacked(elist.unwrap(list), bytes32(randCounter))
211
+ )
212
+ );
213
+ allowTransientInternal(elist.unwrap(result), msg.sender);
214
+ emit EListShuffle(list, randCounter, result, getNewEventId());
215
+ }
216
+
217
+ function listReverse(elist list) external returns (elist result) {
218
+ checkInput(elist.unwrap(list), typeToBitMask(ETypes.List));
219
+
220
+ result = elist.wrap(
221
+ createListResultHandle(
222
+ EOps.EListReverse,
223
+ listTypeOf(elist.unwrap(list)),
224
+ lengthOf(elist.unwrap(list)),
225
+ abi.encodePacked(elist.unwrap(list))
226
+ )
227
+ );
228
+ allowTransientInternal(elist.unwrap(result), msg.sender);
229
+ emit EListReverse(list, result, getNewEventId());
230
+ }
231
+
232
+ }
@@ -0,0 +1,33 @@
1
+ /// SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {elist, ETypes} from "../TypesPreview.sol";
5
+ import {IEListHandleMetadata} from "./primitives/interfaces/IEListHandleMetadata.sol";
6
+
7
+ interface IEList is IEListHandleMetadata {
8
+
9
+ function newEList(bytes32[] memory handles, ETypes listType) external returns (elist newList);
10
+
11
+ function newEList(bytes[] memory inputs, ETypes listType, address user) external payable returns (elist newList);
12
+
13
+ function listAppend(elist list, bytes32 value) external returns (elist result);
14
+
15
+ function listGet(elist list, uint16 i) external returns (bytes32 result);
16
+
17
+ function listGetOr(elist list, bytes32 i, bytes32 defaultValue) external returns (bytes32 result);
18
+
19
+ function listSet(elist list, bytes32 i, bytes32 value) external returns (elist result);
20
+
21
+ function listInsert(elist list, bytes32 i, bytes32 value) external returns (elist result);
22
+
23
+ function listConcat(elist lhs, elist rhs) external returns (elist result);
24
+
25
+ function listSlice(elist list, bytes32 start, uint16 len, bytes32 defaultValue) external returns (elist result);
26
+
27
+ function listRange(uint16 start, uint16 end) external returns (elist result);
28
+
29
+ function listShuffle(elist list) external payable returns (elist result);
30
+
31
+ function listReverse(elist list) external returns (elist result);
32
+
33
+ }
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {ETypes, EOps} from "@inco/lightning/src/Types.sol";
5
+ import {HandleGeneration} from "@inco/lightning/src/lightning-parts/primitives/HandleGeneration.sol";
6
+ import {EListHandleMetadata} from "./EListHandleMetadata.sol";
7
+
8
+ contract EListHandleGeneration is HandleGeneration, EListHandleMetadata {
9
+
10
+ function createListResultHandle(EOps op, ETypes listType, uint16 len, bytes memory packedInputs)
11
+ internal
12
+ pure
13
+ returns (bytes32 result)
14
+ {
15
+ bytes32 baseHandle = keccak256(abi.encodePacked(op, packedInputs));
16
+ baseHandle = embedListLength(baseHandle, len);
17
+ baseHandle = embedListType(baseHandle, listType);
18
+ result = embedTypeVersion(baseHandle, ETypes.List);
19
+ }
20
+
21
+ function createListInputHandle(bytes32[] memory handles, ETypes listType)
22
+ internal
23
+ pure
24
+ returns (bytes32 newHandle)
25
+ {
26
+ newHandle = createListResultHandle(
27
+ EOps.NewEList,
28
+ listType,
29
+ uint16(handles.length),
30
+ abi.encodePacked(
31
+ //Since we're only dealing with handles, it should be sufficient to treat this operation as an operand on handles.
32
+ handles
33
+ )
34
+ );
35
+ }
36
+
37
+ }
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {ETypes} from "@inco/lightning/src/Types.sol";
5
+ import {IEListHandleMetadata} from "./interfaces/IEListHandleMetadata.sol";
6
+
7
+ contract EListHandleMetadata is IEListHandleMetadata {
8
+
9
+ function embedListLength(bytes32 prehandle, uint16 len) internal pure returns (bytes32 result) {
10
+ // 27 and 28 bits are used for the list length
11
+ result = prehandle & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff;
12
+ result = bytes32(uint256(result) | (uint256(len) << 24)); // append length
13
+ }
14
+
15
+ function lengthOf(bytes32 handle) public pure returns (uint16) {
16
+ return uint16(uint256(handle) >> 24);
17
+ }
18
+
19
+ function embedListType(bytes32 prehandle, ETypes listType) internal pure returns (bytes32 result) {
20
+ result = prehandle & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff;
21
+ result = bytes32(uint256(result) | (uint256(listType) << 16)); // append element type
22
+ }
23
+
24
+ function listTypeOf(bytes32 handle) internal pure returns (ETypes) {
25
+ return ETypes(uint8(uint256(handle) >> 16));
26
+ }
27
+
28
+ }
@@ -0,0 +1,8 @@
1
+ /// SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ interface IEListHandleMetadata {
5
+
6
+ function lengthOf(bytes32 handle) external pure returns (uint16);
7
+
8
+ }
@@ -0,0 +1,66 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {PreviewIncoTest} from "../../test/PreviewIncoTest.sol";
5
+ import {ElistTester} from "../../test/EListTester.sol";
6
+ import {incoPreview, ETypes, elist} from "../../Preview.Lib.sol";
7
+ import {FEE, Fee} from "@inco/lightning/src/lightning-parts/Fee.sol";
8
+ import {EList} from "../EList.sol";
9
+ import {VerifierAddressGetter} from "@inco/lightning/src/lightning-parts/primitives/VerifierAddressGetter.sol";
10
+
11
+ contract ElistFeeTester is EList {
12
+
13
+ constructor() VerifierAddressGetter(address(0)) {}
14
+
15
+ }
16
+
17
+ contract TestEList is PreviewIncoTest {
18
+
19
+ ElistTester tester;
20
+ ElistFeeTester feeTester;
21
+
22
+ function setUp() public virtual override {
23
+ super.setUp();
24
+ tester = new ElistTester(incoPreview);
25
+ vm.deal(address(tester), 1 ether);
26
+ feeTester = new ElistFeeTester();
27
+ }
28
+
29
+ function testNewElistFromInputs() public {
30
+ createList();
31
+ // todo test read the created list
32
+ }
33
+
34
+ function testListAppend() public {
35
+ createList();
36
+ bytes memory ctValue = fakePrepareEuint256Ciphertext(40, address(this), address(tester));
37
+ tester.listAppend(ctValue);
38
+ }
39
+
40
+ function createList() internal returns (elist list) {
41
+ bytes[] memory inputs = new bytes[](3);
42
+ inputs[0] = fakePrepareEuint256Ciphertext(10, address(this), address(tester));
43
+ inputs[1] = fakePrepareEuint256Ciphertext(20, address(this), address(tester));
44
+ inputs[2] = fakePrepareEuint256Ciphertext(30, address(this), address(tester));
45
+ list = tester.newEList(inputs, ETypes.Uint256, address(this));
46
+ }
47
+
48
+ function testRevertsOnBadFeeAmount() public {
49
+ // should fail if no fee
50
+ vm.expectRevert(Fee.FeeNotPaid.selector);
51
+ feeTester.listShuffle(elist.wrap(bytes32(0)));
52
+
53
+ // should fail if not enough fee
54
+ vm.expectRevert(Fee.FeeNotPaid.selector);
55
+ feeTester.listShuffle{value: FEE - 1}(elist.wrap(bytes32(0)));
56
+
57
+ // should fail if too much fee
58
+ vm.expectRevert(Fee.FeeNotPaid.selector);
59
+ feeTester.listShuffle{value: FEE + 1}(elist.wrap(bytes32(0)));
60
+
61
+ vm.expectRevert(Fee.FeeNotPaid.selector);
62
+ bytes[] memory inputs = new bytes[](3);
63
+ feeTester.newEList{value: FEE * 2}(inputs, ETypes.Uint256, address(this));
64
+ }
65
+
66
+ }
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {Session} from "@inco/lightning/src/periphery/SessionVerifier.sol";
5
+
6
+ // @dev this contract is not used on-chain, it is only used to generate the
7
+ // ABI of some symbols that are not exposed directly by the IncoLightning or
8
+ // periphery contracts, but are needed for the JS SDK.
9
+ contract ABIHelper {
10
+
11
+ function getSession() public pure returns (Session memory) {
12
+ revert("This function exists only to include Session struct in ABI");
13
+ }
14
+
15
+ }
@@ -0,0 +1,148 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IIncoLightningPreview} from "../IIncoLightningPreview.sol";
5
+ /// forge-lint: disable-next-line(unused-import)
6
+ import {ETypes, elist} from "../TypesPreview.sol";
7
+ import {euint256} from "@inco/lightning/src/Types.sol";
8
+ import {Fee, FEE} from "@inco/lightning/src/lightning-parts/Fee.sol";
9
+
10
+ contract ElistTester is Fee {
11
+
12
+ /// forge-lint: disable-next-line(screaming-snake-case-immutable)
13
+ IIncoLightningPreview immutable inco;
14
+
15
+ constructor(IIncoLightningPreview _inco) {
16
+ inco = _inco;
17
+ }
18
+
19
+ elist public list;
20
+ elist public newRangeList;
21
+
22
+ function newEList(bytes[] memory inputs, ETypes listType, address user)
23
+ public
24
+ payable
25
+ refundUnspent
26
+ returns (elist)
27
+ {
28
+ list = inco.newEList{value: FEE * inputs.length}(inputs, listType, user);
29
+ inco.allow(elist.unwrap(list), address(this));
30
+ inco.allow(elist.unwrap(list), address(msg.sender));
31
+ return list;
32
+ }
33
+
34
+ function listAppend(bytes memory ctValue) public payable refundUnspent returns (elist) {
35
+ euint256 handle = inco.newEuint256{value: FEE}(ctValue, msg.sender);
36
+ inco.allow(euint256.unwrap(handle), address(this));
37
+ inco.allow(euint256.unwrap(handle), address(msg.sender));
38
+ list = inco.listAppend(list, euint256.unwrap(handle));
39
+ inco.allow(elist.unwrap(list), address(this));
40
+ inco.allow(elist.unwrap(list), address(msg.sender));
41
+ return list;
42
+ }
43
+
44
+ function listGet(uint16 index) public returns (bytes32) {
45
+ bytes32 res = inco.listGet(list, index);
46
+ inco.allow(res, msg.sender);
47
+ return res;
48
+ }
49
+
50
+ function newEList(bytes32[] memory handles, ETypes listType) public payable refundUnspent returns (elist) {
51
+ list = inco.newEList(handles, listType);
52
+ inco.allow(elist.unwrap(list), address(this));
53
+ inco.allow(elist.unwrap(list), address(msg.sender));
54
+ return list;
55
+ }
56
+
57
+ function listGetOr(bytes memory ctIndex, bytes memory ctDefaultValue)
58
+ public
59
+ payable
60
+ refundUnspent
61
+ returns (bytes32)
62
+ {
63
+ euint256 index = inco.newEuint256{value: FEE}(ctIndex, msg.sender);
64
+ euint256 defaultValue = inco.newEuint256{value: FEE}(ctDefaultValue, msg.sender);
65
+ bytes32 res = inco.listGetOr(list, euint256.unwrap(index), euint256.unwrap(defaultValue));
66
+ inco.allow(res, msg.sender);
67
+ return res;
68
+ }
69
+
70
+ function listSet(bytes memory ctIndex, bytes memory ctValue) public payable refundUnspent returns (elist) {
71
+ euint256 index = inco.newEuint256{value: FEE}(ctIndex, msg.sender);
72
+ euint256 value = inco.newEuint256{value: FEE}(ctValue, msg.sender);
73
+ list = inco.listSet(list, euint256.unwrap(index), euint256.unwrap(value));
74
+ inco.allow(elist.unwrap(list), address(this));
75
+ inco.allow(elist.unwrap(list), address(msg.sender));
76
+ return list;
77
+ }
78
+
79
+ function listInsert(bytes memory ctIndex, bytes memory ctValue) public payable refundUnspent returns (elist) {
80
+ euint256 index = inco.newEuint256{value: FEE}(ctIndex, msg.sender);
81
+ euint256 value = inco.newEuint256{value: FEE}(ctValue, msg.sender);
82
+ list = inco.listInsert(list, euint256.unwrap(index), euint256.unwrap(value));
83
+ inco.allow(elist.unwrap(list), address(this));
84
+ inco.allow(elist.unwrap(list), address(msg.sender));
85
+ return list;
86
+ }
87
+
88
+ function listConcat(bytes[] memory cts, ETypes listType, address user)
89
+ public
90
+ payable
91
+ refundUnspent
92
+ returns (elist)
93
+ {
94
+ elist rhs = inco.newEList{value: FEE * cts.length}(cts, listType, user);
95
+ inco.allow(elist.unwrap(rhs), address(this));
96
+ inco.allow(elist.unwrap(rhs), address(msg.sender));
97
+ list = inco.listConcat(list, rhs);
98
+ inco.allow(elist.unwrap(list), address(this));
99
+ inco.allow(elist.unwrap(list), address(msg.sender));
100
+ return list;
101
+ }
102
+
103
+ function listSlice(bytes memory ctStart, uint16 len, bytes memory ctDefaultValue)
104
+ public
105
+ payable
106
+ refundUnspent
107
+ returns (elist)
108
+ {
109
+ euint256 start = inco.newEuint256{value: FEE}(ctStart, msg.sender);
110
+ euint256 defaultValue = inco.newEuint256{value: FEE}(ctDefaultValue, msg.sender);
111
+ list = inco.listSlice(list, euint256.unwrap(start), len, euint256.unwrap(defaultValue));
112
+ inco.allow(elist.unwrap(list), address(this));
113
+ inco.allow(elist.unwrap(list), address(msg.sender));
114
+ return list;
115
+ }
116
+
117
+ function listRange(uint16 start, uint16 end) public returns (elist) {
118
+ newRangeList = inco.listRange(start, end);
119
+ inco.allow(elist.unwrap(newRangeList), address(this));
120
+ inco.allow(elist.unwrap(newRangeList), address(msg.sender));
121
+ return newRangeList;
122
+ }
123
+
124
+ function listGetRange(uint16 index) public returns (bytes32) {
125
+ bytes32 res = inco.listGet(newRangeList, index);
126
+ inco.allow(res, msg.sender);
127
+ return res;
128
+ }
129
+
130
+ function listShuffle() public payable refundUnspent returns (elist) {
131
+ list = inco.listShuffle{value: FEE}(list);
132
+ inco.allow(elist.unwrap(list), address(this));
133
+ inco.allow(elist.unwrap(list), address(msg.sender));
134
+ return list;
135
+ }
136
+
137
+ function listReverse() public returns (elist) {
138
+ list = inco.listReverse(list);
139
+ inco.allow(elist.unwrap(list), address(this));
140
+ inco.allow(elist.unwrap(list), address(msg.sender));
141
+ return list;
142
+ }
143
+
144
+ receive() external payable {
145
+ // Allow contract to receive ETH
146
+ }
147
+
148
+ }
@@ -0,0 +1,32 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {IncoTest} from "@inco/lightning/src/test/IncoTest.sol";
5
+ import {CONTRACT_NAME, MAJOR_VERSION} from "@inco/lightning/src/version/IncoLightningConfig.sol";
6
+ import {IncoLightningPreview} from "../IncoLightningPreview.sol";
7
+ import {inco} from "@inco/lightning/src/Lib.sol";
8
+ import {console} from "forge-std/console.sol";
9
+ import {IncoLightning} from "@inco/lightning/src/IncoLightning.sol";
10
+
11
+ contract PreviewIncoTest is IncoTest {
12
+
13
+ function setUp() public virtual override {
14
+ super.setUp();
15
+ bytes32 salt = getSalt(CONTRACT_NAME, MAJOR_VERSION, testDeployer, "");
16
+
17
+ IncoLightningPreview newImplem = new IncoLightningPreview(
18
+ // a new inco lightning instance is used a fallback implem for non preview features
19
+ address(new IncoLightning(salt, inco.incoVerifier())),
20
+ address(inco.incoVerifier())
21
+ );
22
+ vm.prank(owner);
23
+ inco.upgradeToAndCall(address(newImplem), "");
24
+ console.log("inco address is %s", vm.toString(address(inco)));
25
+ vm.getRecordedLogs(); // clear the upgrade log
26
+ }
27
+
28
+ function testExample() public pure {
29
+ return;
30
+ }
31
+
32
+ }