@inco/lightning 0.6.7 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -2
- package/manifest.yaml +0 -42
- package/package.json +5 -2
- package/src/CreateXHelper.sol +3 -1
- package/src/DeployUtils.sol +36 -71
- package/src/Errors.sol +1 -1
- package/src/IIncoLightning.sol +2 -0
- package/src/IncoLightning.sol +5 -17
- package/src/IncoVerifier.sol +12 -18
- package/src/Lib.template.sol +40 -159
- package/src/Types.sol +233 -97
- package/src/interfaces/IIncoLightning.sol +2 -0
- package/src/interfaces/IIncoVerifier.sol +7 -12
- package/src/interfaces/automata-interfaces/BELE.sol +2 -0
- package/src/interfaces/automata-interfaces/IAutomataEnclaveIdentityDao.sol +9 -11
- package/src/interfaces/automata-interfaces/IFmspcTcbDao.sol +3 -3
- package/src/interfaces/automata-interfaces/IPCCSRouter.sol +13 -47
- package/src/interfaces/automata-interfaces/IPCCSRouterExtended.sol +2 -0
- package/src/interfaces/automata-interfaces/IPcsDao.sol +6 -11
- package/src/interfaces/automata-interfaces/IQuoteVerifier.sol +4 -7
- package/src/interfaces/automata-interfaces/Types.sol +7 -6
- package/src/libs/incoLightning_devnet_v1_887305889.sol +5 -3
- package/src/libs/incoLightning_testnet_v1_938327937.sol +5 -3
- package/src/lightning-parts/AccessControl/AdvancedAccessControl.sol +41 -75
- package/src/lightning-parts/AccessControl/BaseAccessControlList.sol +31 -62
- package/src/lightning-parts/AccessControl/interfaces/IAdvancedAccessControl.sol +8 -15
- package/src/lightning-parts/AccessControl/interfaces/IBaseAccessControlList.sol +5 -12
- package/src/lightning-parts/AccessControl/test/TestAdvancedAccessControl.t.sol +42 -83
- package/src/lightning-parts/AccessControl/test/TestBaseAccessControl.t.sol +2 -0
- package/src/lightning-parts/DecryptionAttester.sol +14 -28
- package/src/lightning-parts/EncryptedInput.sol +23 -52
- package/src/lightning-parts/EncryptedOperations.sol +93 -440
- package/src/lightning-parts/Fee.sol +3 -1
- package/src/lightning-parts/TEELifecycle.sol +95 -225
- package/src/lightning-parts/TEELifecycle.types.sol +4 -3
- package/src/lightning-parts/TrivialEncryption.sol +6 -20
- package/src/lightning-parts/interfaces/IDecryptionAttester.sol +7 -2
- package/src/lightning-parts/interfaces/IEncryptedInput.sol +5 -12
- package/src/lightning-parts/interfaces/IEncryptedOperations.sol +17 -61
- package/src/lightning-parts/interfaces/ITEELifecycle.sol +7 -11
- package/src/lightning-parts/interfaces/ITrivialEncryption.sol +2 -0
- package/src/lightning-parts/primitives/EventCounter.sol +7 -8
- package/src/lightning-parts/primitives/HandleGeneration.sol +20 -32
- package/src/lightning-parts/primitives/HandleMetadata.sol +7 -17
- package/src/lightning-parts/primitives/LightningAddressGetter.sol +3 -0
- package/src/lightning-parts/primitives/SignatureVerifier.sol +91 -27
- package/src/lightning-parts/primitives/VerifierAddressGetter.sol +3 -0
- package/src/lightning-parts/primitives/interfaces/IEventCounter.sol +2 -0
- package/src/lightning-parts/primitives/interfaces/IHandleGeneration.sol +10 -2
- package/src/lightning-parts/primitives/interfaces/ISignatureVerifier.sol +4 -2
- package/src/lightning-parts/primitives/interfaces/IVerifierAddressGetter.sol +2 -0
- package/src/lightning-parts/primitives/test/SignatureVerifier.t.sol +838 -0
- package/src/lightning-parts/test/Fee.t.sol +6 -6
- package/src/lightning-parts/test/HandleMetadata.t.sol +21 -76
- package/src/lightning-parts/test/InputsFee.t.sol +7 -28
- package/src/lightning-parts/test/TestDecryptionAttestationInSynchronousFlow.t.sol +16 -48
- package/src/pasted-dependencies/CreateX.sol +146 -419
- package/src/pasted-dependencies/ICreateX.sol +58 -102
- package/src/periphery/SessionVerifier.sol +5 -7
- package/src/shared/IOwnable.sol +3 -0
- package/src/shared/IUUPSUpgradable.sol +5 -1
- package/src/shared/JsonUtils.sol +3 -5
- package/src/shared/TestUtils.sol +14 -13
- package/src/test/AddTwo.sol +9 -7
- package/src/test/FakeIncoInfra/FakeComputeServer.sol +11 -53
- package/src/test/FakeIncoInfra/FakeDecryptionAttester.sol +35 -118
- package/src/test/FakeIncoInfra/FakeIncoInfraBase.sol +31 -48
- package/src/test/FakeIncoInfra/FakeQuoteVerifier.sol +4 -7
- package/src/test/FakeIncoInfra/KVStore.sol +2 -0
- package/src/test/FakeIncoInfra/MockOpHandler.sol +9 -31
- package/src/test/FakeIncoInfra/MockRemoteAttestation.sol +44 -21
- package/src/test/IncoTest.sol +15 -9
- package/src/test/OpsTest.sol +429 -0
- package/src/test/TEELifecycle/TEELifecycleMockTest.t.sol +58 -104
- package/src/test/TestAddTwo.t.sol +4 -3
- package/src/test/TestDeploy.t.sol +5 -6
- package/src/test/TestExtractDataOfEventTooLarge.t.sol +7 -14
- package/src/test/TestFakeInfra.t.sol +15 -38
- package/src/test/TestUpgrade.t.sol +40 -135
- package/src/test/TestVersion.t.sol +6 -5
- package/src/version/IncoLightningConfig.sol +1 -1
- package/src/version/Version.sol +48 -51
- package/src/version/interfaces/IVersion.sol +6 -0
|
@@ -7,6 +7,7 @@ import {IncoTest} from "./IncoTest.sol";
|
|
|
7
7
|
import {AddTwo} from "./AddTwo.sol";
|
|
8
8
|
|
|
9
9
|
contract TestAddTwo is IncoTest {
|
|
10
|
+
|
|
10
11
|
AddTwo addTwo;
|
|
11
12
|
|
|
12
13
|
function setUp() public override {
|
|
@@ -25,9 +26,8 @@ contract TestAddTwo is IncoTest {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
function testAddTwoEoaAndPublicReveal() public {
|
|
28
|
-
(euint256 result, euint256 revealedResult) =
|
|
29
|
-
fakePrepareEuint256Ciphertext(3, address(this), address(addTwo))
|
|
30
|
-
);
|
|
29
|
+
(euint256 result, euint256 revealedResult) =
|
|
30
|
+
addTwo.addTwoEoa(fakePrepareEuint256Ciphertext(3, address(this), address(addTwo)));
|
|
31
31
|
processAllOperations();
|
|
32
32
|
assertEq(getUint256Value(result), 5);
|
|
33
33
|
assertEq(getUint256Value(revealedResult), 5);
|
|
@@ -41,4 +41,5 @@ contract TestAddTwo is IncoTest {
|
|
|
41
41
|
assertEq(getBoolValue(trueVal), true);
|
|
42
42
|
assertTrue(inco.isAllowed(ebool.unwrap(trueVal), bob));
|
|
43
43
|
}
|
|
44
|
+
|
|
44
45
|
}
|
|
@@ -9,24 +9,22 @@ import {inco} from "../Lib.sol";
|
|
|
9
9
|
import {IncoTest} from "./IncoTest.sol";
|
|
10
10
|
|
|
11
11
|
contract ReturnTwo is UUPSUpgradeable {
|
|
12
|
+
|
|
12
13
|
function getTwo() external pure returns (uint256) {
|
|
13
14
|
return 2;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
function _authorizeUpgrade(address) internal override {}
|
|
18
|
+
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
contract TestDeploy is Test, IncoTest {
|
|
22
|
+
|
|
20
23
|
// todo test that inco gets deployed at the predicted address
|
|
21
24
|
|
|
22
25
|
function testDeployedCorrectly() public {
|
|
23
26
|
vm.expectEmit(false, false, true, false, address(inco));
|
|
24
|
-
emit TrivialEncryption.TrivialEncrypt(
|
|
25
|
-
bytes32(uint256(1)),
|
|
26
|
-
bytes32(uint256(1)),
|
|
27
|
-
ETypes.Bool,
|
|
28
|
-
0
|
|
29
|
-
);
|
|
27
|
+
emit TrivialEncryption.TrivialEncrypt(bytes32(uint256(1)), bytes32(uint256(1)), ETypes.Bool, 0);
|
|
30
28
|
inco.asEbool(true);
|
|
31
29
|
}
|
|
32
30
|
|
|
@@ -36,4 +34,5 @@ contract TestDeploy is Test, IncoTest {
|
|
|
36
34
|
inco.upgradeToAndCall(address(newImplem), "");
|
|
37
35
|
assertEq(ReturnTwo(address(inco)).getTwo(), 2);
|
|
38
36
|
}
|
|
37
|
+
|
|
39
38
|
}
|
|
@@ -3,27 +3,19 @@ pragma solidity ^0.8;
|
|
|
3
3
|
|
|
4
4
|
import {Test, Vm, console} from "forge-std/Test.sol";
|
|
5
5
|
|
|
6
|
-
event EventTooLarge(
|
|
7
|
-
|
|
8
|
-
bytes32 indexed ifTrue,
|
|
9
|
-
bytes32 indexed ifFalse,
|
|
10
|
-
bytes32 indexed result,
|
|
11
|
-
uint256 eventId
|
|
12
|
-
);
|
|
6
|
+
event EventTooLarge( // can't index >3 fields
|
|
7
|
+
bytes32 control, bytes32 indexed ifTrue, bytes32 indexed ifFalse, bytes32 indexed result, uint256 eventId);
|
|
13
8
|
|
|
14
9
|
contract Emitter {
|
|
10
|
+
|
|
15
11
|
function emitEventTooLarge() external {
|
|
16
|
-
emit EventTooLarge(
|
|
17
|
-
bytes32(uint256(1)),
|
|
18
|
-
bytes32(uint256(2)),
|
|
19
|
-
bytes32(uint256(3)),
|
|
20
|
-
bytes32(uint256(4)),
|
|
21
|
-
5
|
|
22
|
-
);
|
|
12
|
+
emit EventTooLarge(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3)), bytes32(uint256(4)), 5);
|
|
23
13
|
}
|
|
14
|
+
|
|
24
15
|
}
|
|
25
16
|
|
|
26
17
|
contract TestExtractDataOfEventTooLarge is Test {
|
|
18
|
+
|
|
27
19
|
function testEmit() public {
|
|
28
20
|
Emitter emitter = new Emitter();
|
|
29
21
|
vm.recordLogs();
|
|
@@ -40,4 +32,5 @@ contract TestExtractDataOfEventTooLarge is Test {
|
|
|
40
32
|
assertEq(first32Bytes, bytes32(uint256(1)));
|
|
41
33
|
assertEq(second32Bytes, bytes32(uint256(5)));
|
|
42
34
|
}
|
|
35
|
+
|
|
43
36
|
}
|
|
@@ -5,13 +5,10 @@ import {IncoTest} from "./IncoTest.sol";
|
|
|
5
5
|
import {e, euint256, ebool, eaddress, inco} from "../Lib.sol";
|
|
6
6
|
import {SenderNotAllowedForHandle} from "../Types.sol";
|
|
7
7
|
import {TEELifecycle} from "../lightning-parts/TEELifecycle.sol";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
TD10ReportBody,
|
|
11
|
-
MINIMUM_QUOTE_LENGTH
|
|
12
|
-
} from "../interfaces/automata-interfaces/Types.sol";
|
|
8
|
+
import {Td10ReportBody, MINIMUM_QUOTE_LENGTH} from "../interfaces/automata-interfaces/Types.sol";
|
|
13
9
|
|
|
14
10
|
contract TakesEInput is IncoTest {
|
|
11
|
+
|
|
15
12
|
using e for bytes;
|
|
16
13
|
using e for euint256;
|
|
17
14
|
|
|
@@ -27,10 +24,12 @@ contract TakesEInput is IncoTest {
|
|
|
27
24
|
function setB(bytes memory boolEInput) external {
|
|
28
25
|
b = boolEInput.newEbool(msg.sender);
|
|
29
26
|
}
|
|
27
|
+
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
// its meta: this is testing correct behavior of our testing infrastructure
|
|
33
|
-
contract TestFakeInfra is IncoTest
|
|
31
|
+
contract TestFakeInfra is IncoTest {
|
|
32
|
+
|
|
34
33
|
using e for euint256;
|
|
35
34
|
using e for ebool;
|
|
36
35
|
using e for uint256;
|
|
@@ -153,10 +152,7 @@ contract TestFakeInfra is IncoTest, MockRemoteAttestation {
|
|
|
153
152
|
euint256 b = e.asEuint256(4);
|
|
154
153
|
euint256 c = a.rotr(b);
|
|
155
154
|
processAllOperations();
|
|
156
|
-
assertEq(
|
|
157
|
-
getUint256Value(c),
|
|
158
|
-
72370055773322622139731865630429942408293740416025352524660990004945706024960
|
|
159
|
-
);
|
|
155
|
+
assertEq(getUint256Value(c), 72370055773322622139731865630429942408293740416025352524660990004945706024960);
|
|
160
156
|
}
|
|
161
157
|
|
|
162
158
|
function testEEq() public {
|
|
@@ -272,17 +268,9 @@ contract TestFakeInfra is IncoTest, MockRemoteAttestation {
|
|
|
272
268
|
TakesEInput inputContract = new TakesEInput();
|
|
273
269
|
vm.deal(address(inputContract), 1 ether);
|
|
274
270
|
address self = address(this);
|
|
275
|
-
bytes memory ciphertext = fakePrepareEuint256Ciphertext(
|
|
276
|
-
12,
|
|
277
|
-
self,
|
|
278
|
-
address(inputContract)
|
|
279
|
-
);
|
|
271
|
+
bytes memory ciphertext = fakePrepareEuint256Ciphertext(12, self, address(inputContract));
|
|
280
272
|
inputContract.setA(ciphertext);
|
|
281
|
-
inputContract.setB(
|
|
282
|
-
fakePrepareEboolCiphertext(true,
|
|
283
|
-
self,
|
|
284
|
-
address(inputContract)
|
|
285
|
-
));
|
|
273
|
+
inputContract.setB(fakePrepareEboolCiphertext(true, self, address(inputContract)));
|
|
286
274
|
processAllOperations();
|
|
287
275
|
assertEq(getUint256Value(inputContract.a()), 12);
|
|
288
276
|
assertEq(getBoolValue(inputContract.b()), true);
|
|
@@ -291,35 +279,24 @@ contract TestFakeInfra is IncoTest, MockRemoteAttestation {
|
|
|
291
279
|
function testUninitializedHandleIsDisallowed() public {
|
|
292
280
|
bytes32 randomHandle = keccak256("random handle");
|
|
293
281
|
euint256 a = e.asEuint256(12);
|
|
294
|
-
vm.expectRevert(
|
|
295
|
-
abi.encodeWithSelector(
|
|
296
|
-
SenderNotAllowedForHandle.selector,
|
|
297
|
-
randomHandle,
|
|
298
|
-
address(this)
|
|
299
|
-
)
|
|
300
|
-
);
|
|
282
|
+
vm.expectRevert(abi.encodeWithSelector(SenderNotAllowedForHandle.selector, randomHandle, address(this)));
|
|
301
283
|
a.add(euint256.wrap(randomHandle));
|
|
302
284
|
}
|
|
303
285
|
|
|
304
286
|
function testCreateQuote() public view {
|
|
305
|
-
bytes
|
|
306
|
-
|
|
287
|
+
bytes memory mrtd =
|
|
288
|
+
hex"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
|
|
307
289
|
address signer = address(0x1234567890123456789012345678901234567890);
|
|
308
290
|
bytes memory quote = createQuote(mrtd, signer);
|
|
309
291
|
TEELifecycle lifecycle = TEELifecycle(address(inco.incoVerifier()));
|
|
310
|
-
|
|
311
|
-
(address reportDataSigner, bytes32 reportMrAggregated) = lifecycle
|
|
312
|
-
.parseReport(tdReport);
|
|
292
|
+
Td10ReportBody memory tdReport = lifecycle.parseTd10ReportBody(quote);
|
|
293
|
+
(address reportDataSigner, bytes32 reportMrAggregated) = lifecycle.parseReport(tdReport);
|
|
313
294
|
assertEq(reportDataSigner, signer);
|
|
314
295
|
assertEq(
|
|
315
296
|
reportMrAggregated,
|
|
316
|
-
lifecycle.computeMrAggregated(
|
|
317
|
-
tdReport.mrTd,
|
|
318
|
-
tdReport.rtMr0,
|
|
319
|
-
tdReport.rtMr1,
|
|
320
|
-
tdReport.rtMr2
|
|
321
|
-
)
|
|
297
|
+
lifecycle.computeMrAggregated(tdReport.mrTd, tdReport.rtMr0, tdReport.rtMr1, tdReport.rtMr2)
|
|
322
298
|
);
|
|
323
299
|
assertEq(quote.length, MINIMUM_QUOTE_LENGTH);
|
|
324
300
|
}
|
|
301
|
+
|
|
325
302
|
}
|
|
@@ -12,48 +12,34 @@ import {IncoLightning} from "../IncoLightning.sol";
|
|
|
12
12
|
import {IVersion} from "../version/interfaces/IVersion.sol";
|
|
13
13
|
import {Version} from "../version/Version.sol";
|
|
14
14
|
import {IIncoVerifier} from "../interfaces/IIncoVerifier.sol";
|
|
15
|
-
import {
|
|
16
|
-
MAJOR_VERSION,
|
|
17
|
-
MINOR_VERSION,
|
|
18
|
-
PATCH_VERSION
|
|
19
|
-
} from "../version/IncoLightningConfig.sol";
|
|
15
|
+
import {MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION} from "../version/IncoLightningConfig.sol";
|
|
20
16
|
|
|
21
17
|
interface IUUPS {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
) external payable;
|
|
18
|
+
|
|
19
|
+
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;
|
|
20
|
+
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
contract IncoLightningV2 is IncoLightning {
|
|
24
|
+
|
|
29
25
|
uint8 constant MAJOR_VERSION_MOCK = 255;
|
|
30
26
|
uint8 constant MINOR_VERSION_MOCK = 255;
|
|
31
27
|
uint8 constant PATCH_VERSION_MOCK = 255;
|
|
32
28
|
|
|
33
29
|
constructor(bytes32 salt) IncoLightning(salt, IIncoVerifier(address(0))) {}
|
|
34
30
|
|
|
35
|
-
function getVersion()
|
|
36
|
-
|
|
37
|
-
view
|
|
38
|
-
virtual
|
|
39
|
-
override(IVersion, Version)
|
|
40
|
-
returns (string memory)
|
|
41
|
-
{
|
|
42
|
-
return
|
|
43
|
-
versionString(
|
|
44
|
-
MAJOR_VERSION_MOCK,
|
|
45
|
-
MINOR_VERSION_MOCK,
|
|
46
|
-
PATCH_VERSION_MOCK
|
|
47
|
-
);
|
|
31
|
+
function getVersion() public view virtual override(IVersion, Version) returns (string memory) {
|
|
32
|
+
return versionString(MAJOR_VERSION_MOCK, MINOR_VERSION_MOCK, PATCH_VERSION_MOCK);
|
|
48
33
|
}
|
|
34
|
+
|
|
49
35
|
}
|
|
50
36
|
|
|
51
37
|
contract TestUpgrade is IncoTest {
|
|
38
|
+
|
|
52
39
|
using Strings for uint256;
|
|
53
40
|
|
|
54
41
|
// EIP-1967 implementation slot
|
|
55
|
-
bytes32 private constant IMPLEMENTATION_SLOT =
|
|
56
|
-
0x360894A13BA1A3210667C828492DB98DCA3E2076CC3735A920A3CA505D382BBC;
|
|
42
|
+
bytes32 private constant IMPLEMENTATION_SLOT = 0x360894A13BA1A3210667C828492DB98DCA3E2076CC3735A920A3CA505D382BBC;
|
|
57
43
|
|
|
58
44
|
address private incoProxyAddr;
|
|
59
45
|
IncoLightning private v1Impl;
|
|
@@ -84,20 +70,13 @@ contract TestUpgrade is IncoTest {
|
|
|
84
70
|
0,
|
|
85
71
|
payable(address(0))
|
|
86
72
|
);
|
|
87
|
-
safe = Safe(
|
|
88
|
-
payable(factory.createProxyWithNonce(address(master), setupData, 0))
|
|
89
|
-
);
|
|
73
|
+
safe = Safe(payable(factory.createProxyWithNonce(address(master), setupData, 0)));
|
|
90
74
|
|
|
91
75
|
vm.prank(owner);
|
|
92
76
|
inco.transferOwnership(address(safe));
|
|
93
77
|
|
|
94
78
|
// Deploy V2
|
|
95
|
-
bytes32 salt = getSalt(
|
|
96
|
-
"IncoLightningV2",
|
|
97
|
-
255,
|
|
98
|
-
testDeployer,
|
|
99
|
-
"testnet"
|
|
100
|
-
);
|
|
79
|
+
bytes32 salt = getSalt("IncoLightningV2", 255, testDeployer, "testnet");
|
|
101
80
|
v2Impl = new IncoLightningV2(salt);
|
|
102
81
|
}
|
|
103
82
|
|
|
@@ -114,11 +93,7 @@ contract TestUpgrade is IncoTest {
|
|
|
114
93
|
)
|
|
115
94
|
);
|
|
116
95
|
// data to sign
|
|
117
|
-
bytes memory data = abi.encodeWithSelector(
|
|
118
|
-
IUUPS.upgradeToAndCall.selector,
|
|
119
|
-
address(v2Impl),
|
|
120
|
-
""
|
|
121
|
-
);
|
|
96
|
+
bytes memory data = abi.encodeWithSelector(IUUPS.upgradeToAndCall.selector, address(v2Impl), "");
|
|
122
97
|
// prepare txhash
|
|
123
98
|
bytes32 txHash = _txHash(safe, incoProxyAddr, 0, data);
|
|
124
99
|
// sign txHash
|
|
@@ -129,9 +104,7 @@ contract TestUpgrade is IncoTest {
|
|
|
129
104
|
// execute tx with sorted signatures
|
|
130
105
|
_execSafe(safe, incoProxyAddr, 0, data, signatures);
|
|
131
106
|
|
|
132
|
-
address implAfter = address(
|
|
133
|
-
uint160(uint256(vm.load(incoProxyAddr, IMPLEMENTATION_SLOT)))
|
|
134
|
-
);
|
|
107
|
+
address implAfter = address(uint160(uint256(vm.load(incoProxyAddr, IMPLEMENTATION_SLOT))));
|
|
135
108
|
assertEq(implAfter, address(v2Impl));
|
|
136
109
|
|
|
137
110
|
string memory versionAfter = inco.getVersion();
|
|
@@ -139,11 +112,7 @@ contract TestUpgrade is IncoTest {
|
|
|
139
112
|
}
|
|
140
113
|
|
|
141
114
|
function test_SafeSingleSignature_Fails() public {
|
|
142
|
-
bytes memory data = abi.encodeWithSelector(
|
|
143
|
-
IUUPS.upgradeToAndCall.selector,
|
|
144
|
-
address(v2Impl),
|
|
145
|
-
""
|
|
146
|
-
);
|
|
115
|
+
bytes memory data = abi.encodeWithSelector(IUUPS.upgradeToAndCall.selector, address(v2Impl), "");
|
|
147
116
|
bytes32 txHash = _txHash(safe, incoProxyAddr, 0, data);
|
|
148
117
|
bytes memory sigA = _sign(alicePrivKey, txHash);
|
|
149
118
|
vm.expectRevert();
|
|
@@ -151,11 +120,7 @@ contract TestUpgrade is IncoTest {
|
|
|
151
120
|
}
|
|
152
121
|
|
|
153
122
|
function test_Safe_UnsortedSignatures_Fails() public {
|
|
154
|
-
bytes memory data = abi.encodeWithSelector(
|
|
155
|
-
IUUPS.upgradeToAndCall.selector,
|
|
156
|
-
address(v2Impl),
|
|
157
|
-
""
|
|
158
|
-
);
|
|
123
|
+
bytes memory data = abi.encodeWithSelector(IUUPS.upgradeToAndCall.selector, address(v2Impl), "");
|
|
159
124
|
bytes32 txHash = _txHash(safe, incoProxyAddr, 0, data);
|
|
160
125
|
bytes memory sigA = _sign(alicePrivKey, txHash);
|
|
161
126
|
bytes memory sigC = _sign(carolPrivKey, txHash);
|
|
@@ -165,30 +130,17 @@ contract TestUpgrade is IncoTest {
|
|
|
165
130
|
}
|
|
166
131
|
|
|
167
132
|
function test_Safe_WrongSigner_Fails() public {
|
|
168
|
-
bytes memory data = abi.encodeWithSelector(
|
|
169
|
-
IUUPS.upgradeToAndCall.selector,
|
|
170
|
-
address(v2Impl),
|
|
171
|
-
""
|
|
172
|
-
);
|
|
133
|
+
bytes memory data = abi.encodeWithSelector(IUUPS.upgradeToAndCall.selector, address(v2Impl), "");
|
|
173
134
|
bytes32 txHash = _txHash(safe, incoProxyAddr, 0, data);
|
|
174
135
|
bytes memory sigOwner = _sign(alicePrivKey, txHash);
|
|
175
136
|
bytes memory sigAttacker = _sign(davePrivKey, txHash);
|
|
176
|
-
bytes memory signatures = _packSortedTwo(
|
|
177
|
-
sigOwner,
|
|
178
|
-
alice,
|
|
179
|
-
sigAttacker,
|
|
180
|
-
dave
|
|
181
|
-
); // dave not an owner
|
|
137
|
+
bytes memory signatures = _packSortedTwo(sigOwner, alice, sigAttacker, dave); // dave not an owner
|
|
182
138
|
vm.expectRevert();
|
|
183
139
|
_execSafe(safe, incoProxyAddr, 0, data, signatures);
|
|
184
140
|
}
|
|
185
141
|
|
|
186
142
|
function test_Safe_ReplayNonce_Fails() public {
|
|
187
|
-
bytes memory data = abi.encodeWithSelector(
|
|
188
|
-
IUUPS.upgradeToAndCall.selector,
|
|
189
|
-
address(v2Impl),
|
|
190
|
-
""
|
|
191
|
-
);
|
|
143
|
+
bytes memory data = abi.encodeWithSelector(IUUPS.upgradeToAndCall.selector, address(v2Impl), "");
|
|
192
144
|
bytes32 txHash = _txHash(safe, incoProxyAddr, 0, data);
|
|
193
145
|
bytes memory sigA = _sign(alicePrivKey, txHash);
|
|
194
146
|
bytes memory sigB = _sign(bobPrivKey, txHash);
|
|
@@ -204,21 +156,11 @@ contract TestUpgrade is IncoTest {
|
|
|
204
156
|
|
|
205
157
|
function test_Safe_UpdateSigners_SwapOwner_ThenUpgrade() public {
|
|
206
158
|
// swap bob -> eve (prevOwner = alice since owners were [alice, bob, carol])
|
|
207
|
-
bytes memory change = abi.encodeWithSelector(
|
|
208
|
-
IOwnerManager.swapOwner.selector,
|
|
209
|
-
alice,
|
|
210
|
-
bob,
|
|
211
|
-
eve
|
|
212
|
-
);
|
|
159
|
+
bytes memory change = abi.encodeWithSelector(IOwnerManager.swapOwner.selector, alice, bob, eve);
|
|
213
160
|
bytes32 changeHash = _txHash(safe, address(safe), 0, change);
|
|
214
161
|
bytes memory changeSigA = _sign(alicePrivKey, changeHash);
|
|
215
162
|
bytes memory changeSigC = _sign(carolPrivKey, changeHash);
|
|
216
|
-
bytes memory changeSigs = _packSortedTwo(
|
|
217
|
-
changeSigA,
|
|
218
|
-
alice,
|
|
219
|
-
changeSigC,
|
|
220
|
-
carol
|
|
221
|
-
);
|
|
163
|
+
bytes memory changeSigs = _packSortedTwo(changeSigA, alice, changeSigC, carol);
|
|
222
164
|
_execSafe(safe, address(safe), 0, change, changeSigs);
|
|
223
165
|
|
|
224
166
|
// assertions on owners/threshold
|
|
@@ -227,11 +169,7 @@ contract TestUpgrade is IncoTest {
|
|
|
227
169
|
assertEq(safe.getThreshold(), 2, "threshold changed unexpectedly");
|
|
228
170
|
|
|
229
171
|
// Attempt upgrade signed by removed owner should fail
|
|
230
|
-
bytes memory upg = abi.encodeWithSelector(
|
|
231
|
-
IUUPS.upgradeToAndCall.selector,
|
|
232
|
-
address(v2Impl),
|
|
233
|
-
""
|
|
234
|
-
);
|
|
172
|
+
bytes memory upg = abi.encodeWithSelector(IUUPS.upgradeToAndCall.selector, address(v2Impl), "");
|
|
235
173
|
bytes32 upgHash = _txHash(safe, incoProxyAddr, 0, upg);
|
|
236
174
|
bytes memory badSigA = _sign(alicePrivKey, upgHash);
|
|
237
175
|
bytes memory badSigB = _sign(bobPrivKey, upgHash); // removed owner
|
|
@@ -245,9 +183,7 @@ contract TestUpgrade is IncoTest {
|
|
|
245
183
|
bytes memory goodSigs = _packSortedTwo(goodSigA, alice, goodSigE, eve);
|
|
246
184
|
_execSafe(safe, incoProxyAddr, 0, upg, goodSigs);
|
|
247
185
|
|
|
248
|
-
address implAfter = address(
|
|
249
|
-
uint160(uint256(vm.load(incoProxyAddr, IMPLEMENTATION_SLOT)))
|
|
250
|
-
);
|
|
186
|
+
address implAfter = address(uint160(uint256(vm.load(incoProxyAddr, IMPLEMENTATION_SLOT))));
|
|
251
187
|
assertEq(implAfter, address(v2Impl));
|
|
252
188
|
|
|
253
189
|
string memory versionAfter = inco.getVersion();
|
|
@@ -261,61 +197,30 @@ contract TestUpgrade is IncoTest {
|
|
|
261
197
|
}
|
|
262
198
|
|
|
263
199
|
// Helpers
|
|
264
|
-
function _txHash(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
bytes memory data
|
|
269
|
-
) internal view returns (bytes32) {
|
|
270
|
-
return
|
|
271
|
-
_safe.getTransactionHash(
|
|
272
|
-
to,
|
|
273
|
-
value,
|
|
274
|
-
data,
|
|
275
|
-
Enum.Operation.Call,
|
|
276
|
-
0,
|
|
277
|
-
0,
|
|
278
|
-
0,
|
|
279
|
-
address(0),
|
|
280
|
-
payable(address(0)),
|
|
281
|
-
_safe.nonce()
|
|
282
|
-
);
|
|
200
|
+
function _txHash(Safe _safe, address to, uint256 value, bytes memory data) internal view returns (bytes32) {
|
|
201
|
+
return _safe.getTransactionHash(
|
|
202
|
+
to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), payable(address(0)), _safe.nonce()
|
|
203
|
+
);
|
|
283
204
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
bytes32 txHash
|
|
287
|
-
) internal view returns (bytes memory) {
|
|
205
|
+
|
|
206
|
+
function _sign(uint256 pk, bytes32 txHash) internal pure returns (bytes memory) {
|
|
288
207
|
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, txHash);
|
|
289
208
|
if (v < 27) v += 27;
|
|
290
209
|
return abi.encodePacked(r, s, v);
|
|
291
210
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return
|
|
299
|
-
addrA < addrB ? bytes.concat(sigA, sigB) : bytes.concat(sigB, sigA);
|
|
211
|
+
|
|
212
|
+
function _packSortedTwo(bytes memory sigA, address addrA, bytes memory sigB, address addrB)
|
|
213
|
+
internal
|
|
214
|
+
pure
|
|
215
|
+
returns (bytes memory)
|
|
216
|
+
{
|
|
217
|
+
return addrA < addrB ? bytes.concat(sigA, sigB) : bytes.concat(sigB, sigA);
|
|
300
218
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
address to,
|
|
304
|
-
uint256 value,
|
|
305
|
-
bytes memory data,
|
|
306
|
-
bytes memory signatures
|
|
307
|
-
) internal {
|
|
219
|
+
|
|
220
|
+
function _execSafe(Safe _safe, address to, uint256 value, bytes memory data, bytes memory signatures) internal {
|
|
308
221
|
_safe.execTransaction(
|
|
309
|
-
to,
|
|
310
|
-
value,
|
|
311
|
-
data,
|
|
312
|
-
Enum.Operation.Call,
|
|
313
|
-
0,
|
|
314
|
-
0,
|
|
315
|
-
0,
|
|
316
|
-
address(0),
|
|
317
|
-
payable(address(0)),
|
|
318
|
-
signatures
|
|
222
|
+
to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), payable(address(0)), signatures
|
|
319
223
|
);
|
|
320
224
|
}
|
|
225
|
+
|
|
321
226
|
}
|
|
@@ -5,10 +5,13 @@ import {Test} from "forge-std/Test.sol";
|
|
|
5
5
|
import {Version} from "../version/Version.sol";
|
|
6
6
|
|
|
7
7
|
contract SomeContract is Version {
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
constructor() Version(1, 2, 3, bytes32(uint256(12345678)), "SomeContract") {}
|
|
10
|
+
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
contract TestVersion is Test {
|
|
14
|
+
|
|
12
15
|
SomeContract someContract;
|
|
13
16
|
|
|
14
17
|
function setUp() public {
|
|
@@ -21,9 +24,7 @@ contract TestVersion is Test {
|
|
|
21
24
|
assertEq(someContract.patchVersion(), 3);
|
|
22
25
|
assertEq(someContract.getName(), "SomeContract");
|
|
23
26
|
assertEq(someContract.getVersion(), "1_2_3");
|
|
24
|
-
assertEq(
|
|
25
|
-
someContract.getVersionedName(),
|
|
26
|
-
"SomeContract_1_2_3__12345678"
|
|
27
|
-
);
|
|
27
|
+
assertEq(someContract.getVersionedName(), "SomeContract_1_2_3__12345678");
|
|
28
28
|
}
|
|
29
|
+
|
|
29
30
|
}
|
|
@@ -13,6 +13,6 @@ uint8 constant MINOR_VERSION = 0;
|
|
|
13
13
|
// otherwise make test_upgrade will fail
|
|
14
14
|
// consequently, when we do a patch release, we don't need to pump it as it's already pumped
|
|
15
15
|
// when the previous release was done
|
|
16
|
-
uint8 constant PATCH_VERSION =
|
|
16
|
+
uint8 constant PATCH_VERSION = 4;
|
|
17
17
|
|
|
18
18
|
string constant VERIFIER_NAME = "incoVerifier";
|
package/src/version/Version.sol
CHANGED
|
@@ -2,77 +2,74 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
|
5
|
-
import {
|
|
6
|
-
ShortStrings,
|
|
7
|
-
ShortString
|
|
8
|
-
} from "@openzeppelin/contracts/utils/ShortStrings.sol";
|
|
5
|
+
import {ShortStrings, ShortString} from "@openzeppelin/contracts/utils/ShortStrings.sol";
|
|
9
6
|
import {IVersion} from "./interfaces/IVersion.sol";
|
|
10
7
|
|
|
11
8
|
contract Version is IVersion {
|
|
9
|
+
|
|
12
10
|
using ShortStrings for ShortString;
|
|
13
11
|
using ShortStrings for string;
|
|
14
12
|
|
|
15
|
-
uint8
|
|
16
|
-
uint8
|
|
17
|
-
uint8
|
|
18
|
-
bytes32
|
|
19
|
-
ShortString internal immutable
|
|
13
|
+
uint8 internal immutable VERSION_MAJOR;
|
|
14
|
+
uint8 internal immutable VERSION_MINOR;
|
|
15
|
+
uint8 internal immutable VERSION_PATCH;
|
|
16
|
+
bytes32 internal immutable SALT;
|
|
17
|
+
ShortString internal immutable NAME;
|
|
20
18
|
|
|
21
|
-
constructor(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
) {
|
|
28
|
-
majorVersion = _majorVersion;
|
|
29
|
-
minorVersion = _minorVersion;
|
|
30
|
-
patchVersion = _patchVersion;
|
|
31
|
-
salt = _salt;
|
|
32
|
-
name = _name.toShortString();
|
|
19
|
+
constructor(uint8 _majorVersion, uint8 _minorVersion, uint8 _patchVersion, bytes32 _salt, string memory _name) {
|
|
20
|
+
VERSION_MAJOR = _majorVersion;
|
|
21
|
+
VERSION_MINOR = _minorVersion;
|
|
22
|
+
VERSION_PATCH = _patchVersion;
|
|
23
|
+
SALT = _salt;
|
|
24
|
+
NAME = _name.toShortString();
|
|
33
25
|
}
|
|
34
26
|
|
|
35
27
|
function getVersionedName() public view virtual returns (string memory) {
|
|
36
|
-
uint256 shortSalt = uint256(
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
28
|
+
uint256 shortSalt = uint256(SALT) % 10e8;
|
|
29
|
+
return string(
|
|
30
|
+
abi.encodePacked(
|
|
31
|
+
getName(),
|
|
32
|
+
"_",
|
|
33
|
+
getVersion(),
|
|
34
|
+
"__",
|
|
35
|
+
// avoids name collision for deployments of the same version
|
|
36
|
+
Strings.toString(shortSalt)
|
|
37
|
+
)
|
|
38
|
+
);
|
|
48
39
|
}
|
|
49
40
|
|
|
50
41
|
function getVersion() public view virtual returns (string memory) {
|
|
51
|
-
return versionString(
|
|
42
|
+
return versionString(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
|
|
52
43
|
}
|
|
53
44
|
|
|
54
|
-
function versionString(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
) internal pure returns (string memory) {
|
|
59
|
-
return
|
|
60
|
-
string(
|
|
61
|
-
abi.encodePacked(
|
|
62
|
-
Strings.toString(major),
|
|
63
|
-
"_",
|
|
64
|
-
Strings.toString(minor),
|
|
65
|
-
"_",
|
|
66
|
-
Strings.toString(patch)
|
|
67
|
-
)
|
|
68
|
-
);
|
|
45
|
+
function versionString(uint8 major, uint8 minor, uint8 patch) internal pure returns (string memory) {
|
|
46
|
+
return string(
|
|
47
|
+
abi.encodePacked(Strings.toString(major), "_", Strings.toString(minor), "_", Strings.toString(patch))
|
|
48
|
+
);
|
|
69
49
|
}
|
|
70
50
|
|
|
71
51
|
function getName() public view virtual returns (string memory) {
|
|
72
|
-
return
|
|
52
|
+
return NAME.toString();
|
|
73
53
|
}
|
|
74
54
|
|
|
75
55
|
function getMajorVersion() public view virtual returns (string memory) {
|
|
76
|
-
return Strings.toString(
|
|
56
|
+
return Strings.toString(VERSION_MAJOR);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function majorVersion() public view returns (uint8) {
|
|
60
|
+
return VERSION_MAJOR;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function minorVersion() public view returns (uint8) {
|
|
64
|
+
return VERSION_MINOR;
|
|
77
65
|
}
|
|
66
|
+
|
|
67
|
+
function patchVersion() public view returns (uint8) {
|
|
68
|
+
return VERSION_PATCH;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function salt() public view returns (bytes32) {
|
|
72
|
+
return SALT;
|
|
73
|
+
}
|
|
74
|
+
|
|
78
75
|
}
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
pragma solidity ^0.8;
|
|
3
3
|
|
|
4
4
|
interface IVersion {
|
|
5
|
+
|
|
5
6
|
function getVersionedName() external view returns (string memory);
|
|
6
7
|
function getVersion() external view returns (string memory);
|
|
7
8
|
function getName() external view returns (string memory);
|
|
8
9
|
function getMajorVersion() external view returns (string memory);
|
|
10
|
+
function majorVersion() external view returns (uint8);
|
|
11
|
+
function minorVersion() external view returns (uint8);
|
|
12
|
+
function patchVersion() external view returns (uint8);
|
|
13
|
+
function salt() external view returns (bytes32);
|
|
14
|
+
|
|
9
15
|
}
|