@inco/lightning 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/manifest.yaml +23 -9
  2. package/package.json +1 -2
  3. package/src/DeployUtils.sol +10 -19
  4. package/src/Lib.alphanet.sol +12 -6
  5. package/src/Lib.demonet.sol +12 -6
  6. package/src/Lib.devnet.sol +13 -7
  7. package/src/Lib.sol +13 -7
  8. package/src/Lib.template.sol +12 -6
  9. package/src/Lib.testnet.sol +12 -6
  10. package/src/Types.sol +4 -1
  11. package/src/libs/incoLightning_alphanet_v0_297966649.sol +12 -6
  12. package/src/libs/incoLightning_demonet_v0_863421733.sol +12 -6
  13. package/src/libs/incoLightning_devnet_v0_340846814.sol +12 -6
  14. package/src/libs/incoLightning_devnet_v1_904635675.sol +457 -0
  15. package/src/libs/incoLightning_testnet_v0_183408998.sol +12 -6
  16. package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +21 -5
  17. package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +1 -0
  18. package/src/lightning-parts/EncryptedInput.sol +22 -6
  19. package/src/lightning-parts/EncryptedOperations.sol +6 -6
  20. package/src/lightning-parts/Fee.sol +41 -0
  21. package/src/lightning-parts/TEELifecycle.sol +170 -67
  22. package/src/lightning-parts/TEELifecycle.types.sol +9 -12
  23. package/src/lightning-parts/TrivialEncryption.sol +1 -1
  24. package/src/lightning-parts/interfaces/IEncryptedInput.sol +3 -3
  25. package/src/lightning-parts/interfaces/IEncryptedOperations.sol +48 -1
  26. package/src/lightning-parts/interfaces/ITEELifecycle.sol +2 -2
  27. package/src/lightning-parts/test/Fee.t.sol +101 -0
  28. package/src/lightning-parts/test/HandleMetadata.t.sol +4 -3
  29. package/src/lightning-parts/test/InputsFee.t.sol +65 -0
  30. package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +1 -0
  31. package/src/test/AddTwo.sol +18 -6
  32. package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +12 -0
  33. package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +6 -0
  34. package/src/test/FakeIncoInfra/getOpForSelector.sol +5 -0
  35. package/src/test/IncoTest.sol +1 -0
  36. package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +21 -26
  37. package/src/test/TestAddTwo.t.sol +9 -1
  38. package/src/test/TestFakeInfra.t.sol +12 -3
  39. package/src/version/IncoLightningConfig.sol +3 -1
  40. package/src/test/TEELifecycle/README.md +0 -53
@@ -0,0 +1,41 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ // the fee should be modified through upgrades to limit gas cost
5
+ uint256 constant FEE = 0.0001 ether;
6
+
7
+ /// @notice Fee utils for lightning functions that require a fee
8
+ /// @dev the fee may be changed through upgrades, develop your apps accordingly!
9
+ abstract contract Fee {
10
+ error FeeNotPaid();
11
+
12
+ /// @notice the fee to pay through msg.value for inputs and randomness IT MAY CHANGE
13
+ function getFee() public pure returns (uint256) {
14
+ return FEE;
15
+ }
16
+
17
+ modifier paying() {
18
+ require(msg.value == FEE, FeeNotPaid());
19
+ _;
20
+ }
21
+
22
+ modifier payingMultiple(uint256 nbOfFees) {
23
+ require(msg.value == FEE * nbOfFees, FeeNotPaid());
24
+ _;
25
+ }
26
+
27
+ // Refund the difference between msg.value and what was actually spent
28
+ // assumes that all outflows and inflows to the contract are due to the user
29
+ // though the refund is capped at msg.value
30
+ modifier refundUnspent() {
31
+ uint256 balanceBefore = address(this).balance;
32
+ _;
33
+ uint256 balanceAfter = address(this).balance;
34
+ uint256 spent = balanceBefore > balanceAfter ? balanceBefore - balanceAfter : 0;
35
+ uint256 refund = msg.value > spent ? msg.value - spent : 0;
36
+ if (refund > 0) {
37
+ (bool success, ) = msg.sender.call{value: refund}("");
38
+ require(success, "Refund failed");
39
+ }
40
+ }
41
+ }
@@ -2,8 +2,7 @@ pragma solidity ^0.8.19;
2
2
 
3
3
  import {
4
4
  BootstrapResult,
5
- TEEVersion,
6
- TEEVersionStatus
5
+ UpgradeResult
7
6
  } from "./TEELifecycle.types.sol";
8
7
  import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
9
8
  import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
@@ -28,40 +27,53 @@ abstract contract TEELifecycle is
28
27
  OwnableUpgradeable,
29
28
  EIP712Upgradeable
30
29
  {
30
+ // Errors
31
31
  error InvalidQuoteVerifierVersion(uint16 actual, uint16 expected);
32
32
  error EmptyTcbInfo();
33
33
  error EmptyIdentity();
34
34
  error BootstrapNotComplete();
35
35
  error BootstrapAlreadyCompleted();
36
- /// @notice TEEVersionHistory must have exactly one version, please call approveNewTEEVersion first
37
- error TEEVersionHistoryInconsistent();
38
- error TEEVersionHistoryStatusIsNotPending();
39
- error InvalidReportMRTD();
40
- error InvalidBootstrapDataSignature();
41
- /// @notice MRTD must be exactly 48 bytes
42
- error MrtdInvalidLength();
43
- error EOASignerAlreadyInitialized();
44
- error InvalidMrtdReport();
36
+ /// @notice The TEE version was not found in the TEEVersionHistory
37
+ error TEEVersionNotFound();
38
+ error InvalidReportMrAggregated();
45
39
  error InvalidReportDataSigner();
40
+ /// @notice The EIP712 signature recovered an incorrect address
41
+ error InvalidEIP712Signature();
42
+ error EOASignerAlreadyInitialized();
43
+ // @notice The EOA signer in the quote is not an existing EOA signer
44
+ error EOASignerNotFound();
45
+ // @notice The network pubkey signed by the TDX EOA is not the same as the one in the bootstrap result
46
+ error InvalidNetworkPubkey();
46
47
 
47
- event QuoteVerifierUpdated(uint16 indexed version);
48
- event TEEVersionUpdated(TEEVersion teeVersion);
48
+ // Events
49
+ // @notice A new MR_AGGREGATED has been approved
50
+ event NewTEEVersionApproved(uint256 indexed version, bytes32 indexed mrAggregated);
49
51
  event NewCovalidatorAdded(address covalidatorAddress, bytes quote);
50
52
  event BootstrapStageComplete(
51
53
  address indexed newEOASigner,
52
54
  BootstrapResult bootstrapResult
53
55
  );
56
+ // @notice Emitted to prove that an EOA has upgraded their TDX to a new
57
+ // MR_AGGREGATED. This is done by checking remote attestation of the quote
58
+ // and verifying the EIP712 signature of the bootstrap/upgrade result by
59
+ // the TDX EOA.
60
+ event EOAHasUpdatedTDX(address indexed eoaSigner, bytes32 indexed mrAggregated);
54
61
 
62
+ // Constants
55
63
  bytes32 public constant BootstrapResultStructHash =
56
64
  keccak256(bytes("BootstrapResult(bytes ecies_pubkey)"));
65
+ bytes32 public constant UpgradeResultStructHash =
66
+ keccak256(bytes("UpgradeResult(bytes network_pubkey)"));
57
67
 
58
68
  uint16 public constant QUOTE_VERIFIER_VERSION = 4;
59
69
 
60
70
  IQuoteVerifier public quoteVerifier;
61
- BootstrapResult public VerifiedBootstrapResult;
62
- bool public BootstrapComplete;
63
71
 
64
- TEEVersion[] public TEEVersionHistory;
72
+ // @notice The list of approved TEE versions, each item is the MR_AGGREGATED 32 bytes
73
+ // @dev The index of the TEE version is the version number
74
+ bytes32[] public ApprovedTEEVersions;
75
+ // @notice The Network key
76
+ // @todo rename to NetworkPubkey https://github.com/Inco-fhevm/inco-monorepo/issues/983
65
77
  bytes public ECIESPubkey;
66
78
  mapping(address => bool) public EOASigners;
67
79
 
@@ -109,10 +121,10 @@ abstract contract TEELifecycle is
109
121
  }
110
122
 
111
123
  /**
112
- * @notice Verifies the bootstrap data against the provided quote and signature
124
+ * @notice Wrapper around activateNewTEEVersion which verifies the bootstrap result and marks the new TEE version as active
113
125
  * @param bootstrapResult - The bootstrap data to verify
114
126
  * @param quote - The quote to verify against
115
- * @param signature - The signature to verify against
127
+ * @param signature - The EIP712 signature of the bootstrap result by the TDX EOA
116
128
  */
117
129
  function verifyBootstrapResult(
118
130
  BootstrapResult calldata bootstrapResult,
@@ -120,63 +132,121 @@ abstract contract TEELifecycle is
120
132
  bytes calldata signature
121
133
  ) public onlyOwner {
122
134
  // Make sure the bootstrap is not already complete, and that the contract owner
123
- // has already submitted the pending TEE MRTD.
135
+ // has already submitted the pending TEE MR_AGGREGATED.
124
136
  require(!isBootstrapComplete(), BootstrapAlreadyCompleted());
125
- require(TEEVersionHistory.length == 1, TEEVersionHistoryInconsistent());
126
- require(
127
- TEEVersionHistory[0].status == TEEVersionStatus.PENDING,
128
- TEEVersionHistoryStatusIsNotPending()
137
+ require(ApprovedTEEVersions.length == 1, TEEVersionNotFound());
138
+
139
+ bytes32 digest = bootstrapResultDigest(bootstrapResult);
140
+ address reportDataSigner = _verifyResultForEOA(
141
+ ApprovedTEEVersions[0],
142
+ digest,
143
+ quote,
144
+ signature
145
+ );
146
+
147
+ // For bootstrap phase, we only have one EOA signer
148
+ // So if we arrive here in code, it means that the EOA has signed the bootstrap result
149
+
150
+ // Update contract publicly viewable state
151
+ ECIESPubkey = bootstrapResult.ecies_pubkey;
152
+ EOASigners[reportDataSigner] = true;
153
+
154
+ emit BootstrapStageComplete(reportDataSigner, bootstrapResult);
155
+ }
156
+
157
+ /**
158
+ * @notice Verifies the upgrade result for a single EOA. This function does not modify any contract state.
159
+ * It simply serves as an on-chain proof that each TDX has been updated to the newest MR_AGGREGATED.
160
+ * @param upgradeResult - The upgrade data to verify
161
+ * @param quote - The quote to verify against (contains the TDX EOA)
162
+ * @param signature - The EIP712 signature of the upgrade result by the TDX EOA
163
+ */
164
+ function verifyUpgradeResult(
165
+ bytes32 newMrAggregated,
166
+ UpgradeResult calldata upgradeResult,
167
+ bytes calldata quote,
168
+ bytes calldata signature
169
+ ) public {
170
+ require(isBootstrapComplete(), BootstrapNotComplete());
171
+ // Make sure the quote's network pubkey is the same as the one in the bootstrap result
172
+ require(keccak256(ECIESPubkey) == keccak256(upgradeResult.network_pubkey), InvalidNetworkPubkey());
173
+ // Make sure the new MR_AGGREGATED has been pre-approved.
174
+ bool isApproved = _isApprovedTEEVersion(newMrAggregated);
175
+ require(isApproved, TEEVersionNotFound());
176
+
177
+ bytes32 digest = upgradeResultDigest(upgradeResult);
178
+ address reportDataSigner = _verifyResultForEOA(
179
+ newMrAggregated,
180
+ digest,
181
+ quote,
182
+ signature
129
183
  );
184
+ // Make sure the new EOA signer is an existing EOA signer
185
+ require(EOASigners[reportDataSigner], EOASignerNotFound());
186
+ }
187
+
188
+ /**
189
+ * @notice Approves a new TEE version as PENDING and updates the TEEVersionHistory.
190
+ * The new TEE version can be activated by calling verifyBootstrapResult or activateNewTEEVersion.
191
+ * @param newMrAggregated - The MR_AGGREGATED bytes of the new TEE version
192
+ * @dev This function increments the version number automatically based on the current history
193
+ */
194
+ function approveNewTEEVersion(bytes32 newMrAggregated) public onlyOwner {
195
+ ApprovedTEEVersions.push(newMrAggregated);
196
+ emit NewTEEVersionApproved(ApprovedTEEVersions.length - 1, newMrAggregated);
197
+ }
198
+
199
+ function _isApprovedTEEVersion(bytes32 newMrAggregated) internal view returns (bool) {
200
+ for (uint256 i = 0; i < ApprovedTEEVersions.length; i++) {
201
+ if (ApprovedTEEVersions[i] == newMrAggregated) {
202
+ return true;
203
+ }
204
+ }
205
+ return false;
206
+ }
130
207
 
131
- bytes32 _bootstrapResultDigest = bootstrapResultDigest(bootstrapResult);
208
+ /**
209
+ * @notice Verifies quote and signature from TDX for a single EOA. This is a shared function for bootstrap and upgrade.
210
+ * @param newMrAggregated - The MR_AGGREGATED bytes of the new TEE version
211
+ * @param resultEip712Digest - The EIP712 digest of the result to verify
212
+ * @param quote - The quote to verify against (contains the TDX EOA)
213
+ * @param signature - The EIP712 signature of the digest by the TDX EOA
214
+ * @return reportDataSigner - The address of the report data signer (i.e. the TDX EOA)
215
+ */
216
+ function _verifyResultForEOA(
217
+ bytes32 newMrAggregated,
218
+ bytes32 resultEip712Digest,
219
+ bytes calldata quote,
220
+ bytes calldata signature
221
+ ) internal onlyOwner returns (address) {
132
222
  (bool success, bytes memory output) = _verifyAndAttestOnChain(quote);
133
223
  require(success, string(output));
134
224
 
135
- bytes memory v0MRTD = TEEVersionHistory[0].mrtd;
136
-
137
225
  TD10ReportBody memory tdReport = parseTD10ReportBody(quote);
138
- (address reportDataSigner, bytes memory reportMRTD) = parseReport(
226
+ (address reportDataSigner, bytes32 reportMrAggregated) = parseReport(
139
227
  tdReport
140
228
  );
141
229
  require(
142
- keccak256(reportMRTD) == keccak256(v0MRTD),
143
- InvalidReportMRTD()
230
+ reportMrAggregated == newMrAggregated,
231
+ InvalidReportMrAggregated()
144
232
  );
145
233
  address recoveredAddress = ECDSA.recover(
146
- _bootstrapResultDigest,
234
+ resultEip712Digest,
147
235
  signature
148
236
  );
149
237
  require(
150
238
  recoveredAddress == reportDataSigner,
151
- InvalidBootstrapDataSignature()
239
+ InvalidEIP712Signature()
152
240
  );
153
241
 
154
- VerifiedBootstrapResult = bootstrapResult;
155
- TEEVersionHistory[0].status = TEEVersionStatus.ACTIVE;
156
- emit BootstrapStageComplete(reportDataSigner, bootstrapResult);
157
- ECIESPubkey = bootstrapResult.ecies_pubkey;
158
- EOASigners[reportDataSigner] = true;
159
- //TODO: update ECIES public key to ?? contract state and EOA addresses signers to the Signers contract state
160
- }
161
-
162
- /**
163
- * @notice Approves a new TEE version and updates the TEEVersionHistory
164
- * @param newMRTD - The MRTD bytes of the new TEE version
165
- * @dev This function increments the version number automatically based on the current history
166
- */
167
- function approveNewTEEVersion(bytes calldata newMRTD) public onlyOwner {
168
- require(newMRTD.length == 48, MrtdInvalidLength());
169
-
170
- TEEVersionHistory.push(
171
- TEEVersion({mrtd: newMRTD, status: TEEVersionStatus.PENDING})
172
- );
242
+ emit EOAHasUpdatedTDX(reportDataSigner, newMrAggregated);
173
243
 
174
- emit TEEVersionUpdated(TEEVersionHistory[TEEVersionHistory.length - 1]);
244
+ return reportDataSigner;
175
245
  }
176
246
 
177
247
  /**
178
248
  * @notice Adds a new covalidator to the contract state
179
- * @param quote - The quote from the new covalidator that contains the current MRTD and the eoa address of the new party in the report data
249
+ * @param quote - The quote from the new covalidator that contains the current MR_AGGREGATED and the eoa address of the new party in the report data
180
250
  */
181
251
  function addNewCovalidator(bytes calldata quote) public onlyOwner {
182
252
  require(isBootstrapComplete(), BootstrapNotComplete());
@@ -184,30 +254,27 @@ abstract contract TEELifecycle is
184
254
  (bool success, bytes memory output) = _verifyAndAttestOnChain(quote);
185
255
  require(success, string(output));
186
256
  TD10ReportBody memory tdReport = parseTD10ReportBody(quote);
187
- (address reportDataSigner, bytes memory reportMRTD) = parseReport(
257
+ (address reportDataSigner, bytes32 reportMrAggregated) = parseReport(
188
258
  tdReport
189
259
  );
190
260
  require(!EOASigners[reportDataSigner], EOASignerAlreadyInitialized());
191
261
 
192
- require(
193
- keccak256(reportMRTD) ==
194
- keccak256(TEEVersionHistory[TEEVersionHistory.length - 1].mrtd),
195
- InvalidMrtdReport()
196
- );
262
+ bool isApproved = _isApprovedTEEVersion(reportMrAggregated);
263
+ require(isApproved, TEEVersionNotFound());
264
+
197
265
  require(reportDataSigner != address(0), InvalidReportDataSigner());
198
266
  emit NewCovalidatorAdded(reportDataSigner, quote);
199
267
  EOASigners[reportDataSigner] = true;
200
- //TODO: Add the new covalidator signers to the Signers contract state
201
268
  }
202
269
 
203
270
  /**
204
- * @notice Checks if the bootstrap is complete, meaning that there is an active TEE version.
271
+ * @notice Checks if the bootstrap is complete.
205
272
  * @return true if the bootstrap is complete, false otherwise
206
273
  */
207
274
  function isBootstrapComplete() public view returns (bool) {
208
- return
209
- TEEVersionHistory.length >= 1 &&
210
- TEEVersionHistory[0].status == TEEVersionStatus.ACTIVE;
275
+ // The network pubkey is set once and once only, during the bootstrap process
276
+ // So we can use the length of the network pubkey to check if the bootstrap is complete
277
+ return ECIESPubkey.length > 0;
211
278
  }
212
279
 
213
280
  /**
@@ -320,15 +387,37 @@ abstract contract TEELifecycle is
320
387
  }
321
388
 
322
389
  /**
323
- * @notice Parses the TD10 report to extract the report data and MRTD
390
+ * @notice Parses the TD10 report to extract the report data and MR_AGGREGATED
324
391
  * @param tdReport - The TD10 report body
325
392
  * @return reportDataSigner - The signing address of the report data signer
326
- * @return reportMRTD - The MRTD bytes from the report
393
+ * @return reportMrAggregated - The MR_AGGREGATED bytes from the report
327
394
  */
328
395
  function parseReport(
329
396
  TD10ReportBody memory tdReport
330
- ) public pure returns (address, bytes memory) {
331
- return (address(bytes20(tdReport.reportData)), tdReport.mrTd);
397
+ ) public pure returns (address, bytes32) {
398
+ return (
399
+ address(bytes20(tdReport.reportData)),
400
+ computeMrAggregated(tdReport.mrTd, tdReport.rtMr0, tdReport.rtMr1, tdReport.rtMr2)
401
+ );
402
+ }
403
+
404
+ /**
405
+ * @notice Computes the MR_AGGREGATED from the TD10 report body. It is defined as:
406
+ * KECCAK256(mrTd ++ rtMr0 ++ rtMr1 ++ rtMr2 ++ rtMr3)
407
+ * @param mrTd - The MR_TD bytes
408
+ * @param rtMr0 - The RTMR0 bytes
409
+ * @param rtMr1 - The RTMR1 bytes
410
+ * @param rtMr2 - The RTMR2 bytes
411
+ * @return mrAggregated - The MR_AGGREGATED bytes32
412
+ */
413
+ function computeMrAggregated(
414
+ bytes memory mrTd,
415
+ bytes memory rtMr0,
416
+ bytes memory rtMr1,
417
+ bytes memory rtMr2
418
+ ) public pure returns (bytes32) {
419
+ bytes memory message = abi.encodePacked(mrTd, rtMr0, rtMr1, rtMr2);
420
+ return keccak256(message);
332
421
  }
333
422
 
334
423
  function bootstrapResultDigest(
@@ -344,4 +433,18 @@ abstract contract TEELifecycle is
344
433
  )
345
434
  );
346
435
  }
436
+
437
+ function upgradeResultDigest(
438
+ UpgradeResult memory upgradeResult
439
+ ) public view returns (bytes32) {
440
+ return
441
+ _hashTypedDataV4(
442
+ keccak256(
443
+ abi.encode(
444
+ UpgradeResultStructHash,
445
+ keccak256(upgradeResult.network_pubkey)
446
+ )
447
+ )
448
+ );
449
+ }
347
450
  }
@@ -1,21 +1,18 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8.19;
3
3
 
4
+ /**
5
+ * @notice A struct representing what the TDX EOA signs during the bootstrap process.
6
+ */
4
7
  struct BootstrapResult {
8
+ // TODO: rename to network_pubkey
9
+ // https://github.com/Inco-fhevm/inco-monorepo/issues/983
5
10
  bytes ecies_pubkey;
6
11
  }
7
12
 
8
- enum TEEVersionStatus {
9
- PENDING,
10
- ACTIVE
11
- }
12
-
13
13
  /**
14
- * @notice A struct representing a TEE version. The actual version number is the index in the TEEVersionHistory array.
15
- * @param mrtd - The MRTD of the TEE version
16
- * @param status - The status of the TEE version
14
+ * @notice A struct representing what the TDX EOA signs during the upgrade process.
17
15
  */
18
- struct TEEVersion {
19
- bytes mrtd;
20
- TEEVersionStatus status;
21
- }
16
+ struct UpgradeResult {
17
+ bytes network_pubkey;
18
+ }
@@ -9,8 +9,8 @@ import {ITrivialEncryption} from "./interfaces/ITrivialEncryption.sol";
9
9
 
10
10
  abstract contract TrivialEncryption is
11
11
  ITrivialEncryption,
12
- BaseAccessControlList,
13
12
  EventCounter,
13
+ BaseAccessControlList,
14
14
  HandleGeneration
15
15
  {
16
16
  event TrivialEncrypt(
@@ -7,13 +7,13 @@ interface IEncryptedInput {
7
7
  function newEuint256(
8
8
  bytes memory ciphertext,
9
9
  address user
10
- ) external returns (euint256 newValue);
10
+ ) external payable returns (euint256 newValue);
11
11
  function newEbool(
12
12
  bytes memory ciphertext,
13
13
  address user
14
- ) external returns (ebool newValue);
14
+ ) external payable returns (ebool newValue);
15
15
  function newEaddress(
16
16
  bytes memory ciphertext,
17
17
  address user
18
- ) external returns (eaddress newValue);
18
+ ) external payable returns (eaddress newValue);
19
19
  }
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: No License
2
2
  pragma solidity ^0.8;
3
3
 
4
- import {euint256} from "../../Types.sol";
4
+ import {euint256, ebool, ETypes} from "../../Types.sol";
5
5
 
6
6
  interface IEncryptedOperations {
7
7
  function eAdd(
@@ -28,4 +28,51 @@ interface IEncryptedOperations {
28
28
  bytes32 lhs,
29
29
  bytes32 rhs
30
30
  ) external returns (bytes32 result);
31
+ function eBitOr(bytes32 lhs, bytes32 rhs) external returns (bytes32 result);
32
+ function eBitXor(
33
+ bytes32 lhs,
34
+ bytes32 rhs
35
+ ) external returns (bytes32 result);
36
+ function eShl(
37
+ euint256 lhs,
38
+ euint256 rhs
39
+ ) external returns (euint256 result);
40
+ function eShr(
41
+ euint256 lhs,
42
+ euint256 rhs
43
+ ) external returns (euint256 result);
44
+ function eRotl(
45
+ euint256 lhs,
46
+ euint256 rhs
47
+ ) external returns (euint256 result);
48
+ function eRotr(
49
+ euint256 lhs,
50
+ euint256 rhs
51
+ ) external returns (euint256 result);
52
+ function eEq(bytes32 lhs, bytes32 rhs) external returns (ebool result);
53
+ function eNe(bytes32 lhs, bytes32 rhs) external returns (ebool result);
54
+ function eGe(euint256 lhs, euint256 rhs) external returns (ebool result);
55
+ function eGt(euint256 lhs, euint256 rhs) external returns (ebool result);
56
+ function eLe(euint256 lhs, euint256 rhs) external returns (ebool result);
57
+ function eLt(euint256 lhs, euint256 rhs) external returns (ebool result);
58
+ function eMin(
59
+ euint256 lhs,
60
+ euint256 rhs
61
+ ) external returns (euint256 result);
62
+ function eMax(
63
+ euint256 lhs,
64
+ euint256 rhs
65
+ ) external returns (euint256 result);
66
+ function eNot(ebool operand) external returns (ebool result);
67
+ function eCast(bytes32 ct, ETypes toType) external returns (bytes32 result);
68
+ function eRand(ETypes randType) external payable returns (bytes32 result);
69
+ function eRandBounded(
70
+ bytes32 upperBound,
71
+ ETypes randType
72
+ ) external payable returns (bytes32 result);
73
+ function eIfThenElse(
74
+ ebool condition,
75
+ bytes32 ifTrue,
76
+ bytes32 ifFalse
77
+ ) external returns (bytes32 result);
31
78
  }
@@ -11,14 +11,14 @@ interface ITEELifecycle {
11
11
  bytes calldata quote,
12
12
  bytes calldata signature
13
13
  ) external;
14
- function approveNewTEEVersion(bytes calldata newMRTD) external;
14
+ function approveNewTEEVersion(bytes32 newMrAggregated) external;
15
15
  function addNewCovalidator(bytes calldata quote) external;
16
16
  function parseTD10ReportBody(
17
17
  bytes calldata rawQuote
18
18
  ) external pure returns (TD10ReportBody memory report);
19
19
  function parseReport(
20
20
  TD10ReportBody memory tdReport
21
- ) external pure returns (address, bytes memory);
21
+ ) external pure returns (address, bytes32);
22
22
  function bootstrapResultDigest(
23
23
  BootstrapResult memory bootstrapResult
24
24
  ) external view returns (bytes32);
@@ -0,0 +1,101 @@
1
+ // SPDX-License-Identifier: No License
2
+ pragma solidity ^0.8;
3
+
4
+ import {Test} from "forge-std/Test.sol";
5
+ import {Fee, FEE} from "../Fee.sol";
6
+
7
+ contract FeeTester is Fee {
8
+ function costOneFee() public payable paying {
9
+ // do nothing
10
+ }
11
+
12
+ function costMultipleVariableFees(
13
+ uint256 nbOfFees
14
+ ) public payable payingMultiple(nbOfFees) {
15
+ // do nothing
16
+ }
17
+
18
+ function costMultipleFixedFees() public payable payingMultiple(3) {
19
+ // do nothing
20
+ }
21
+ }
22
+
23
+ contract TestFee is Test {
24
+ FeeTester feeTester;
25
+
26
+ function setUp() public {
27
+ feeTester = new FeeTester();
28
+ }
29
+
30
+ function testGetFee() public view {
31
+ uint256 fee = feeTester.getFee();
32
+ assertEq(fee, FEE);
33
+ }
34
+
35
+ function testPaying() public {
36
+ // should fail if no fee
37
+ vm.expectRevert(Fee.FeeNotPaid.selector);
38
+ feeTester.costOneFee{value: 0}();
39
+
40
+ // should fail if not enough fee
41
+ vm.expectRevert(Fee.FeeNotPaid.selector);
42
+ feeTester.costOneFee{value: FEE - 1}();
43
+
44
+ // should fail if too much fee
45
+ vm.expectRevert(Fee.FeeNotPaid.selector);
46
+ feeTester.costOneFee{value: FEE + 1}();
47
+
48
+ // should work with exact fee
49
+ feeTester.costOneFee{value: FEE}();
50
+ }
51
+
52
+ function testPayingMultiple() public {
53
+ // should fail if no fee
54
+ vm.expectRevert(Fee.FeeNotPaid.selector);
55
+ feeTester.costMultipleVariableFees{value: 0}(3);
56
+
57
+ // should fail if not enough fee
58
+ vm.expectRevert(Fee.FeeNotPaid.selector);
59
+ feeTester.costMultipleVariableFees{value: FEE * 3 - 1}(3);
60
+
61
+ // should fail if too much fee
62
+ vm.expectRevert(Fee.FeeNotPaid.selector);
63
+ feeTester.costMultipleVariableFees{value: FEE * 3 + 1}(3);
64
+
65
+ // should work with exact fee
66
+ feeTester.costMultipleVariableFees{value: FEE * 3}(3);
67
+
68
+ // should work with exact fee for fixed number of fees
69
+ feeTester.costMultipleFixedFees{value: FEE * 3}();
70
+ }
71
+
72
+ function testPayingMultipleZero() public {
73
+ feeTester.costMultipleVariableFees{value: 0}(0);
74
+
75
+ // should fail if too much fee
76
+ vm.expectRevert(Fee.FeeNotPaid.selector);
77
+ feeTester.costMultipleVariableFees{value: FEE + 1}(0);
78
+
79
+ // should work with exact fee
80
+ feeTester.costMultipleVariableFees{value: 0}(0);
81
+ }
82
+
83
+ function testFuzzPayingMultipleVariableFees(uint8 nbOfFees) public {
84
+ uint256 expectedValue = FEE * nbOfFees;
85
+
86
+ // should work with exact fee
87
+ feeTester.costMultipleVariableFees{value: expectedValue}(nbOfFees);
88
+
89
+ // should fail if not enough fee (unless expectedValue is 0)
90
+ if (expectedValue > 0) {
91
+ vm.expectRevert(Fee.FeeNotPaid.selector);
92
+ feeTester.costMultipleVariableFees{value: expectedValue - 1}(
93
+ nbOfFees
94
+ );
95
+ }
96
+
97
+ // should fail if too much fee
98
+ vm.expectRevert(Fee.FeeNotPaid.selector);
99
+ feeTester.costMultipleVariableFees{value: expectedValue + 1}(nbOfFees);
100
+ }
101
+ }
@@ -15,6 +15,7 @@ import {
15
15
  typeToBitMask
16
16
  } from "../../Types.sol";
17
17
  import {VerifierAddressGetter} from "../primitives/VerifierAddressGetter.sol";
18
+ import {FEE} from "../Fee.sol";
18
19
 
19
20
  contract TestHandleMetadata is
20
21
  EIP712,
@@ -107,11 +108,11 @@ contract TestHandleMetadata is
107
108
  }
108
109
 
109
110
  function testEncryptedInputHandleType() public {
110
- euint256 a = this.newEuint256("ciphertext", address(this));
111
+ euint256 a = this.newEuint256{value: FEE}("ciphertext", address(this));
111
112
  assert(typeOf(euint256.unwrap(a)) == ETypes.Uint256);
112
- ebool b = this.newEbool("ciphertext", address(this));
113
+ ebool b = this.newEbool{value: FEE}("ciphertext", address(this));
113
114
  assert(typeOf(ebool.unwrap(b)) == ETypes.Bool);
114
- eaddress c = this.newEaddress("ciphertext", address(this));
115
+ eaddress c = this.newEaddress{value: FEE}("ciphertext", address(this));
115
116
  assert(typeOf(eaddress.unwrap(c)) == ETypes.AddressOrUint160OrBytes20);
116
117
  }
117
118
  }