@inco/lightning 0.8.0-devnet-4 → 0.8.0-devnet-5
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 +59 -1
- package/manifest.yaml +22 -0
- package/package.json +1 -1
- package/src/DeployUtils.sol +71 -25
- package/src/IncoLightning.sol +27 -7
- package/src/IncoVerifier.sol +18 -1
- package/src/Lib.alphanet.sol +390 -3
- package/src/Lib.demonet.sol +390 -3
- package/src/Lib.devnet.sol +391 -4
- package/src/Lib.sol +391 -4
- package/src/Lib.template.sol +387 -0
- package/src/Lib.testnet.sol +390 -3
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +390 -3
- package/src/libs/incoLightning_alphanet_v1_725458969.sol +390 -3
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +390 -3
- package/src/libs/incoLightning_demonet_v0_863421733.sol +390 -3
- package/src/libs/incoLightning_demonet_v2_467437523.sol +390 -3
- package/src/libs/incoLightning_devnet_v0_340846814.sol +390 -3
- package/src/libs/incoLightning_devnet_v1_904635675.sol +390 -3
- package/src/libs/incoLightning_devnet_v2_295237520.sol +390 -3
- package/src/libs/incoLightning_devnet_v3_976859633.sol +390 -3
- package/src/libs/incoLightning_devnet_v4_409204766.sol +921 -0
- package/src/libs/incoLightning_testnet_v0_183408998.sol +390 -3
- package/src/libs/incoLightning_testnet_v2_889158349.sol +390 -3
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +65 -4
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +71 -5
- package/src/lightning-parts/DecryptionAttester.sol +16 -3
- package/src/lightning-parts/EncryptedInput.sol +48 -2
- package/src/lightning-parts/EncryptedOperations.sol +134 -1
- package/src/lightning-parts/Fee.sol +29 -6
- package/src/lightning-parts/primitives/EventCounter.sol +36 -5
- package/src/lightning-parts/primitives/HandleGeneration.sol +38 -6
- package/src/lightning-parts/primitives/HandleMetadata.sol +28 -0
- package/src/lightning-parts/primitives/LightningAddressGetter.sol +10 -0
- package/src/lightning-parts/primitives/VerifierAddressGetter.sol +10 -0
- package/src/lightning-parts/primitives/test/SignatureVerifier.t.sol +0 -2
- package/src/periphery/IncoUtils.sol +1 -0
- package/src/periphery/SessionVerifier.sol +35 -7
- package/src/test/TestFakeInfra.t.sol +536 -1
- package/src/version/IncoLightningConfig.sol +2 -2
|
@@ -7,9 +7,21 @@ import {HandleGeneration} from "./primitives/HandleGeneration.sol";
|
|
|
7
7
|
import {IEncryptedOperations} from "./interfaces/IEncryptedOperations.sol";
|
|
8
8
|
import {Fee} from "./Fee.sol";
|
|
9
9
|
|
|
10
|
+
/// @title EncryptedOperations
|
|
11
|
+
/// @notice Provides operations on encrypted values.
|
|
12
|
+
/// @dev All operations require the caller to have access to the input handles. Results are granted
|
|
13
|
+
/// transient access to the caller. Each operation emits an event that is processed by the covalidator
|
|
14
|
+
/// to perform the actual computation off-chain. The result handle is deterministically derived
|
|
15
|
+
/// from the operation and inputs, enabling consistent state across chains.
|
|
10
16
|
abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControlList, HandleGeneration, Fee {
|
|
11
17
|
|
|
18
|
+
/// @notice Thrown when an operation receives a handle of an unexpected type.
|
|
19
|
+
/// @param actual The actual type of the handle.
|
|
20
|
+
/// @param expectedTypes A bitmask of the expected types.
|
|
12
21
|
error UnexpectedType(ETypes actual, bytes32 expectedTypes);
|
|
22
|
+
|
|
23
|
+
/// @notice Thrown when an operation receives an unsupported type.
|
|
24
|
+
/// @param actual The unsupported type.
|
|
13
25
|
error UnsupportedType(ETypes actual);
|
|
14
26
|
|
|
15
27
|
uint256 internal randCounter;
|
|
@@ -55,17 +67,26 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
55
67
|
event ENot(ebool indexed operand, ebool indexed result, uint256 eventId);
|
|
56
68
|
event ECast(bytes32 indexed ct, uint8 indexed toType, bytes32 indexed result, uint256 eventId);
|
|
57
69
|
|
|
70
|
+
/// @dev Validates that both inputs are euint256 and the caller has access to them.
|
|
58
71
|
modifier checked(euint256 lhs, euint256 rhs) {
|
|
59
72
|
checkInput(euint256.unwrap(lhs), typeToBitMask(ETypes.Uint256));
|
|
60
73
|
checkInput(euint256.unwrap(rhs), typeToBitMask(ETypes.Uint256));
|
|
61
74
|
_;
|
|
62
75
|
}
|
|
63
76
|
|
|
77
|
+
/// @dev Validates that the caller has access to the input handle and that its type matches the required types.
|
|
78
|
+
/// @param input The handle to validate.
|
|
79
|
+
/// @param requiredTypes A bitmask of acceptable types for this input.
|
|
64
80
|
function checkInput(bytes32 input, bytes32 requiredTypes) internal view {
|
|
65
81
|
require(isAllowed(input, msg.sender), SenderNotAllowedForHandle(input, msg.sender));
|
|
66
82
|
require(requiredTypes & typeToBitMask(typeOf(input)) != 0, UnexpectedType(typeOf(input), requiredTypes));
|
|
67
83
|
}
|
|
68
84
|
|
|
85
|
+
/// @dev Creates a result handle for an operation and grants transient access to the caller.
|
|
86
|
+
/// @param op The operation type.
|
|
87
|
+
/// @param returnType The type of the result handle.
|
|
88
|
+
/// @param packedInputs The packed input handles.
|
|
89
|
+
/// @return result The generated result handle.
|
|
69
90
|
function createResultHandle(EOps op, ETypes returnType, bytes memory packedInputs)
|
|
70
91
|
internal
|
|
71
92
|
returns (bytes32 result)
|
|
@@ -74,6 +95,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
74
95
|
allowTransientInternal(result, msg.sender);
|
|
75
96
|
}
|
|
76
97
|
|
|
98
|
+
/// @notice Adds two encrypted uint256 values.
|
|
99
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
100
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
101
|
+
/// @return result The encrypted sum (lhs + rhs).
|
|
77
102
|
function eAdd(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
78
103
|
result = euint256.wrap(
|
|
79
104
|
createResultHandle(EOps.Add, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -83,6 +108,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
83
108
|
setDigest(abi.encodePacked(result, id));
|
|
84
109
|
}
|
|
85
110
|
|
|
111
|
+
/// @notice Subtracts one encrypted uint256 from another.
|
|
112
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
113
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
114
|
+
/// @return result The encrypted difference (lhs - rhs).
|
|
86
115
|
function eSub(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
87
116
|
result = euint256.wrap(
|
|
88
117
|
createResultHandle(EOps.Sub, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -92,6 +121,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
92
121
|
setDigest(abi.encodePacked(result, id));
|
|
93
122
|
}
|
|
94
123
|
|
|
124
|
+
/// @notice Multiplies two encrypted uint256 values.
|
|
125
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
126
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
127
|
+
/// @return result The encrypted product (lhs * rhs).
|
|
95
128
|
function eMul(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
96
129
|
result = euint256.wrap(
|
|
97
130
|
createResultHandle(EOps.Mul, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -101,6 +134,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
101
134
|
setDigest(abi.encodePacked(result, id));
|
|
102
135
|
}
|
|
103
136
|
|
|
137
|
+
/// @notice Divides one encrypted uint256 by another.
|
|
138
|
+
/// @dev Division by zero returns zero.
|
|
139
|
+
/// @param lhs The dividend (encrypted).
|
|
140
|
+
/// @param rhs The divisor (encrypted).
|
|
141
|
+
/// @return result The encrypted quotient (lhs / rhs).
|
|
104
142
|
function eDiv(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
105
143
|
result = euint256.wrap(
|
|
106
144
|
createResultHandle(EOps.Div, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -110,6 +148,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
110
148
|
setDigest(abi.encodePacked(result, id));
|
|
111
149
|
}
|
|
112
150
|
|
|
151
|
+
/// @notice Computes the remainder of dividing one encrypted uint256 by another.
|
|
152
|
+
/// @dev Remainder by zero returns zero.
|
|
153
|
+
/// @param lhs The dividend (encrypted).
|
|
154
|
+
/// @param rhs The divisor (encrypted).
|
|
155
|
+
/// @return result The encrypted remainder (lhs % rhs).
|
|
113
156
|
function eRem(euint256 lhs, euint256 rhs) external virtual checked(lhs, rhs) returns (euint256 result) {
|
|
114
157
|
result = euint256.wrap(
|
|
115
158
|
createResultHandle(EOps.Rem, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -119,6 +162,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
119
162
|
setDigest(abi.encodePacked(result, id));
|
|
120
163
|
}
|
|
121
164
|
|
|
165
|
+
/// @notice Performs bitwise AND on two encrypted values of the same type.
|
|
166
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
167
|
+
/// @param rhs The right-hand side encrypted operand (must be same type as lhs).
|
|
168
|
+
/// @return result The encrypted bitwise AND result.
|
|
122
169
|
function eBitAnd(bytes32 lhs, bytes32 rhs) external returns (bytes32 result) {
|
|
123
170
|
ETypes lhsType = typeOf(lhs);
|
|
124
171
|
ETypes rhsType = typeOf(rhs);
|
|
@@ -131,6 +178,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
131
178
|
setDigest(abi.encodePacked(result, id));
|
|
132
179
|
}
|
|
133
180
|
|
|
181
|
+
/// @notice Performs bitwise OR on two encrypted values of the same type.
|
|
182
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
183
|
+
/// @param rhs The right-hand side encrypted operand (must be same type as lhs).
|
|
184
|
+
/// @return result The encrypted bitwise OR result.
|
|
134
185
|
function eBitOr(bytes32 lhs, bytes32 rhs) external returns (bytes32 result) {
|
|
135
186
|
ETypes lhsType = typeOf(lhs);
|
|
136
187
|
ETypes rhsType = typeOf(rhs);
|
|
@@ -143,6 +194,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
143
194
|
setDigest(abi.encodePacked(result, id));
|
|
144
195
|
}
|
|
145
196
|
|
|
197
|
+
/// @notice Performs bitwise XOR on two encrypted values of the same type.
|
|
198
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
199
|
+
/// @param rhs The right-hand side encrypted operand (must be same type as lhs).
|
|
200
|
+
/// @return result The encrypted bitwise XOR result.
|
|
146
201
|
function eBitXor(bytes32 lhs, bytes32 rhs) external returns (bytes32 result) {
|
|
147
202
|
ETypes lhsType = typeOf(lhs);
|
|
148
203
|
ETypes rhsType = typeOf(rhs);
|
|
@@ -155,6 +210,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
155
210
|
setDigest(abi.encodePacked(result, id));
|
|
156
211
|
}
|
|
157
212
|
|
|
213
|
+
/// @notice Shifts an encrypted uint256 left by an encrypted number of bits.
|
|
214
|
+
/// @param lhs The value to shift (encrypted).
|
|
215
|
+
/// @param rhs The number of bits to shift by (encrypted).
|
|
216
|
+
/// @return result The encrypted left-shifted result.
|
|
158
217
|
function eShl(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
159
218
|
result = euint256.wrap(
|
|
160
219
|
createResultHandle(EOps.Shl, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -164,6 +223,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
164
223
|
setDigest(abi.encodePacked(result, id));
|
|
165
224
|
}
|
|
166
225
|
|
|
226
|
+
/// @notice Shifts an encrypted uint256 right by an encrypted number of bits.
|
|
227
|
+
/// @param lhs The value to shift (encrypted).
|
|
228
|
+
/// @param rhs The number of bits to shift by (encrypted).
|
|
229
|
+
/// @return result The encrypted right-shifted result.
|
|
167
230
|
function eShr(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
168
231
|
result = euint256.wrap(
|
|
169
232
|
createResultHandle(EOps.Shr, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -173,6 +236,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
173
236
|
setDigest(abi.encodePacked(result, id));
|
|
174
237
|
}
|
|
175
238
|
|
|
239
|
+
/// @notice Rotates an encrypted uint256 left by an encrypted number of bits.
|
|
240
|
+
/// @param lhs The value to rotate (encrypted).
|
|
241
|
+
/// @param rhs The number of bits to rotate by (encrypted).
|
|
242
|
+
/// @return result The encrypted left-rotated result.
|
|
176
243
|
function eRotl(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
177
244
|
result = euint256.wrap(
|
|
178
245
|
createResultHandle(EOps.Rotl, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -182,6 +249,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
182
249
|
setDigest(abi.encodePacked(result, id));
|
|
183
250
|
}
|
|
184
251
|
|
|
252
|
+
/// @notice Rotates an encrypted uint256 right by an encrypted number of bits.
|
|
253
|
+
/// @param lhs The value to rotate (encrypted).
|
|
254
|
+
/// @param rhs The number of bits to rotate by (encrypted).
|
|
255
|
+
/// @return result The encrypted right-rotated result.
|
|
185
256
|
function eRotr(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
186
257
|
result = euint256.wrap(
|
|
187
258
|
createResultHandle(EOps.Rotr, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -191,6 +262,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
191
262
|
setDigest(abi.encodePacked(result, id));
|
|
192
263
|
}
|
|
193
264
|
|
|
265
|
+
/// @notice Checks if two encrypted values are equal.
|
|
266
|
+
/// @dev Supports euint256, ebool, and eaddress types.
|
|
267
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
268
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
269
|
+
/// @return result An encrypted boolean (true if lhs == rhs).
|
|
194
270
|
function eEq(bytes32 lhs, bytes32 rhs) external returns (ebool result) {
|
|
195
271
|
checkInput(lhs, SUPPORTED_TYPES_MASK);
|
|
196
272
|
checkInput(rhs, SUPPORTED_TYPES_MASK);
|
|
@@ -201,6 +277,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
201
277
|
setDigest(abi.encodePacked(result, id));
|
|
202
278
|
}
|
|
203
279
|
|
|
280
|
+
/// @notice Checks if two encrypted values are not equal.
|
|
281
|
+
/// @dev Supports euint256, ebool, and eaddress types.
|
|
282
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
283
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
284
|
+
/// @return result An encrypted boolean (true if lhs != rhs).
|
|
204
285
|
function eNe(bytes32 lhs, bytes32 rhs) external returns (ebool result) {
|
|
205
286
|
checkInput(lhs, SUPPORTED_TYPES_MASK);
|
|
206
287
|
checkInput(rhs, SUPPORTED_TYPES_MASK);
|
|
@@ -211,6 +292,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
211
292
|
setDigest(abi.encodePacked(result, id));
|
|
212
293
|
}
|
|
213
294
|
|
|
295
|
+
/// @notice Checks if lhs is greater than or equal to rhs.
|
|
296
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
297
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
298
|
+
/// @return result An encrypted boolean (true if lhs >= rhs).
|
|
214
299
|
function eGe(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (ebool result) {
|
|
215
300
|
result = ebool.wrap(
|
|
216
301
|
createResultHandle(EOps.Ge, ETypes.Bool, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -220,6 +305,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
220
305
|
setDigest(abi.encodePacked(result, id));
|
|
221
306
|
}
|
|
222
307
|
|
|
308
|
+
/// @notice Checks if lhs is greater than rhs.
|
|
309
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
310
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
311
|
+
/// @return result An encrypted boolean (true if lhs > rhs).
|
|
223
312
|
function eGt(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (ebool result) {
|
|
224
313
|
result = ebool.wrap(
|
|
225
314
|
createResultHandle(EOps.Gt, ETypes.Bool, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -229,6 +318,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
229
318
|
setDigest(abi.encodePacked(result, id));
|
|
230
319
|
}
|
|
231
320
|
|
|
321
|
+
/// @notice Checks if lhs is less than or equal to rhs.
|
|
322
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
323
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
324
|
+
/// @return result An encrypted boolean (true if lhs <= rhs).
|
|
232
325
|
function eLe(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (ebool result) {
|
|
233
326
|
result = ebool.wrap(
|
|
234
327
|
createResultHandle(EOps.Le, ETypes.Bool, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -238,6 +331,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
238
331
|
setDigest(abi.encodePacked(result, id));
|
|
239
332
|
}
|
|
240
333
|
|
|
334
|
+
/// @notice Checks if lhs is less than rhs.
|
|
335
|
+
/// @param lhs The left-hand side encrypted operand.
|
|
336
|
+
/// @param rhs The right-hand side encrypted operand.
|
|
337
|
+
/// @return result An encrypted boolean (true if lhs < rhs).
|
|
241
338
|
function eLt(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (ebool result) {
|
|
242
339
|
result = ebool.wrap(
|
|
243
340
|
createResultHandle(EOps.Lt, ETypes.Bool, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -247,6 +344,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
247
344
|
setDigest(abi.encodePacked(result, id));
|
|
248
345
|
}
|
|
249
346
|
|
|
347
|
+
/// @notice Returns the minimum of two encrypted uint256 values.
|
|
348
|
+
/// @param lhs The first encrypted value.
|
|
349
|
+
/// @param rhs The second encrypted value.
|
|
350
|
+
/// @return result The encrypted minimum value.
|
|
250
351
|
function eMin(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
251
352
|
result = euint256.wrap(
|
|
252
353
|
createResultHandle(EOps.Min, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -256,6 +357,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
256
357
|
setDigest(abi.encodePacked(result, id));
|
|
257
358
|
}
|
|
258
359
|
|
|
360
|
+
/// @notice Returns the maximum of two encrypted uint256 values.
|
|
361
|
+
/// @param lhs The first encrypted value.
|
|
362
|
+
/// @param rhs The second encrypted value.
|
|
363
|
+
/// @return result The encrypted maximum value.
|
|
259
364
|
function eMax(euint256 lhs, euint256 rhs) external checked(lhs, rhs) returns (euint256 result) {
|
|
260
365
|
result = euint256.wrap(
|
|
261
366
|
createResultHandle(EOps.Max, ETypes.Uint256, abi.encodePacked(euint256.unwrap(lhs), euint256.unwrap(rhs)))
|
|
@@ -265,6 +370,9 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
265
370
|
setDigest(abi.encodePacked(result, id));
|
|
266
371
|
}
|
|
267
372
|
|
|
373
|
+
/// @notice Performs logical NOT on an encrypted boolean.
|
|
374
|
+
/// @param operand The encrypted boolean to negate.
|
|
375
|
+
/// @return result The negated encrypted boolean.
|
|
268
376
|
function eNot(ebool operand) external returns (ebool result) {
|
|
269
377
|
checkInput(ebool.unwrap(operand), typeToBitMask(ETypes.Bool));
|
|
270
378
|
result = ebool.wrap(createResultHandle(EOps.Not, ETypes.Bool, abi.encodePacked(ebool.unwrap(operand))));
|
|
@@ -273,6 +381,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
273
381
|
setDigest(abi.encodePacked(result, id));
|
|
274
382
|
}
|
|
275
383
|
|
|
384
|
+
/// @notice Casts an encrypted value to a different encrypted type.
|
|
385
|
+
/// @dev Supports casting between euint256, ebool, and eaddress.
|
|
386
|
+
/// @param ct The encrypted value to cast.
|
|
387
|
+
/// @param toType The target type to cast to.
|
|
388
|
+
/// @return result The casted encrypted value.
|
|
276
389
|
function eCast(bytes32 ct, ETypes toType) external returns (bytes32 result) {
|
|
277
390
|
checkInput(ct, SUPPORTED_TYPES_MASK);
|
|
278
391
|
require(isTypeSupported(toType), UnsupportedType(toType));
|
|
@@ -283,6 +396,10 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
283
396
|
setDigest(abi.encodePacked(result, id));
|
|
284
397
|
}
|
|
285
398
|
|
|
399
|
+
/// @notice Generates an encrypted random value of the specified type.
|
|
400
|
+
/// @dev This is a paid operation.
|
|
401
|
+
/// @param randType The type of random value to generate.
|
|
402
|
+
/// @return result An encrypted random value.
|
|
286
403
|
function eRand(ETypes randType) external payable paying returns (bytes32 result) {
|
|
287
404
|
require(isTypeSupported(randType), UnsupportedType(randType));
|
|
288
405
|
randCounter++;
|
|
@@ -292,6 +409,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
292
409
|
setDigest(abi.encodePacked(result, id));
|
|
293
410
|
}
|
|
294
411
|
|
|
412
|
+
/// @notice Generates an encrypted random value bounded by an upper limit.
|
|
413
|
+
/// @dev This is a paid operation. The result is in the range [0, upperBound).
|
|
414
|
+
/// @param upperBound The encrypted upper bound (exclusive).
|
|
415
|
+
/// @param randType The type of random value to generate.
|
|
416
|
+
/// @return result An encrypted random value less than upperBound.
|
|
295
417
|
function eRandBounded(bytes32 upperBound, ETypes randType) external payable paying returns (bytes32 result) {
|
|
296
418
|
require(isTypeSupported(randType), UnsupportedType(randType));
|
|
297
419
|
checkInput(upperBound, typeToBitMask(ETypes.Uint256));
|
|
@@ -302,7 +424,13 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
302
424
|
setDigest(abi.encodePacked(result, id));
|
|
303
425
|
}
|
|
304
426
|
|
|
305
|
-
|
|
427
|
+
/// @notice Selects between two encrypted values based on an encrypted condition.
|
|
428
|
+
/// @dev Returns ifTrue if control is true, otherwise returns ifFalse.
|
|
429
|
+
/// Both ifTrue and ifFalse must be the same type.
|
|
430
|
+
/// @param control The encrypted boolean condition.
|
|
431
|
+
/// @param ifTrue The value to return if control is true.
|
|
432
|
+
/// @param ifFalse The value to return if control is false.
|
|
433
|
+
/// @return result The selected encrypted value.
|
|
306
434
|
function eIfThenElse(ebool control, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32 result) {
|
|
307
435
|
ETypes returnType = checkEIfThenElseInputs(control, ifTrue, ifFalse);
|
|
308
436
|
result =
|
|
@@ -313,6 +441,11 @@ abstract contract EncryptedOperations is IEncryptedOperations, BaseAccessControl
|
|
|
313
441
|
setDigest(abi.encodePacked(result, id));
|
|
314
442
|
}
|
|
315
443
|
|
|
444
|
+
/// @dev Validates inputs for eIfThenElse operation.
|
|
445
|
+
/// @param control The encrypted boolean condition (must be ebool).
|
|
446
|
+
/// @param ifTrue The value to return if control is true.
|
|
447
|
+
/// @param ifFalse The value to return if control is false (must match ifTrue type).
|
|
448
|
+
/// @return ifTrueType The type of the ifTrue/ifFalse values.
|
|
316
449
|
function checkEIfThenElseInputs(ebool control, bytes32 ifTrue, bytes32 ifFalse)
|
|
317
450
|
internal
|
|
318
451
|
view
|
|
@@ -1,34 +1,57 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/// @dev The current fee required for paid encryption operations.
|
|
5
|
+
/// This constant may be modified through contract upgrades.
|
|
6
|
+
/// Developers should call getFee() rather than hardcoding this value.
|
|
5
7
|
uint256 constant FEE = 0.000001 ether;
|
|
6
8
|
|
|
7
|
-
/// @
|
|
8
|
-
/// @
|
|
9
|
+
/// @title Fee
|
|
10
|
+
/// @notice Fee management utilities for encryption operations that require payment
|
|
11
|
+
/// @dev Certain operations (encrypted inputs, randomness) require a fee to cover covalidator costs.
|
|
12
|
+
/// The fee is paid via msg.value and accumulates in the contract balance.
|
|
13
|
+
/// The contract owner can withdraw accumulated fees via withdrawFees() in IncoLightning.
|
|
14
|
+
///
|
|
15
|
+
/// Important: The fee amount may change through contract upgrades. Always use getFee()
|
|
16
|
+
/// to determine the current fee rather than hardcoding values.
|
|
9
17
|
abstract contract Fee {
|
|
10
18
|
|
|
19
|
+
/// @notice Thrown when the exact required fee is not paid
|
|
11
20
|
error FeeNotPaid();
|
|
21
|
+
|
|
22
|
+
/// @notice Thrown when the ETH transfer during fee withdrawal fails
|
|
12
23
|
error FeeWithdrawalFailed();
|
|
24
|
+
|
|
25
|
+
/// @notice Thrown when attempting to withdraw with zero balance
|
|
13
26
|
error NoFeesToWithdraw();
|
|
14
27
|
|
|
15
|
-
/// @notice the fee
|
|
28
|
+
/// @notice Returns the fee required for paid operations
|
|
29
|
+
/// @dev The fee may change through contract upgrades. Always query this function
|
|
30
|
+
/// to get the current fee rather than caching the value.
|
|
31
|
+
/// @return The fee amount in wei
|
|
16
32
|
function getFee() public pure returns (uint256) {
|
|
17
33
|
return FEE;
|
|
18
34
|
}
|
|
19
35
|
|
|
36
|
+
/// @notice Modifier that requires the exact fee to be paid via msg.value
|
|
37
|
+
/// @dev Use this modifier on functions that require a single fee payment (e.g., single input)
|
|
20
38
|
modifier paying() {
|
|
21
39
|
require(msg.value == FEE, FeeNotPaid());
|
|
22
40
|
_;
|
|
23
41
|
}
|
|
24
42
|
|
|
43
|
+
/// @notice Modifier that requires multiple fees to be paid via msg.value
|
|
44
|
+
/// @dev Use this modifier on functions that require payment for multiple operations (e.g., batch inputs)
|
|
45
|
+
/// @param nbOfFees The number of fee units required (total cost = FEE * nbOfFees)
|
|
25
46
|
modifier payingMultiple(uint256 nbOfFees) {
|
|
26
47
|
require(msg.value == FEE * nbOfFees, FeeNotPaid());
|
|
27
48
|
_;
|
|
28
49
|
}
|
|
29
50
|
|
|
30
|
-
/// @notice
|
|
31
|
-
/// @
|
|
51
|
+
/// @notice Withdraws all accumulated fees to the specified recipient
|
|
52
|
+
/// @dev Internal function called by IncoLightning.withdrawFees(). Transfers the entire
|
|
53
|
+
/// contract balance to the recipient.
|
|
54
|
+
/// @param recipient The address to send the accumulated fees to
|
|
32
55
|
function _withdrawFeesTo(address recipient) internal {
|
|
33
56
|
uint256 fees = address(this).balance;
|
|
34
57
|
require(fees > 0, NoFeesToWithdraw());
|
|
@@ -3,15 +3,25 @@ pragma solidity ^0.8;
|
|
|
3
3
|
|
|
4
4
|
import {IEventCounter} from "./interfaces/IEventCounter.sol";
|
|
5
5
|
|
|
6
|
+
/// @title EventCounterStorage
|
|
7
|
+
/// @notice Diamond storage pattern for the event counter state
|
|
8
|
+
/// @dev Uses a unique storage slot to avoid conflicts with other contracts in the inheritance chain.
|
|
9
|
+
/// The event counter provides unique, sequential identifiers for encrypted operations within a transaction.
|
|
6
10
|
contract EventCounterStorage {
|
|
7
11
|
|
|
12
|
+
/// @notice Storage struct containing the event counter state
|
|
13
|
+
/// @dev eventCounter is incremented for each encrypted operation to ensure unique handle generation
|
|
8
14
|
struct Storage {
|
|
9
|
-
|
|
10
|
-
uint256 eventCounter;
|
|
15
|
+
/// @notice Counter that increments for each event, or stores a digest for batch operations
|
|
16
|
+
uint256 eventCounter; // TODO: change type to bytes32 when we rename away from "counter".
|
|
11
17
|
}
|
|
12
18
|
|
|
19
|
+
/// @notice Storage slot location using keccak256 of a unique namespace string
|
|
13
20
|
bytes32 private constant EVENT_COUNTER_STORAGE_LOCATION = keccak256("lightning.storage.EventCounter");
|
|
14
21
|
|
|
22
|
+
/// @notice Retrieves the storage struct from its dedicated slot
|
|
23
|
+
/// @dev Uses assembly to directly access the storage slot for gas efficiency
|
|
24
|
+
/// @return $ Reference to the Storage struct
|
|
15
25
|
function getEventCounterStorage() internal pure returns (Storage storage $) {
|
|
16
26
|
bytes32 loc = EVENT_COUNTER_STORAGE_LOCATION;
|
|
17
27
|
assembly {
|
|
@@ -21,23 +31,44 @@ contract EventCounterStorage {
|
|
|
21
31
|
|
|
22
32
|
}
|
|
23
33
|
|
|
34
|
+
/// @title EventCounter
|
|
35
|
+
/// @notice Manages unique event identifiers for encrypted operation handle generation
|
|
36
|
+
/// @dev Each encrypted operation requires a unique identifier to generate deterministic handles.
|
|
37
|
+
/// This contract provides two modes:
|
|
38
|
+
/// 1. Sequential mode: getNewEventId() increments counter for each operation
|
|
39
|
+
/// 2. Digest mode: setDigest() sets counter to hash of serialized operations (for batching)
|
|
40
|
+
///
|
|
41
|
+
/// The event ID is incorporated into handle generation to ensure uniqueness even when
|
|
42
|
+
/// the same operation is performed multiple times in the same transaction.
|
|
24
43
|
contract EventCounter is IEventCounter, EventCounterStorage {
|
|
25
44
|
|
|
45
|
+
/// @notice Generates and returns a new unique event ID
|
|
46
|
+
/// @dev Post-increments the counter, so the returned value is the ID before incrementing.
|
|
47
|
+
/// This ensures each call returns a unique ID within the contract's lifetime.
|
|
48
|
+
/// @return newEventId The event ID to use for this operation
|
|
26
49
|
function getNewEventId() internal returns (uint256 newEventId) {
|
|
27
50
|
newEventId = getEventCounterStorage().eventCounter++;
|
|
28
51
|
}
|
|
29
52
|
|
|
53
|
+
/// @notice Sets the event counter to a digest value for batch operation tracking
|
|
54
|
+
/// @dev Used when processing batched operations where a serialization hash
|
|
55
|
+
/// provides better uniqueness than sequential IDs
|
|
56
|
+
/// @param serialization The serialized batch data to hash
|
|
30
57
|
function setDigest(bytes memory serialization) internal {
|
|
31
58
|
getEventCounterStorage().eventCounter = uint256(keccak256(serialization));
|
|
32
59
|
}
|
|
33
60
|
|
|
34
|
-
|
|
61
|
+
/// @notice Returns the next event ID that will be assigned
|
|
62
|
+
/// @dev View function that does not modify state. Useful for predicting handles
|
|
63
|
+
/// or verifying the current state of the counter.
|
|
64
|
+
/// @return The next event ID value
|
|
35
65
|
function getNextEventId() public view returns (uint256) {
|
|
36
66
|
return getEventCounterStorage().eventCounter;
|
|
37
67
|
}
|
|
38
68
|
|
|
39
|
-
|
|
40
|
-
|
|
69
|
+
/// @notice Returns the current value of the event counter
|
|
70
|
+
/// @dev Deprecated: Use getNextEventId() instead. Kept for backwards compatibility.
|
|
71
|
+
/// @return The current event counter value
|
|
41
72
|
function getEventCounter() public view returns (uint256) {
|
|
42
73
|
return getNextEventId();
|
|
43
74
|
}
|
|
@@ -5,22 +5,38 @@ import {ETypes, EOps, EVM_HOST_CHAIN_PREFIX, HANDLE_INDEX} from "../../Types.sol
|
|
|
5
5
|
import {HandleMetadata} from "./HandleMetadata.sol";
|
|
6
6
|
import {IHandleGeneration} from "./interfaces/IHandleGeneration.sol";
|
|
7
7
|
|
|
8
|
+
/// @title HandleGeneration
|
|
9
|
+
/// @notice Generates deterministic handles for encrypted values.
|
|
10
|
+
/// @dev Handles are unique identifiers for encrypted ciphertexts. They are computed deterministically
|
|
11
|
+
/// from the operation type and inputs, ensuring the same encrypted operation always produces the same
|
|
12
|
+
/// handle. This enables consistent state across chains and allows the covalidator to map handles to
|
|
13
|
+
/// their corresponding ciphertexts. Handles embed type and version metadata in their lower bytes.
|
|
8
14
|
contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
9
15
|
|
|
16
|
+
/// @notice Generates a handle for a trivially encrypted value.
|
|
17
|
+
/// @dev Trivial encryption creates a handle from a known plaintext. The handle is deterministic
|
|
18
|
+
/// based on the plaintext value, allowing the same plaintext to always produce the same handle.
|
|
19
|
+
/// @param plaintextBytes The plaintext value as bytes32.
|
|
20
|
+
/// @param handleType The type of encrypted value (euint256, ebool, etc.).
|
|
21
|
+
/// @return generatedHandle The deterministic handle for this trivial encryption.
|
|
10
22
|
function getTrivialEncryptHandle(bytes32 plaintextBytes, ETypes handleType)
|
|
11
23
|
public
|
|
12
24
|
pure
|
|
13
25
|
returns (bytes32 generatedHandle)
|
|
14
26
|
{
|
|
15
|
-
generatedHandle = keccak256(
|
|
16
|
-
abi.encodePacked(
|
|
17
|
-
EOps.TrivialEncrypt, // !! Note[Silas]: I reordered this to be first element for greater regularity 26/08/2025 (remove this note after 1 month) !!
|
|
18
|
-
plaintextBytes
|
|
19
|
-
)
|
|
20
|
-
);
|
|
27
|
+
generatedHandle = keccak256(abi.encodePacked(EOps.TrivialEncrypt, plaintextBytes));
|
|
21
28
|
generatedHandle = embedTypeVersion(generatedHandle, handleType);
|
|
22
29
|
}
|
|
23
30
|
|
|
31
|
+
/// @notice Generates a handle for a client-encrypted input.
|
|
32
|
+
/// @dev Internal version that uses the current contract as the executor address.
|
|
33
|
+
/// The handle is computed from the ciphertext and context (chain, executor, user, contract).
|
|
34
|
+
/// @param ciphertext The encrypted input data.
|
|
35
|
+
/// @param user The user address that encrypted the value.
|
|
36
|
+
/// @param contractAddress The contract submitting the input.
|
|
37
|
+
/// @param version The version of the handle format.
|
|
38
|
+
/// @param inputType The type of encrypted value.
|
|
39
|
+
/// @return generatedHandle The deterministic handle for this input.
|
|
24
40
|
function getInputHandle(
|
|
25
41
|
bytes memory ciphertext,
|
|
26
42
|
address user,
|
|
@@ -31,6 +47,15 @@ contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
|
31
47
|
return getInputHandle(ciphertext, address(this), user, contractAddress, version, inputType);
|
|
32
48
|
}
|
|
33
49
|
|
|
50
|
+
/// @notice Generates a handle for a client-encrypted input with explicit executor.
|
|
51
|
+
/// @dev The handle incorporates the full context (chain ID, executor, user, contract) to ensure
|
|
52
|
+
/// uniqueness across different chains and deployments. This prevents replay attacks.
|
|
53
|
+
/// @param ciphertext The encrypted input data.
|
|
54
|
+
/// @param executorAddress The executor contract address.
|
|
55
|
+
/// @param user The user address that encrypted the value.
|
|
56
|
+
/// @param contractAddress The contract submitting the input.
|
|
57
|
+
/// @param inputType The type of encrypted value.
|
|
58
|
+
/// @return generatedHandle The deterministic handle for this input.
|
|
34
59
|
function getInputHandle(
|
|
35
60
|
bytes memory ciphertext,
|
|
36
61
|
address executorAddress,
|
|
@@ -60,6 +85,13 @@ contract HandleGeneration is IHandleGeneration, HandleMetadata {
|
|
|
60
85
|
);
|
|
61
86
|
}
|
|
62
87
|
|
|
88
|
+
/// @notice Generates a handle for the result of an encrypted operation.
|
|
89
|
+
/// @dev The handle is deterministic based on the operation type and input handles.
|
|
90
|
+
/// This ensures that the same operation on the same inputs always produces the same result handle.
|
|
91
|
+
/// @param op The operation type (eAdd, eSub, etc.).
|
|
92
|
+
/// @param returnType The type of the result value.
|
|
93
|
+
/// @param packedInputs The packed input handles.
|
|
94
|
+
/// @return generatedHandle The deterministic handle for this operation result.
|
|
63
95
|
function getOpResultHandle(EOps op, ETypes returnType, bytes memory packedInputs)
|
|
64
96
|
public
|
|
65
97
|
pure
|
|
@@ -3,8 +3,24 @@ pragma solidity ^0.8;
|
|
|
3
3
|
|
|
4
4
|
import {HANDLE_VERSION, HANDLE_INDEX, ETypes} from "../../Types.sol";
|
|
5
5
|
|
|
6
|
+
/// @title HandleMetadata
|
|
7
|
+
/// @notice Utilities for embedding and extracting metadata from encrypted value handles
|
|
8
|
+
/// @dev Handle structure (32 bytes / 256 bits):
|
|
9
|
+
/// - Bytes 0-28: Handle-specific data (hash, counters, etc.)
|
|
10
|
+
/// - Byte 29: Handle index (distinguishes input vs operation handles)
|
|
11
|
+
/// - Byte 30: Encrypted type (ETypes enum value)
|
|
12
|
+
/// - Byte 31: Handle version
|
|
6
13
|
contract HandleMetadata {
|
|
7
14
|
|
|
15
|
+
/// @notice Embeds the handle index, encrypted type, and protocol version into a prehandle
|
|
16
|
+
/// @dev Used for input handles where the index distinguishes the source.
|
|
17
|
+
/// Clears bytes 29-31 of the prehandle, then sets:
|
|
18
|
+
/// - Byte 29: HANDLE_INDEX constant
|
|
19
|
+
/// - Byte 30: inputType enum value
|
|
20
|
+
/// - Byte 31: HANDLE_VERSION constant
|
|
21
|
+
/// @param prehandle The 32-byte hash before metadata embedding
|
|
22
|
+
/// @param inputType The encrypted type to embed (ebool, euint8, etc.)
|
|
23
|
+
/// @return result The complete handle with embedded metadata
|
|
8
24
|
function embedIndexTypeVersion(bytes32 prehandle, ETypes inputType) internal pure returns (bytes32 result) {
|
|
9
25
|
// Create a mask to clear the last three bytes
|
|
10
26
|
bytes32 mask = bytes32(uint256(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF));
|
|
@@ -15,12 +31,24 @@ contract HandleMetadata {
|
|
|
15
31
|
result = embedTypeVersion(result, inputType);
|
|
16
32
|
}
|
|
17
33
|
|
|
34
|
+
/// @notice Embeds the encrypted type and protocol version into a prehandle
|
|
35
|
+
/// @dev Used for operation result handles and trivial encryptions.
|
|
36
|
+
/// Clears bytes 30-31 of the prehandle, then sets:
|
|
37
|
+
/// - Byte 30: handleType enum value
|
|
38
|
+
/// - Byte 31: HANDLE_VERSION constant
|
|
39
|
+
/// @param prehandle The 32-byte hash before metadata embedding
|
|
40
|
+
/// @param handleType The encrypted type to embed (ebool, euint8, etc.)
|
|
41
|
+
/// @return result The handle with type and version embedded
|
|
18
42
|
function embedTypeVersion(bytes32 prehandle, ETypes handleType) internal pure returns (bytes32 result) {
|
|
19
43
|
result = prehandle & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000;
|
|
20
44
|
result = bytes32(uint256(result) | (uint256(handleType) << 8)); // append type
|
|
21
45
|
result = bytes32(uint256(result) | HANDLE_VERSION);
|
|
22
46
|
}
|
|
23
47
|
|
|
48
|
+
/// @notice Extracts the encrypted type from a handle
|
|
49
|
+
/// @dev Reads byte 30 of the handle and casts to ETypes enum
|
|
50
|
+
/// @param handle The encrypted value handle to inspect
|
|
51
|
+
/// @return The encrypted type (ebool, euint8, euint16, etc.)
|
|
24
52
|
function typeOf(bytes32 handle) internal pure returns (ETypes) {
|
|
25
53
|
return ETypes(uint8(uint256(handle) >> 8));
|
|
26
54
|
}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
|
+
/// @title LightningAddressGetter
|
|
5
|
+
/// @notice Provides immutable access to the IncoLightning contract address
|
|
6
|
+
/// @dev Abstract contract that stores the main IncoLightning address at deployment time.
|
|
7
|
+
/// Used by peripheral contracts (like AdvancedAccessControl, SessionVerifier) that need
|
|
8
|
+
/// to call back to the main IncoLightning contract for ACL lookups or other operations.
|
|
9
|
+
/// The address is immutable to prevent redirection attacks.
|
|
4
10
|
abstract contract LightningAddressGetter {
|
|
5
11
|
|
|
12
|
+
/// @notice The main IncoLightning contract address
|
|
13
|
+
/// @dev Set immutably at deployment. Used for delegating calls and ACL lookups.
|
|
6
14
|
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
7
15
|
address internal immutable incoLightningAddress;
|
|
8
16
|
|
|
17
|
+
/// @notice Initializes the contract with the IncoLightning address
|
|
18
|
+
/// @param _incoLightningAddress The address of the deployed IncoLightning contract
|
|
9
19
|
constructor(address _incoLightningAddress) {
|
|
10
20
|
incoLightningAddress = _incoLightningAddress;
|
|
11
21
|
}
|
|
@@ -4,11 +4,21 @@ pragma solidity ^0.8;
|
|
|
4
4
|
import {IIncoVerifier} from "../../interfaces/IIncoVerifier.sol";
|
|
5
5
|
import {IVerifierAddressGetter} from "./interfaces/IVerifierAddressGetter.sol";
|
|
6
6
|
|
|
7
|
+
/// @title VerifierAddressGetter
|
|
8
|
+
/// @notice Provides immutable access to the IncoVerifier contract address
|
|
9
|
+
/// @dev Abstract contract that stores the IncoVerifier address at deployment time.
|
|
10
|
+
/// The IncoVerifier is responsible for validating decryption attestations from covalidators.
|
|
11
|
+
/// This pattern ensures the verifier address is set once and cannot be changed,
|
|
12
|
+
/// which is critical for security as the verifier is trusted for attestation validation.
|
|
7
13
|
abstract contract VerifierAddressGetter is IVerifierAddressGetter {
|
|
8
14
|
|
|
15
|
+
/// @notice The IncoVerifier contract used for attestation validation
|
|
16
|
+
/// @dev Set immutably at deployment. Used to verify decryption proofs from covalidators.
|
|
9
17
|
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
10
18
|
IIncoVerifier public immutable incoVerifier;
|
|
11
19
|
|
|
20
|
+
/// @notice Initializes the contract with the IncoVerifier address
|
|
21
|
+
/// @param _incoVerifier The address of the deployed IncoVerifier contract
|
|
12
22
|
constructor(address _incoVerifier) {
|
|
13
23
|
incoVerifier = IIncoVerifier(_incoVerifier);
|
|
14
24
|
}
|