@inco/lightning 0.5.3 → 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.
- package/manifest.yaml +14 -0
- package/package.json +1 -1
- package/src/Lib.alphanet.sol +12 -6
- package/src/Lib.demonet.sol +12 -6
- package/src/Lib.devnet.sol +12 -6
- package/src/Lib.sol +12 -6
- package/src/Lib.template.sol +12 -6
- package/src/Lib.testnet.sol +12 -6
- package/src/Types.sol +2 -1
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +12 -6
- package/src/libs/incoLightning_demonet_v0_863421733.sol +12 -6
- package/src/libs/incoLightning_devnet_v0_340846814.sol +12 -6
- package/src/libs/incoLightning_devnet_v1_904635675.sol +12 -6
- package/src/libs/incoLightning_testnet_v0_183408998.sol +12 -6
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +11 -3
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +1 -0
- package/src/lightning-parts/EncryptedInput.sol +22 -6
- package/src/lightning-parts/EncryptedOperations.sol +6 -6
- package/src/lightning-parts/Fee.sol +41 -0
- package/src/lightning-parts/TEELifecycle.sol +138 -52
- package/src/lightning-parts/TEELifecycle.types.sol +9 -12
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +3 -3
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +48 -1
- package/src/lightning-parts/test/Fee.t.sol +101 -0
- package/src/lightning-parts/test/HandleMetadata.t.sol +4 -3
- package/src/lightning-parts/test/InputsFee.t.sol +65 -0
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +1 -0
- package/src/test/AddTwo.sol +18 -6
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +12 -0
- package/src/test/FakeIncoInfra/getOpForSelector.sol +3 -1
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +2 -2
- package/src/test/TestAddTwo.t.sol +9 -1
- package/src/test/TestFakeInfra.t.sol +13 -3
- package/src/version/IncoLightningConfig.sol +1 -1
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
|
|
5
|
-
import {EventCounter} from "./primitives/EventCounter.sol";
|
|
6
5
|
import {HandleGeneration} from "./primitives/HandleGeneration.sol";
|
|
7
6
|
import {euint256, ebool, eaddress, ETypes} from "../Types.sol";
|
|
8
7
|
import {IEncryptedInput} from "./interfaces/IEncryptedInput.sol";
|
|
9
8
|
import {HandleAlreadyExists} from "../Errors.sol";
|
|
9
|
+
import {Fee} from "./Fee.sol";
|
|
10
10
|
|
|
11
11
|
abstract contract EncryptedInput is
|
|
12
12
|
IEncryptedInput,
|
|
13
|
-
EventCounter,
|
|
14
13
|
BaseAccessControlList,
|
|
15
|
-
HandleGeneration
|
|
14
|
+
HandleGeneration,
|
|
15
|
+
Fee
|
|
16
16
|
{
|
|
17
17
|
event NewInput(
|
|
18
18
|
bytes32 indexed result,
|
|
@@ -26,21 +26,21 @@ abstract contract EncryptedInput is
|
|
|
26
26
|
function newEuint256(
|
|
27
27
|
bytes memory ciphertext,
|
|
28
28
|
address user
|
|
29
|
-
) external returns (euint256 newValue) {
|
|
29
|
+
) external payable returns (euint256 newValue) {
|
|
30
30
|
return euint256.wrap(newInput(ciphertext, user, ETypes.Uint256));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function newEbool(
|
|
34
34
|
bytes memory ciphertext,
|
|
35
35
|
address user
|
|
36
|
-
) external returns (ebool newValue) {
|
|
36
|
+
) external payable returns (ebool newValue) {
|
|
37
37
|
return ebool.wrap(newInput(ciphertext, user, ETypes.Bool));
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function newEaddress(
|
|
41
41
|
bytes memory ciphertext,
|
|
42
42
|
address user
|
|
43
|
-
) external returns (eaddress newValue) {
|
|
43
|
+
) external payable returns (eaddress newValue) {
|
|
44
44
|
return
|
|
45
45
|
eaddress.wrap(
|
|
46
46
|
newInput(ciphertext, user, ETypes.AddressOrUint160OrBytes20)
|
|
@@ -51,7 +51,23 @@ abstract contract EncryptedInput is
|
|
|
51
51
|
bytes memory ciphertext,
|
|
52
52
|
address user,
|
|
53
53
|
ETypes inputType
|
|
54
|
+
) internal paying returns (bytes32 newHandle) {
|
|
55
|
+
newHandle = _newInput(ciphertext, user, inputType);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function newInputNotPaying(
|
|
59
|
+
bytes memory ciphertext,
|
|
60
|
+
address user,
|
|
61
|
+
ETypes inputType
|
|
54
62
|
) internal returns (bytes32 newHandle) {
|
|
63
|
+
newHandle = _newInput(ciphertext, user, inputType);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function _newInput(
|
|
67
|
+
bytes memory ciphertext,
|
|
68
|
+
address user,
|
|
69
|
+
ETypes inputType
|
|
70
|
+
) private returns (bytes32 newHandle) {
|
|
55
71
|
newHandle = getInputHandle(ciphertext, user, msg.sender, inputType);
|
|
56
72
|
// We assume that providing the same handle (which via HADU implies same plaintext, same context, and same
|
|
57
73
|
// instance of encryption)
|
|
@@ -3,15 +3,15 @@ pragma solidity ^0.8;
|
|
|
3
3
|
|
|
4
4
|
import {euint256, ebool, EOps, SenderNotAllowedForHandle, ETypes, isTypeSupported, typeToBitMask} from "../Types.sol";
|
|
5
5
|
import {BaseAccessControlList} from "./AccessControl/BaseAccessControlList.sol";
|
|
6
|
-
import {EventCounter} from "./primitives/EventCounter.sol";
|
|
7
6
|
import {HandleGeneration} from "./primitives/HandleGeneration.sol";
|
|
8
7
|
import {IEncryptedOperations} from "./interfaces/IEncryptedOperations.sol";
|
|
8
|
+
import {Fee} from "./Fee.sol";
|
|
9
9
|
|
|
10
10
|
abstract contract EncryptedOperations is
|
|
11
11
|
IEncryptedOperations,
|
|
12
|
-
EventCounter,
|
|
13
12
|
BaseAccessControlList,
|
|
14
|
-
HandleGeneration
|
|
13
|
+
HandleGeneration,
|
|
14
|
+
Fee
|
|
15
15
|
{
|
|
16
16
|
error UnexpectedType(ETypes actual, bytes32 expectedTypes);
|
|
17
17
|
error UnsupportedType(ETypes actual);
|
|
@@ -600,12 +600,12 @@ abstract contract EncryptedOperations is
|
|
|
600
600
|
|
|
601
601
|
function eRand(
|
|
602
602
|
ETypes randType
|
|
603
|
-
) external returns (bytes32 result) {
|
|
603
|
+
) external paying payable returns (bytes32 result) {
|
|
604
604
|
require(isTypeSupported(randType), UnsupportedType(randType));
|
|
605
605
|
|
|
606
606
|
result = createResultHandle(
|
|
607
607
|
EOps.Rand,
|
|
608
|
-
randType,
|
|
608
|
+
randType,
|
|
609
609
|
bytes32(randCounter++),
|
|
610
610
|
bytes32(uint256(randType))
|
|
611
611
|
);
|
|
@@ -620,7 +620,7 @@ abstract contract EncryptedOperations is
|
|
|
620
620
|
function eRandBounded(
|
|
621
621
|
bytes32 upperBound,
|
|
622
622
|
ETypes randType
|
|
623
|
-
) external returns (bytes32 result) {
|
|
623
|
+
) external paying payable returns (bytes32 result) {
|
|
624
624
|
require(isTypeSupported(randType), UnsupportedType(randType));
|
|
625
625
|
checkInput(upperBound, typeToBitMask(ETypes.Uint256));
|
|
626
626
|
|
|
@@ -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
|
-
|
|
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,37 +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
|
|
37
|
-
error
|
|
38
|
-
error TEEVersionHistoryStatusIsNotPending();
|
|
36
|
+
/// @notice The TEE version was not found in the TEEVersionHistory
|
|
37
|
+
error TEEVersionNotFound();
|
|
39
38
|
error InvalidReportMrAggregated();
|
|
40
|
-
error InvalidBootstrapDataSignature();
|
|
41
|
-
error EOASignerAlreadyInitialized();
|
|
42
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();
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
// Events
|
|
49
|
+
// @notice A new MR_AGGREGATED has been approved
|
|
50
|
+
event NewTEEVersionApproved(uint256 indexed version, bytes32 indexed mrAggregated);
|
|
46
51
|
event NewCovalidatorAdded(address covalidatorAddress, bytes quote);
|
|
47
52
|
event BootstrapStageComplete(
|
|
48
53
|
address indexed newEOASigner,
|
|
49
54
|
BootstrapResult bootstrapResult
|
|
50
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);
|
|
51
61
|
|
|
62
|
+
// Constants
|
|
52
63
|
bytes32 public constant BootstrapResultStructHash =
|
|
53
64
|
keccak256(bytes("BootstrapResult(bytes ecies_pubkey)"));
|
|
65
|
+
bytes32 public constant UpgradeResultStructHash =
|
|
66
|
+
keccak256(bytes("UpgradeResult(bytes network_pubkey)"));
|
|
54
67
|
|
|
55
68
|
uint16 public constant QUOTE_VERIFIER_VERSION = 4;
|
|
56
69
|
|
|
57
70
|
IQuoteVerifier public quoteVerifier;
|
|
58
|
-
BootstrapResult public VerifiedBootstrapResult;
|
|
59
|
-
bool public BootstrapComplete;
|
|
60
71
|
|
|
61
|
-
|
|
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
|
|
62
77
|
bytes public ECIESPubkey;
|
|
63
78
|
mapping(address => bool) public EOASigners;
|
|
64
79
|
|
|
@@ -106,10 +121,10 @@ abstract contract TEELifecycle is
|
|
|
106
121
|
}
|
|
107
122
|
|
|
108
123
|
/**
|
|
109
|
-
* @notice
|
|
124
|
+
* @notice Wrapper around activateNewTEEVersion which verifies the bootstrap result and marks the new TEE version as active
|
|
110
125
|
* @param bootstrapResult - The bootstrap data to verify
|
|
111
126
|
* @param quote - The quote to verify against
|
|
112
|
-
* @param signature - The signature
|
|
127
|
+
* @param signature - The EIP712 signature of the bootstrap result by the TDX EOA
|
|
113
128
|
*/
|
|
114
129
|
function verifyBootstrapResult(
|
|
115
130
|
BootstrapResult calldata bootstrapResult,
|
|
@@ -119,54 +134,114 @@ abstract contract TEELifecycle is
|
|
|
119
134
|
// Make sure the bootstrap is not already complete, and that the contract owner
|
|
120
135
|
// has already submitted the pending TEE MR_AGGREGATED.
|
|
121
136
|
require(!isBootstrapComplete(), BootstrapAlreadyCompleted());
|
|
122
|
-
require(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
126
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
|
+
}
|
|
127
207
|
|
|
128
|
-
|
|
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) {
|
|
129
222
|
(bool success, bytes memory output) = _verifyAndAttestOnChain(quote);
|
|
130
223
|
require(success, string(output));
|
|
131
224
|
|
|
132
|
-
bytes32 v0MrAggregated = TEEVersionHistory[0].mrAggregated;
|
|
133
|
-
|
|
134
225
|
TD10ReportBody memory tdReport = parseTD10ReportBody(quote);
|
|
135
226
|
(address reportDataSigner, bytes32 reportMrAggregated) = parseReport(
|
|
136
227
|
tdReport
|
|
137
228
|
);
|
|
138
229
|
require(
|
|
139
|
-
reportMrAggregated ==
|
|
230
|
+
reportMrAggregated == newMrAggregated,
|
|
140
231
|
InvalidReportMrAggregated()
|
|
141
232
|
);
|
|
142
233
|
address recoveredAddress = ECDSA.recover(
|
|
143
|
-
|
|
234
|
+
resultEip712Digest,
|
|
144
235
|
signature
|
|
145
236
|
);
|
|
146
237
|
require(
|
|
147
238
|
recoveredAddress == reportDataSigner,
|
|
148
|
-
|
|
239
|
+
InvalidEIP712Signature()
|
|
149
240
|
);
|
|
150
241
|
|
|
151
|
-
|
|
152
|
-
TEEVersionHistory[0].status = TEEVersionStatus.ACTIVE;
|
|
153
|
-
emit BootstrapStageComplete(reportDataSigner, bootstrapResult);
|
|
154
|
-
ECIESPubkey = bootstrapResult.ecies_pubkey;
|
|
155
|
-
EOASigners[reportDataSigner] = true;
|
|
156
|
-
//TODO: update ECIES public key to ?? contract state and EOA addresses signers to the Signers contract state
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* @notice Approves a new TEE version and updates the TEEVersionHistory
|
|
161
|
-
* @param newMrAggregated - The MR_AGGREGATED bytes of the new TEE version
|
|
162
|
-
* @dev This function increments the version number automatically based on the current history
|
|
163
|
-
*/
|
|
164
|
-
function approveNewTEEVersion(bytes32 newMrAggregated) public onlyOwner {
|
|
165
|
-
TEEVersionHistory.push(
|
|
166
|
-
TEEVersion({mrAggregated: newMrAggregated, status: TEEVersionStatus.PENDING})
|
|
167
|
-
);
|
|
242
|
+
emit EOAHasUpdatedTDX(reportDataSigner, newMrAggregated);
|
|
168
243
|
|
|
169
|
-
|
|
244
|
+
return reportDataSigner;
|
|
170
245
|
}
|
|
171
246
|
|
|
172
247
|
/**
|
|
@@ -184,25 +259,22 @@ abstract contract TEELifecycle is
|
|
|
184
259
|
);
|
|
185
260
|
require(!EOASigners[reportDataSigner], EOASignerAlreadyInitialized());
|
|
186
261
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
InvalidReportMrAggregated()
|
|
191
|
-
);
|
|
262
|
+
bool isApproved = _isApprovedTEEVersion(reportMrAggregated);
|
|
263
|
+
require(isApproved, TEEVersionNotFound());
|
|
264
|
+
|
|
192
265
|
require(reportDataSigner != address(0), InvalidReportDataSigner());
|
|
193
266
|
emit NewCovalidatorAdded(reportDataSigner, quote);
|
|
194
267
|
EOASigners[reportDataSigner] = true;
|
|
195
|
-
//TODO: Add the new covalidator signers to the Signers contract state
|
|
196
268
|
}
|
|
197
269
|
|
|
198
270
|
/**
|
|
199
|
-
* @notice Checks if the bootstrap is complete
|
|
271
|
+
* @notice Checks if the bootstrap is complete.
|
|
200
272
|
* @return true if the bootstrap is complete, false otherwise
|
|
201
273
|
*/
|
|
202
274
|
function isBootstrapComplete() public view returns (bool) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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;
|
|
206
278
|
}
|
|
207
279
|
|
|
208
280
|
/**
|
|
@@ -361,4 +433,18 @@ abstract contract TEELifecycle is
|
|
|
361
433
|
)
|
|
362
434
|
);
|
|
363
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
|
+
}
|
|
364
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
|
|
15
|
-
* @param mrAggregated - The MR_AGGREGATED 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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
16
|
+
struct UpgradeResult {
|
|
17
|
+
bytes network_pubkey;
|
|
18
|
+
}
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|