@cofhe/mock-contracts 1.0.0-alpha.0 → 1.0.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/CHANGELOG.md +37 -0
- package/contracts/MockTaskManager.sol +55 -56
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/MockTaskManager.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @cofhe/mock-contracts Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6dcfb7d: ACPs sharing SNAPSHOTs (ctHashes rather than live data) can use the new on-chain ACP Sharing Registry `metadata` field to cite the origin of the snapshotted data (contract address + view-function / event), and the recipient can verify it on-chain. [Docs](https://cofhesdk.fhenix.io/sdk/acp#labelling-a-snapshot-share)
|
|
8
|
+
|
|
9
|
+
**@cofhe/sdk**
|
|
10
|
+
|
|
11
|
+
- `createSharing({ labels })`, `shareOnChain(acp, { labels | metadata })`; labels travel in `export()` / `importShared` as `SharedACP.metadata`.
|
|
12
|
+
- New `client.acp.verifyShareLabels`, `client.acp.getShareFromChain`, and `describeShareMetadata`. `IncomingShare` gains `metadata` and `appKey`.
|
|
13
|
+
- New `acp.app` config option: shares are tagged with the app's key and `getIncomingShares` lists only that app's shares ([docs](https://cofhesdk.fhenix.io/sdk/acp#mark-shares-for-your-app)).
|
|
14
|
+
- `@cofhe/sdk/acps` exports the metadata codec, label builders (`viewFunctionLabel`, `eventLogLabel`, `UNLABELLED`), verifiers, registry readers, `shareAppKey` and `ERC7984_ABI`.
|
|
15
|
+
|
|
16
|
+
**@cofhe/react**
|
|
17
|
+
|
|
18
|
+
- New `useCofheShareLabels`. `useCofheShareOnChain` accepts `{ acp, labels | metadata }`.
|
|
19
|
+
- The inbox shows each share's labels and their verification. [Docs](https://cofhesdk.fhenix.io/react/acp#share-labels)
|
|
20
|
+
|
|
21
|
+
**Mocks and plugins**
|
|
22
|
+
|
|
23
|
+
- `ACPShareRegistry`, `ACPTimestampRevoker` and `Permissioned` are copied verbatim from a pinned cofhe-contracts commit (`pnpm update:cofhe-contracts <commit>`). The share registry is deployed behind `MockERC1967Proxy`.
|
|
24
|
+
- Mocks now need Solidity ≥0.8.25 and `@openzeppelin/contracts-upgradeable` (new Hardhat plugin peer dependency; Foundry users add its remapping).
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- d711ce2: The mocks now behave like the real TaskManager and TFHE-rs in more places. Tests that relied on the old mock behaviour may start failing, as they would on a real network.
|
|
29
|
+
|
|
30
|
+
- `FHE.asE*` (trivial encrypt) reverts with `InvalidInputForFunction` when the value does not fit the type (e.g. `FHE.asEuint8(256)`), and with `InvalidSecurityZone` for an out of range zone, instead of storing the value masked.
|
|
31
|
+
- `encryptInputs` against the mocks rejects out-of-range values with the same error as the production path, instead of passing them on to be masked (e.g. `Encryptable.uint8(256n)` became `0`).
|
|
32
|
+
- `FHE.not` on encrypted integers is a bitwise NOT (`not(euint8(2))` is 253, not 0), and `FHE.rol` / `FHE.ror` rotate within the type's width, with the amount taken modulo the width, instead of shifting.
|
|
33
|
+
- `FHE.rem(x, 0)` returns `x` instead of reverting.
|
|
34
|
+
- `FHE.random*` handles carry their type and security zone and can be allowed and computed on.
|
|
35
|
+
- `MockTaskManager.isPubliclyAllowed` returns whether a handle was made public with `FHE.allowGlobal` / `FHE.allowPublic`, instead of reverting with `NotImplemented`.
|
|
36
|
+
- Handles in a negative security zone go through the ACL like any other handle. Previously any contract could use them and `FHE.allow*` did nothing.
|
|
37
|
+
- `publishDecryptResultBatch` emits `DecryptionResult` with the caller as `requestor`, and the batch decrypt result functions revert with `LengthMismatch` when the arrays differ in length.
|
|
38
|
+
- `setSecurityZones` rejects an inverted range (`min > max`) with `InvalidSecurityZone`.
|
|
39
|
+
|
|
3
40
|
## 0.8.0
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
|
@@ -16,6 +16,7 @@ error InvalidInputsAmount(string operation, uint256 got, uint256 expected);
|
|
|
16
16
|
error InvalidOperationInputs(string operation);
|
|
17
17
|
error TooManyInputs(string operation, uint256 got, uint256 maxAllowed);
|
|
18
18
|
error InvalidBytesLength(uint256 got, uint256 expected);
|
|
19
|
+
error LengthMismatch();
|
|
19
20
|
// Type and security validation errors
|
|
20
21
|
error InvalidTypeOrSecurityZone(string operation);
|
|
21
22
|
error InvalidInputType(uint8 actual, uint8 expected);
|
|
@@ -158,10 +159,6 @@ library TMCommon {
|
|
|
158
159
|
return uint256((SHIFTED_TYPE_MASK | SECURITY_ZONE_MASK) & hash);
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
function isTriviallyEncryptedFromHash(uint256 hash) internal pure returns (bool) {
|
|
162
|
-
return (hash & TRIVIALLY_ENCRYPTED_MASK) == TRIVIALLY_ENCRYPTED_MASK;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
162
|
function computeDecryptResultHash(
|
|
166
163
|
uint256 ctHash,
|
|
167
164
|
uint256 result,
|
|
@@ -210,8 +207,17 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
210
207
|
}
|
|
211
208
|
|
|
212
209
|
function setSecurityZones(int32 minSZ, int32 maxSZ) external onlyOwner {
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
_setSecurityZones(minSZ, maxSZ);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/// @dev Same check as the real task manager's `_setSecurityZones`, the one write path for the bounds.
|
|
214
|
+
/// Without it `setSecurityZones(2, 1)` would be stored here while the real task manager reverts.
|
|
215
|
+
function _setSecurityZones(int32 newMin, int32 newMax) private {
|
|
216
|
+
if (newMin > newMax) {
|
|
217
|
+
revert InvalidSecurityZone(newMin, newMin, newMax);
|
|
218
|
+
}
|
|
219
|
+
securityZoneMin = newMin;
|
|
220
|
+
securityZoneMax = newMax;
|
|
215
221
|
}
|
|
216
222
|
|
|
217
223
|
function isInitialized() public view returns (bool) {
|
|
@@ -372,9 +378,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
372
378
|
}
|
|
373
379
|
|
|
374
380
|
function checkAllowed(uint256 ctHash) internal view {
|
|
375
|
-
if (!
|
|
376
|
-
if (!acl.isAllowed(ctHash, msg.sender)) revert ACLNotAllowed(ctHash, msg.sender);
|
|
377
|
-
}
|
|
381
|
+
if (!acl.isAllowed(ctHash, msg.sender)) revert ACLNotAllowed(ctHash, msg.sender);
|
|
378
382
|
}
|
|
379
383
|
|
|
380
384
|
function isUnaryOperation(FunctionId funcId) internal pure returns (bool) {
|
|
@@ -575,12 +579,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
575
579
|
/// @notice Publish a signed decrypt result to the chain
|
|
576
580
|
/// @dev Anyone with a valid signature from the decrypt network can call this
|
|
577
581
|
function publishDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) external {
|
|
578
|
-
|
|
579
|
-
_decryptResultReady[ctHash] = true;
|
|
580
|
-
_decryptResult[ctHash] = result;
|
|
581
|
-
|
|
582
|
-
_decryptResultReadyTimestamp[ctHash] = uint64(block.timestamp);
|
|
583
|
-
emit DecryptionResult(ctHash, result, msg.sender);
|
|
582
|
+
_publishDecryptResult(ctHash, result, signature);
|
|
584
583
|
}
|
|
585
584
|
|
|
586
585
|
function publishDecryptResultBatch(
|
|
@@ -588,14 +587,25 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
588
587
|
uint256[] calldata results,
|
|
589
588
|
bytes[] calldata signatures
|
|
590
589
|
) external {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
590
|
+
uint256 length = ctHashes.length;
|
|
591
|
+
if (results.length != length || signatures.length != length) revert LengthMismatch();
|
|
592
|
+
|
|
593
|
+
for (uint256 i = 0; i < length; i++) {
|
|
594
|
+
_publishDecryptResult(ctHashes[i], results[i], signatures[i]);
|
|
596
595
|
}
|
|
597
596
|
}
|
|
598
597
|
|
|
598
|
+
/// @dev Shared by both publish functions, so a batch keeps its caller as the `DecryptionResult` requestor,
|
|
599
|
+
/// like the real task manager. An external self-call would make the requestor this contract.
|
|
600
|
+
function _publishDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) private {
|
|
601
|
+
_verifyDecryptResult(ctHash, result, signature, true);
|
|
602
|
+
_decryptResultReady[ctHash] = true;
|
|
603
|
+
_decryptResult[ctHash] = result;
|
|
604
|
+
|
|
605
|
+
_decryptResultReadyTimestamp[ctHash] = uint64(block.timestamp);
|
|
606
|
+
emit DecryptionResult(ctHash, result, msg.sender);
|
|
607
|
+
}
|
|
608
|
+
|
|
599
609
|
function verifyDecryptResult(uint256 ctHash, uint256 result, bytes calldata signature) external view returns (bool) {
|
|
600
610
|
return _verifyDecryptResult(ctHash, result, signature, true);
|
|
601
611
|
}
|
|
@@ -688,47 +698,36 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
688
698
|
}
|
|
689
699
|
|
|
690
700
|
function allow(uint256 ctHash, address account) external {
|
|
691
|
-
|
|
692
|
-
acl.allow(ctHash, account, msg.sender);
|
|
701
|
+
acl.allow(ctHash, account, msg.sender);
|
|
693
702
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
}
|
|
703
|
+
// NOTE: MOCK
|
|
704
|
+
MOCK_trackedLogAllow(account == msg.sender ? 'FHE.allowThis' : 'FHE.allow', ctHash, account);
|
|
697
705
|
}
|
|
698
706
|
|
|
699
707
|
function allowGlobal(uint256 ctHash) external {
|
|
700
|
-
|
|
701
|
-
acl.allowGlobal(ctHash, msg.sender);
|
|
708
|
+
acl.allowGlobal(ctHash, msg.sender);
|
|
702
709
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
}
|
|
710
|
+
// NOTE: MOCK
|
|
711
|
+
MOCK_trackedLogAllow('FHE.allowGlobal', ctHash, msg.sender);
|
|
706
712
|
}
|
|
707
713
|
|
|
708
714
|
function allowTransient(uint256 ctHash, address account) external {
|
|
709
|
-
|
|
710
|
-
acl.allowTransient(ctHash, account, msg.sender);
|
|
715
|
+
acl.allowTransient(ctHash, account, msg.sender);
|
|
711
716
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
}
|
|
717
|
+
// NOTE: MOCK
|
|
718
|
+
MOCK_trackedLogAllow('FHE.allowTransient', ctHash, account);
|
|
715
719
|
}
|
|
716
720
|
|
|
717
721
|
function allowForDecryption(uint256 ctHash) external {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
acl.allowForDecryption(hashes, msg.sender);
|
|
722
|
+
uint256[] memory hashes = new uint256[](1);
|
|
723
|
+
hashes[0] = ctHash;
|
|
724
|
+
acl.allowForDecryption(hashes, msg.sender);
|
|
722
725
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
+
// NOTE: MOCK
|
|
727
|
+
MOCK_trackedLogAllow('FHE.allowForDecryption', ctHash, msg.sender);
|
|
726
728
|
}
|
|
727
729
|
|
|
728
730
|
function isAllowed(uint256 ctHash, address account) external view returns (bool) {
|
|
729
|
-
if (TMCommon.isTriviallyEncryptedFromHash(ctHash)) {
|
|
730
|
-
return true;
|
|
731
|
-
}
|
|
732
731
|
return acl.isAllowed(ctHash, account);
|
|
733
732
|
}
|
|
734
733
|
|
|
@@ -800,17 +799,11 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
800
799
|
}
|
|
801
800
|
|
|
802
801
|
function setSecurityZoneMax(int32 securityZone) external onlyOwner {
|
|
803
|
-
|
|
804
|
-
revert InvalidSecurityZone(securityZone, securityZoneMin, securityZoneMax);
|
|
805
|
-
}
|
|
806
|
-
securityZoneMax = securityZone;
|
|
802
|
+
_setSecurityZones(securityZoneMin, securityZone);
|
|
807
803
|
}
|
|
808
804
|
|
|
809
805
|
function setSecurityZoneMin(int32 securityZone) external onlyOwner {
|
|
810
|
-
|
|
811
|
-
revert InvalidSecurityZone(securityZone, securityZoneMin, securityZoneMax);
|
|
812
|
-
}
|
|
813
|
-
securityZoneMin = securityZone;
|
|
806
|
+
_setSecurityZones(securityZone, securityZoneMax);
|
|
814
807
|
}
|
|
815
808
|
|
|
816
809
|
function setACLContract(address _aclAddress) external onlyOwner {
|
|
@@ -891,7 +884,10 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
891
884
|
uint256[] calldata results,
|
|
892
885
|
bytes[] calldata signatures
|
|
893
886
|
) external view returns (bool) {
|
|
894
|
-
|
|
887
|
+
uint256 length = ctHashes.length;
|
|
888
|
+
if (results.length != length || signatures.length != length) revert LengthMismatch();
|
|
889
|
+
|
|
890
|
+
for (uint256 i = 0; i < length; i++) {
|
|
895
891
|
if (!_verifyDecryptResult(ctHashes[i], results[i], signatures[i], true)) {
|
|
896
892
|
return false;
|
|
897
893
|
}
|
|
@@ -904,8 +900,11 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
904
900
|
uint256[] calldata results,
|
|
905
901
|
bytes[] calldata signatures
|
|
906
902
|
) external view returns (bool[] memory) {
|
|
907
|
-
|
|
908
|
-
|
|
903
|
+
uint256 length = ctHashes.length;
|
|
904
|
+
if (results.length != length || signatures.length != length) revert LengthMismatch();
|
|
905
|
+
|
|
906
|
+
bool[] memory out = new bool[](length);
|
|
907
|
+
for (uint256 i = 0; i < length; i++) {
|
|
909
908
|
out[i] = _verifyDecryptResult(ctHashes[i], results[i], signatures[i], false);
|
|
910
909
|
}
|
|
911
910
|
return out;
|
package/dist/index.d.mts
CHANGED
|
@@ -1101,6 +1101,10 @@ declare const MockTaskManagerArtifact: {
|
|
|
1101
1101
|
readonly type: "string";
|
|
1102
1102
|
readonly internalType: "string";
|
|
1103
1103
|
}];
|
|
1104
|
+
}, {
|
|
1105
|
+
readonly type: "error";
|
|
1106
|
+
readonly name: "LengthMismatch";
|
|
1107
|
+
readonly inputs: readonly [];
|
|
1104
1108
|
}, {
|
|
1105
1109
|
readonly type: "error";
|
|
1106
1110
|
readonly name: "OnlyAggregatorAllowed";
|
package/dist/index.d.ts
CHANGED
|
@@ -1101,6 +1101,10 @@ declare const MockTaskManagerArtifact: {
|
|
|
1101
1101
|
readonly type: "string";
|
|
1102
1102
|
readonly internalType: "string";
|
|
1103
1103
|
}];
|
|
1104
|
+
}, {
|
|
1105
|
+
readonly type: "error";
|
|
1106
|
+
readonly name: "LengthMismatch";
|
|
1107
|
+
readonly inputs: readonly [];
|
|
1104
1108
|
}, {
|
|
1105
1109
|
readonly type: "error";
|
|
1106
1110
|
readonly name: "OnlyAggregatorAllowed";
|