@inco/lightning 0.9.0-devnet-test-10 → 0.10.0-devnet-1
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 +150 -0
- package/package.json +8 -8
- package/src/CreateXHelper.sol +1 -1
- package/src/DeployUtils.sol +22 -28
- package/src/IncoLightning.sol +27 -18
- package/src/IncoVerifier.sol +1 -1
- package/src/Lib.alphanet.sol +294 -13
- package/src/Lib.demonet.sol +294 -13
- package/src/Lib.devnet.sol +294 -13
- package/src/Lib.sol +294 -13
- package/src/Lib.template.sol +357 -13
- package/src/Lib.testnet.sol +294 -13
- package/src/Types.sol +44 -0
- package/src/interfaces/IIncoLightning.sol +8 -12
- package/src/interfaces/automata-interfaces/BELE.sol +1 -1
- package/src/interfaces/automata-interfaces/IPCCSRouter.sol +1 -1
- package/src/interfaces/automata-interfaces/IPcsDao.sol +1 -1
- package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +1 -1
- package/src/interfaces/automata-interfaces/Types.sol +1 -1
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +294 -13
- package/src/libs/incoLightning_alphanet_v1_725458969.sol +294 -13
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +294 -13
- package/src/libs/incoLightning_demonet_v0_863421733.sol +294 -13
- package/src/libs/incoLightning_demonet_v2_467437523.sol +294 -13
- package/src/libs/incoLightning_devnet_v0_340846814.sol +294 -13
- package/src/libs/incoLightning_devnet_v10_266391127.sol +1223 -0
- package/src/libs/incoLightning_devnet_v1_904635675.sol +294 -13
- package/src/libs/incoLightning_devnet_v2_295237520.sol +294 -13
- package/src/libs/incoLightning_devnet_v3_976859633.sol +294 -13
- package/src/libs/incoLightning_devnet_v4_409204766.sol +294 -13
- package/src/libs/incoLightning_devnet_v5_203964628.sol +1223 -0
- package/src/libs/incoLightning_devnet_v6_281949651.sol +1223 -0
- package/src/libs/incoLightning_devnet_v7_24560427.sol +1223 -0
- package/src/libs/incoLightning_devnet_v8_985328058.sol +1223 -0
- package/src/libs/incoLightning_devnet_v9_269218568.sol +1223 -0
- package/src/libs/incoLightning_testnet_v0_183408998.sol +294 -13
- package/src/libs/incoLightning_testnet_v2_889158349.sol +294 -13
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +8 -3
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +0 -16
- package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +1 -1
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +3 -2
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +18 -1
- package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +0 -43
- package/src/lightning-parts/DecryptionAttester.sol +124 -2
- package/src/lightning-parts/DecryptionAttester.types.sol +20 -0
- package/src/lightning-parts/EList.sol +397 -0
- package/src/lightning-parts/EncryptedInput.sol +78 -8
- package/src/lightning-parts/EncryptedOperations.sol +40 -34
- package/src/lightning-parts/Fee.sol +29 -0
- package/src/lightning-parts/TEELifecycle.sol +38 -30
- package/src/lightning-parts/TEELifecycle.types.sol +1 -1
- package/src/lightning-parts/TrivialEncryption.sol +1 -2
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +16 -1
- package/src/lightning-parts/interfaces/IEList.sol +38 -0
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +9 -1
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +3 -2
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +1 -1
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +3 -1
- package/src/lightning-parts/primitives/EListHandleGeneration.sol +66 -0
- package/src/lightning-parts/primitives/EListHandleMetadata.sol +67 -0
- package/src/lightning-parts/primitives/HandleGeneration.sol +31 -8
- package/src/lightning-parts/primitives/HandleMetadata.sol +10 -3
- package/src/lightning-parts/primitives/interfaces/IEListHandleMetadata.sol +8 -0
- package/src/lightning-parts/primitives/test/SignatureVerifier.t.sol +1 -1
- package/src/lightning-parts/test/Elist.t.sol +218 -0
- package/src/lightning-parts/test/HandleMetadata.t.sol +66 -23
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +41 -13
- package/src/misc/ABIHelper.sol +15 -0
- package/src/pasted-dependencies/ICreateX.sol +1 -1
- package/src/periphery/IncoUtils.sol +1 -1
- package/src/periphery/SessionVerifier.sol +4 -4
- package/src/shared/IOwnable.sol +1 -1
- package/src/shared/IUUPSUpgradable.sol +1 -1
- package/src/shared/TestUtils.sol +8 -1
- package/src/test/EListTester.sol +171 -0
- package/src/test/FakeIncoInfra/FakeComputeServer.sol +2 -2
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +3 -3
- package/src/test/FakeIncoInfra/MockOpHandler.sol +7 -9
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +2 -1
- package/src/test/FakeIncoInfra/getOpForSelector.sol +0 -2
- package/src/test/IncoTest.sol +17 -5
- package/src/test/OpsTest.sol +3 -2
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +85 -57
- package/src/test/TestDeploy.t.sol +73 -1
- package/src/test/TestFakeInfra.t.sol +32 -6
- package/src/test/TestLib.t.sol +986 -19
- package/src/test/TestReceive.t.sol +42 -0
- package/src/test/TestUpgrade.t.sol +34 -63
- package/src/version/IncoLightningConfig.sol +1 -1
|
@@ -2,21 +2,44 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
import {IncoTest} from "../../test/IncoTest.sol";
|
|
5
|
-
import {
|
|
5
|
+
import {ERC7984DemoToken} from "@inco/incoERC7984/src/ERC7984DemoToken.sol";
|
|
6
6
|
import {DecryptionAttestation} from "../DecryptionAttester.types.sol";
|
|
7
7
|
import {GWEI} from "../../shared/TypeUtils.sol";
|
|
8
|
-
import {euint256} from "@inco/lightning/src/Lib.sol"; // import via remapping or compiler fails
|
|
8
|
+
import {inco, e, euint256} from "@inco/lightning/src/Lib.sol"; // import via remapping or compiler fails
|
|
9
9
|
import {AllowanceProof} from "../AccessControl/AdvancedAccessControl.sol";
|
|
10
|
-
import {inco} from "../../Lib.sol";
|
|
11
10
|
import {euint256 as remappedEuint256} from "@inco/lightning/src/Lib.sol";
|
|
11
|
+
import {
|
|
12
|
+
DecryptionAttestation as remappedDecryptionAttestation
|
|
13
|
+
} from "@inco/lightning/src/lightning-parts/DecryptionAttester.types.sol";
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
/// @notice This test demonstrates how a decryption attestation can be used in a synchronous flow, where the result of the operation is known at the time of requesting the attestation.
|
|
16
|
+
/// In this example, we simulate a token burn operation where the user proves that they have enough balance to burn before actually performing the burn.
|
|
17
|
+
contract TokenBurnCurrentBalance is ERC7984DemoToken {
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
using e for uint256;
|
|
20
|
+
using e for euint256;
|
|
21
|
+
|
|
22
|
+
/// @notice Deploys the token with specified name, symbol, and initial supply
|
|
23
|
+
/// @param name_ The token name
|
|
24
|
+
/// @param symbol_ The token symbol
|
|
25
|
+
/// @param initialSupply The initial supply to mint to the deployer (in base units)
|
|
26
|
+
constructor(string memory name_, string memory symbol_, uint256 initialSupply)
|
|
27
|
+
ERC7984DemoToken(name_, symbol_, initialSupply)
|
|
28
|
+
{
|
|
29
|
+
if (initialSupply > 0) {
|
|
30
|
+
_mint(msg.sender, initialSupply.asEuint256());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// @dev In this burn function, the user provides a decryption attestation that proves they have enough balance to burn the specified amount.
|
|
35
|
+
/// The burn operation is performed synchronously, and the success of the burn is verified using the attestation.
|
|
36
|
+
function burnFullCurrentBalance(remappedDecryptionAttestation memory attestation, bytes[] memory signatures)
|
|
37
|
+
public
|
|
38
|
+
{
|
|
16
39
|
euint256 currentBalance = confidentialBalanceOf(msg.sender);
|
|
17
|
-
require(inco.incoVerifier().isValidDecryptionAttestation(
|
|
18
|
-
require(euint256.unwrap(currentBalance) ==
|
|
19
|
-
publicBurn(msg.sender, uint256(
|
|
40
|
+
require(inco.incoVerifier().isValidDecryptionAttestation(attestation, signatures), "Invalid Signature");
|
|
41
|
+
require(euint256.unwrap(currentBalance) == attestation.handle, "Handle mismatch");
|
|
42
|
+
publicBurn(msg.sender, uint256(attestation.value));
|
|
20
43
|
}
|
|
21
44
|
|
|
22
45
|
}
|
|
@@ -26,19 +49,24 @@ contract TestDecryptionAttestationInSynchronousFlow is IncoTest {
|
|
|
26
49
|
AllowanceProof emptyProof; // no proof needed when requester has the handle in persisted allowed pairs
|
|
27
50
|
|
|
28
51
|
function testSynchronousBurning() public {
|
|
29
|
-
TokenBurnCurrentBalance token = new TokenBurnCurrentBalance();
|
|
52
|
+
TokenBurnCurrentBalance token = new TokenBurnCurrentBalance("DemoToken", "DMT", 100 ether);
|
|
30
53
|
vm.deal(address(token), 100 ether);
|
|
31
|
-
token.confidentialTransfer(alice, fakePrepareEuint256Ciphertext(10 * GWEI, address(this), address(token))
|
|
54
|
+
token.confidentialTransfer(alice, fakePrepareEuint256Ciphertext(10 * GWEI, address(this), address(token)));
|
|
32
55
|
processAllOperations(); // saves Alice's balance
|
|
56
|
+
|
|
33
57
|
bytes32 aliceCurrentBalanceHandle = euint256.unwrap(token.confidentialBalanceOf(alice));
|
|
34
58
|
// simulates Alice requesting for a decryption attestation of Ge op on her balance and the amount
|
|
35
59
|
// she intends to burn, therefore proving to the token contract that the operation will succeed
|
|
36
|
-
(DecryptionAttestation memory
|
|
60
|
+
(DecryptionAttestation memory attestation, bytes[] memory signatures) =
|
|
37
61
|
getDecryptionAttestation(alice, HandleWithProof({handle: aliceCurrentBalanceHandle, proof: emptyProof}));
|
|
38
|
-
vm.prank(alice);
|
|
39
62
|
|
|
63
|
+
// Convert attestation to remapped type for cross-project compatibility
|
|
64
|
+
remappedDecryptionAttestation memory remappedAttestation =
|
|
65
|
+
remappedDecryptionAttestation({handle: attestation.handle, value: attestation.value});
|
|
66
|
+
|
|
67
|
+
vm.prank(alice);
|
|
40
68
|
// the decryption attestation is passed to the token burn method
|
|
41
|
-
token.burnFullCurrentBalance(
|
|
69
|
+
token.burnFullCurrentBalance(remappedAttestation, signatures);
|
|
42
70
|
|
|
43
71
|
processAllOperations();
|
|
44
72
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {Session} from "@inco/lightning/src/periphery/SessionVerifier.sol";
|
|
5
|
+
|
|
6
|
+
// @dev this contract is not used on-chain, it is only used to generate the
|
|
7
|
+
// ABI of some symbols that are not exposed directly by the IncoLightning or
|
|
8
|
+
// periphery contracts, but are needed for the JS SDK.
|
|
9
|
+
contract ABIHelper {
|
|
10
|
+
|
|
11
|
+
function getSession() public pure returns (Session memory) {
|
|
12
|
+
revert("This function exists only to include Session struct in ABI");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
}
|
|
@@ -5,7 +5,7 @@ import {StorageSlot} from "@openzeppelin/contracts/utils/StorageSlot.sol";
|
|
|
5
5
|
|
|
6
6
|
// Re-export FEE constant for convenience - consumers can import both IncoUtils and FEE from this file
|
|
7
7
|
// forge-lint: disable-next-line(unused-import)
|
|
8
|
-
import {FEE} from "../lightning-parts/Fee.sol";
|
|
8
|
+
import {FEE, BIT_FEE} from "../lightning-parts/Fee.sol";
|
|
9
9
|
|
|
10
10
|
contract IncoUtils {
|
|
11
11
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: No License
|
|
2
|
-
pragma solidity ^0.8;
|
|
2
|
+
pragma solidity ^0.8.29;
|
|
3
3
|
|
|
4
4
|
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
|
|
5
5
|
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
@@ -38,13 +38,13 @@ struct Session {
|
|
|
38
38
|
contract SessionVerifier is UUPSUpgradeable, OwnableUpgradeable, Version {
|
|
39
39
|
|
|
40
40
|
/// @notice Initializes the SessionVerifier with version information
|
|
41
|
-
/// @param
|
|
42
|
-
constructor(bytes32
|
|
41
|
+
/// @param _salt Unique salt used for deterministic deployment via CreateX
|
|
42
|
+
constructor(bytes32 _salt)
|
|
43
43
|
Version(
|
|
44
44
|
SESSION_VERIFIER_MAJOR_VERSION,
|
|
45
45
|
SESSION_VERIFIER_MINOR_VERSION,
|
|
46
46
|
SESSION_VERIFIER_PATCH_VERSION,
|
|
47
|
-
|
|
47
|
+
_salt,
|
|
48
48
|
SESSION_VERIFIER_NAME
|
|
49
49
|
)
|
|
50
50
|
{}
|
package/src/shared/IOwnable.sol
CHANGED
package/src/shared/TestUtils.sol
CHANGED
|
@@ -3,8 +3,13 @@ pragma solidity ^0.8;
|
|
|
3
3
|
|
|
4
4
|
import {Test} from "forge-std/Test.sol";
|
|
5
5
|
|
|
6
|
+
/// @title TestUtils
|
|
7
|
+
/// @notice WARNING: This contract contains TEST KEYS for LOCAL DEVELOPMENT ONLY.
|
|
8
|
+
/// @dev These keys are publicly known Anvil accounts and have NO security value.
|
|
9
|
+
/// NEVER use these keys on production networks - anyone can derive the private keys.
|
|
6
10
|
contract TestUtils is Test {
|
|
7
11
|
|
|
12
|
+
// WARNING: Well-known Anvil account #0 - publicly known private key, DO NOT use in production
|
|
8
13
|
address private constant ANVIL_ZEROTH_ADDRESS = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
|
|
9
14
|
uint256 private constant ANVIL_ZEROTH_PRIVATE_KEY =
|
|
10
15
|
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
|
|
@@ -20,7 +25,9 @@ contract TestUtils is Test {
|
|
|
20
25
|
uint256 internal evePrivKey;
|
|
21
26
|
address internal immutable eve;
|
|
22
27
|
|
|
23
|
-
//
|
|
28
|
+
// WARNING: These are well-known Anvil test keys with publicly known private keys.
|
|
29
|
+
// They are convenient for e2e tests but have NO security value.
|
|
30
|
+
// Deploy.s.sol has safeguards to prevent using these on non-test chains.
|
|
24
31
|
address internal teeEOA = ANVIL_ZEROTH_ADDRESS;
|
|
25
32
|
uint256 internal teePrivKey = ANVIL_ZEROTH_PRIVATE_KEY;
|
|
26
33
|
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// SPDX-License-Identifier: No License
|
|
2
|
+
pragma solidity ^0.8;
|
|
3
|
+
|
|
4
|
+
import {IIncoLightning} from "../interfaces/IIncoLightning.sol";
|
|
5
|
+
/// forge-lint: disable-next-line(unused-import)
|
|
6
|
+
import {ETypes, elist, typeBitSize} from "../Types.sol";
|
|
7
|
+
import {euint256} from "../Types.sol";
|
|
8
|
+
import {IncoUtils, FEE, BIT_FEE} from "../periphery/IncoUtils.sol";
|
|
9
|
+
|
|
10
|
+
contract ElistTester is IncoUtils {
|
|
11
|
+
|
|
12
|
+
/// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
13
|
+
IIncoLightning immutable inco;
|
|
14
|
+
|
|
15
|
+
constructor(IIncoLightning _inco) {
|
|
16
|
+
inco = _inco;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
elist public list;
|
|
20
|
+
elist public newRangeList;
|
|
21
|
+
|
|
22
|
+
function newEList(bytes[] memory inputs, ETypes listType, address user)
|
|
23
|
+
public
|
|
24
|
+
payable
|
|
25
|
+
refundUnspent
|
|
26
|
+
returns (elist)
|
|
27
|
+
{
|
|
28
|
+
list = inco.newEList{value: FEE * inputs.length}(inputs, listType, user);
|
|
29
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
30
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
31
|
+
return list;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function listAppend(bytes memory ctValue) public payable refundUnspent returns (elist) {
|
|
35
|
+
euint256 handle = inco.newEuint256{value: FEE}(ctValue, msg.sender);
|
|
36
|
+
inco.allow(euint256.unwrap(handle), address(this));
|
|
37
|
+
inco.allow(euint256.unwrap(handle), address(msg.sender));
|
|
38
|
+
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
39
|
+
list = inco.listAppend{value: (uint256(inco.lengthOf(elist.unwrap(list))) * typeBits + typeBits) * BIT_FEE}(
|
|
40
|
+
list, euint256.unwrap(handle)
|
|
41
|
+
);
|
|
42
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
43
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
44
|
+
return list;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function listGet(uint16 index) public returns (bytes32) {
|
|
48
|
+
bytes32 res = inco.listGet(list, index);
|
|
49
|
+
inco.allow(res, msg.sender);
|
|
50
|
+
return res;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function newEList(bytes32[] memory handles, ETypes listType) public payable refundUnspent returns (elist) {
|
|
54
|
+
list = inco.newEList{value: FEE * handles.length}(handles, listType);
|
|
55
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
56
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
57
|
+
return list;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function listGetOr(bytes memory ctIndex, bytes memory ctDefaultValue)
|
|
61
|
+
public
|
|
62
|
+
payable
|
|
63
|
+
refundUnspent
|
|
64
|
+
returns (bytes32)
|
|
65
|
+
{
|
|
66
|
+
euint256 index = inco.newEuint256{value: FEE}(ctIndex, msg.sender);
|
|
67
|
+
euint256 defaultValue = inco.newEuint256{value: FEE}(ctDefaultValue, msg.sender);
|
|
68
|
+
bytes32 res = inco.listGetOr(list, euint256.unwrap(index), euint256.unwrap(defaultValue));
|
|
69
|
+
inco.allow(res, msg.sender);
|
|
70
|
+
return res;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function listSet(bytes memory ctIndex, bytes memory ctValue) public payable refundUnspent returns (elist) {
|
|
74
|
+
euint256 index = inco.newEuint256{value: FEE}(ctIndex, msg.sender);
|
|
75
|
+
euint256 value = inco.newEuint256{value: FEE}(ctValue, msg.sender);
|
|
76
|
+
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
77
|
+
list = inco.listSet{value: uint256(inco.lengthOf(elist.unwrap(list))) * typeBits * BIT_FEE}(
|
|
78
|
+
list, euint256.unwrap(index), euint256.unwrap(value)
|
|
79
|
+
);
|
|
80
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
81
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
82
|
+
return list;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function listInsert(bytes memory ctIndex, bytes memory ctValue) public payable refundUnspent returns (elist) {
|
|
86
|
+
euint256 index = inco.newEuint256{value: FEE}(ctIndex, msg.sender);
|
|
87
|
+
euint256 value = inco.newEuint256{value: FEE}(ctValue, msg.sender);
|
|
88
|
+
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
89
|
+
list = inco.listInsert{value: (uint256(inco.lengthOf(elist.unwrap(list))) * typeBits + typeBits) * BIT_FEE}(
|
|
90
|
+
list, euint256.unwrap(index), euint256.unwrap(value)
|
|
91
|
+
);
|
|
92
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
93
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
94
|
+
return list;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function listConcat(bytes[] memory cts, ETypes listType, address user)
|
|
98
|
+
public
|
|
99
|
+
payable
|
|
100
|
+
refundUnspent
|
|
101
|
+
returns (elist)
|
|
102
|
+
{
|
|
103
|
+
elist rhs = inco.newEList{value: FEE * cts.length}(cts, listType, user);
|
|
104
|
+
inco.allow(elist.unwrap(rhs), address(this));
|
|
105
|
+
inco.allow(elist.unwrap(rhs), address(msg.sender));
|
|
106
|
+
uint256 lhsBits =
|
|
107
|
+
uint256(inco.lengthOf(elist.unwrap(list))) * typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
108
|
+
uint256 rhsBits =
|
|
109
|
+
uint256(inco.lengthOf(elist.unwrap(rhs))) * typeBitSize(ETypes(uint8(uint256(elist.unwrap(rhs)) >> 16)));
|
|
110
|
+
list = inco.listConcat{value: (lhsBits + rhsBits) * BIT_FEE}(list, rhs);
|
|
111
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
112
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
113
|
+
return list;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function listSlice(bytes memory ctStart, uint16 len, bytes memory ctDefaultValue)
|
|
117
|
+
public
|
|
118
|
+
payable
|
|
119
|
+
refundUnspent
|
|
120
|
+
returns (elist)
|
|
121
|
+
{
|
|
122
|
+
euint256 start = inco.newEuint256{value: FEE}(ctStart, msg.sender);
|
|
123
|
+
euint256 defaultValue = inco.newEuint256{value: FEE}(ctDefaultValue, msg.sender);
|
|
124
|
+
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
125
|
+
list = inco.listSlice{value: uint256(len) * typeBits * BIT_FEE}(
|
|
126
|
+
list, euint256.unwrap(start), len, euint256.unwrap(defaultValue)
|
|
127
|
+
);
|
|
128
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
129
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
130
|
+
return list;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function listRange(uint16 start, uint16 end, ETypes listType) public payable returns (elist) {
|
|
134
|
+
newRangeList =
|
|
135
|
+
inco.listRange{value: uint256(end - start) * typeBitSize(listType) * BIT_FEE}(start, end, listType);
|
|
136
|
+
inco.allow(elist.unwrap(newRangeList), address(this));
|
|
137
|
+
inco.allow(elist.unwrap(newRangeList), address(msg.sender));
|
|
138
|
+
return newRangeList;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function listGetRange(uint16 index) public returns (bytes32) {
|
|
142
|
+
bytes32 res = inco.listGet(newRangeList, index);
|
|
143
|
+
inco.allow(res, msg.sender);
|
|
144
|
+
return res;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function listShuffle() public payable refundUnspent returns (elist) {
|
|
148
|
+
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
149
|
+
list = inco.listShuffle{value: uint256(inco.lengthOf(elist.unwrap(list))) * typeBits * BIT_FEE}(list);
|
|
150
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
151
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
152
|
+
return list;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function listReveal() public {
|
|
156
|
+
inco.reveal(elist.unwrap(list));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function listReverse() public payable returns (elist) {
|
|
160
|
+
uint256 typeBits = typeBitSize(ETypes(uint8(uint256(elist.unwrap(list)) >> 16)));
|
|
161
|
+
list = inco.listReverse{value: uint256(inco.lengthOf(elist.unwrap(list))) * typeBits * BIT_FEE}(list);
|
|
162
|
+
inco.allow(elist.unwrap(list), address(this));
|
|
163
|
+
inco.allow(elist.unwrap(list), address(msg.sender));
|
|
164
|
+
return list;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
receive() external payable {
|
|
168
|
+
// Allow contract to receive ETH
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
}
|
|
@@ -14,9 +14,9 @@ contract FakeComputeServer {
|
|
|
14
14
|
} else if (op == EOps.Mul) {
|
|
15
15
|
return lhs * rhs;
|
|
16
16
|
} else if (op == EOps.Div) {
|
|
17
|
-
return lhs / rhs;
|
|
17
|
+
return rhs == 0 ? type(uint256).max : lhs / rhs;
|
|
18
18
|
} else if (op == EOps.Rem) {
|
|
19
|
-
return lhs % rhs;
|
|
19
|
+
return rhs == 0 ? lhs : lhs % rhs;
|
|
20
20
|
} else if (op == EOps.Min) {
|
|
21
21
|
return lhs < rhs ? lhs : rhs;
|
|
22
22
|
} else if (op == EOps.Max) {
|
|
@@ -19,16 +19,16 @@ contract FakeIncoInfraBase is TestUtils, KVStore, HandleGeneration {
|
|
|
19
19
|
{
|
|
20
20
|
// We need a single word here to get correct encoding
|
|
21
21
|
bytes memory ciphertext = abi.encode(word);
|
|
22
|
+
uint16 version = 2; // version - X-Wing
|
|
22
23
|
bytes32 handle = getInputHandle(
|
|
23
24
|
ciphertext,
|
|
24
25
|
address(inco),
|
|
25
26
|
user,
|
|
26
27
|
contractAddress,
|
|
27
|
-
|
|
28
|
-
/* unspecified */
|
|
28
|
+
version, // version - X-Wing
|
|
29
29
|
inputType
|
|
30
30
|
);
|
|
31
|
-
input = abi.encodePacked(
|
|
31
|
+
input = abi.encodePacked(uint32(version), abi.encode(handle, ciphertext));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function fakePrepareEuint256Ciphertext(uint256 value, address userAddress, address contractAddress)
|
|
@@ -46,10 +46,6 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
46
46
|
ebool value = ebool.wrap(log.topics[1]);
|
|
47
47
|
ebool result = ebool.wrap(log.topics[2]);
|
|
48
48
|
handleENot(value, result);
|
|
49
|
-
} else if (op == EOps.Rand) {
|
|
50
|
-
uint256 counter = uint256(log.topics[1]);
|
|
51
|
-
euint256 result = euint256.wrap(log.topics[2]);
|
|
52
|
-
handleERand(counter, result);
|
|
53
49
|
} else if (op == EOps.RandBounded) {
|
|
54
50
|
uint256 counter = uint256(log.topics[1]);
|
|
55
51
|
euint256 upperBound = euint256.wrap(log.topics[2]);
|
|
@@ -85,12 +81,14 @@ contract MockOpHandler is FakeIncoInfraBase, FakeComputeServer {
|
|
|
85
81
|
set(ebool.unwrap(result), asBytes32(!getBoolValue(value)));
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
function handleERand(uint256 counter, euint256 result) private {
|
|
89
|
-
set(euint256.unwrap(result), bytes32(counter));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
84
|
function handleERandBounded(uint256 counter, euint256 upperBound, euint256 result) private {
|
|
93
|
-
|
|
85
|
+
uint256 bound = getUint256Value(upperBound);
|
|
86
|
+
if (bound == 0) {
|
|
87
|
+
// upperBound of 0 means unbounded (used by rand())
|
|
88
|
+
set(euint256.unwrap(result), bytes32(counter));
|
|
89
|
+
} else {
|
|
90
|
+
set(euint256.unwrap(result), bytes32(counter % bound));
|
|
91
|
+
}
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
function handleIfThenElse(ebool control, bytes32 lhs, bytes32 rhs, bytes32 result) private {
|
|
@@ -60,7 +60,8 @@ contract MockRemoteAttestation is TestUtils {
|
|
|
60
60
|
hex"010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";
|
|
61
61
|
// See DEFAULT_MR_AGGREGATED in attestation/src/remote_attestation.rs to
|
|
62
62
|
// see the calculation of the default value.
|
|
63
|
-
|
|
63
|
+
// Note: This uses abi.encode (not encodePacked) to avoid hash collision vulnerabilities.
|
|
64
|
+
mrAggregated = hex"3d48a1faa8620d86ae037f4fd6746987733d085314b3cd5d5d074ade8bab6ebd";
|
|
64
65
|
bootstrapResult = BootstrapResult({networkPubkey: networkPubkey});
|
|
65
66
|
|
|
66
67
|
quote = createQuote(mrtd, signer);
|
|
@@ -59,8 +59,6 @@ function getOpForSelector(bytes32 opEventSelector) pure returns (EOps) {
|
|
|
59
59
|
return EOps.TrivialEncrypt;
|
|
60
60
|
} else if (opEventSelector == EncryptedOperations.EIfThenElse.selector) {
|
|
61
61
|
return EOps.IfThenElse;
|
|
62
|
-
} else if (opEventSelector == EncryptedOperations.ERand.selector) {
|
|
63
|
-
return EOps.Rand;
|
|
64
62
|
} else if (opEventSelector == EncryptedOperations.ERandBounded.selector) {
|
|
65
63
|
return EOps.RandBounded;
|
|
66
64
|
} else if (opEventSelector == BaseAccessControlList.Allow.selector) {
|
package/src/test/IncoTest.sol
CHANGED
|
@@ -12,11 +12,12 @@ import {FakeQuoteVerifier} from "./FakeIncoInfra/FakeQuoteVerifier.sol";
|
|
|
12
12
|
import {IOwnable} from "../../src/shared/IOwnable.sol";
|
|
13
13
|
import {MockRemoteAttestation} from "./FakeIncoInfra/MockRemoteAttestation.sol";
|
|
14
14
|
import {BootstrapResult} from "../lightning-parts/TEELifecycle.types.sol";
|
|
15
|
+
import {Safe} from "safe-smart-account/Safe.sol";
|
|
16
|
+
import {SafeProxyFactory} from "safe-smart-account/proxies/SafeProxyFactory.sol";
|
|
15
17
|
|
|
16
18
|
contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRemoteAttestation {
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
address immutable owner;
|
|
20
|
+
address owner;
|
|
20
21
|
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
21
22
|
address immutable testDeployer;
|
|
22
23
|
|
|
@@ -31,7 +32,6 @@ contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRem
|
|
|
31
32
|
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
|
|
32
33
|
|
|
33
34
|
constructor() {
|
|
34
|
-
owner = getLabeledAddress("owner");
|
|
35
35
|
// extracted from the deploy script running as bare simulation with:
|
|
36
36
|
// forge script src/script/Deploy.s.sol:Deploy
|
|
37
37
|
testDeployer = deployedBy;
|
|
@@ -42,17 +42,29 @@ contract IncoTest is MockOpHandler, DeployUtils, FakeDecryptionAttester, MockRem
|
|
|
42
42
|
|
|
43
43
|
function setUp() public virtual {
|
|
44
44
|
deployCreateX();
|
|
45
|
+
|
|
46
|
+
// Create a Safe multisig (alice, bob, carol) with threshold 2 to act as owner
|
|
47
|
+
Safe master = new Safe();
|
|
48
|
+
SafeProxyFactory factory = new SafeProxyFactory();
|
|
49
|
+
address[] memory safeOwners = new address[](3);
|
|
50
|
+
safeOwners[0] = alice;
|
|
51
|
+
safeOwners[1] = bob;
|
|
52
|
+
safeOwners[2] = carol;
|
|
53
|
+
bytes memory setupData = abi.encodeWithSelector(
|
|
54
|
+
Safe.setup.selector, safeOwners, 2, address(0), bytes(""), address(0), address(0), 0, payable(address(0))
|
|
55
|
+
);
|
|
56
|
+
owner = address(Safe(payable(factory.createProxyWithNonce(address(master), setupData, 0))));
|
|
57
|
+
|
|
45
58
|
vm.startPrank(testDeployer);
|
|
46
59
|
vm.setEnv("SHOULD_SETUP_TEE_SIGNER", "true"); // results in a network pubkey and decrypt signer being populated in the TEE Lifecycle
|
|
47
60
|
(IIncoLightning proxy,) = deployIncoLightningUsingConfig({
|
|
48
61
|
deployer: testDeployer,
|
|
62
|
+
owner: owner,
|
|
49
63
|
// The highest precedent deployment
|
|
50
64
|
// We select the pepper that will be used that will be generated in the lib.sol (usually "testnet"), but currently "alphanet" has higher major version
|
|
51
65
|
pepper: "devnet",
|
|
52
66
|
quoteVerifier: new FakeQuoteVerifier()
|
|
53
67
|
});
|
|
54
|
-
IOwnable(address(proxy)).transferOwnership(owner);
|
|
55
|
-
IOwnable(address(inco.incoVerifier())).transferOwnership(owner);
|
|
56
68
|
vm.stopPrank();
|
|
57
69
|
console.log("Deployed %s (proxy) to: %s", proxy.getName(), address(proxy));
|
|
58
70
|
console.log("Generated inco address: %s", address(inco));
|
package/src/test/OpsTest.sol
CHANGED
|
@@ -380,8 +380,9 @@ contract OpsTest is Fee {
|
|
|
380
380
|
|
|
381
381
|
// ============ RANDOM NUMBER GENERATION ============
|
|
382
382
|
|
|
383
|
-
function
|
|
384
|
-
euint256 result =
|
|
383
|
+
function testRandUnbounded() external payable returns (euint256) {
|
|
384
|
+
euint256 result =
|
|
385
|
+
euint256.wrap(inco.eRandBounded{value: getFee()}(euint256.unwrap(inco.asEuint256(0)), ETypes.Uint256));
|
|
385
386
|
inco.allow(euint256.unwrap(result), address(this));
|
|
386
387
|
inco.allow(euint256.unwrap(result), msg.sender);
|
|
387
388
|
return result;
|