@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 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
- securityZoneMin = minSZ;
214
- securityZoneMax = maxSZ;
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 (!TMCommon.isTriviallyEncryptedFromHash(ctHash)) {
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
- _verifyDecryptResult(ctHash, result, signature, true);
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
- // Mock implementation: process each result individually
592
- // Note: publishDecryptResult is defined later in the contract
593
- for (uint256 i = 0; i < ctHashes.length; i++) {
594
- // Call via external interface to avoid forward reference issue
595
- this.publishDecryptResult(ctHashes[i], results[i], signatures[i]);
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
- if (!TMCommon.isTriviallyEncryptedFromHash(ctHash)) {
692
- acl.allow(ctHash, account, msg.sender);
701
+ acl.allow(ctHash, account, msg.sender);
693
702
 
694
- // NOTE: MOCK
695
- MOCK_trackedLogAllow(account == msg.sender ? 'FHE.allowThis' : 'FHE.allow', ctHash, account);
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
- if (!TMCommon.isTriviallyEncryptedFromHash(ctHash)) {
701
- acl.allowGlobal(ctHash, msg.sender);
708
+ acl.allowGlobal(ctHash, msg.sender);
702
709
 
703
- // NOTE: MOCK
704
- MOCK_trackedLogAllow('FHE.allowGlobal', ctHash, msg.sender);
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
- if (!TMCommon.isTriviallyEncryptedFromHash(ctHash)) {
710
- acl.allowTransient(ctHash, account, msg.sender);
715
+ acl.allowTransient(ctHash, account, msg.sender);
711
716
 
712
- // NOTE: MOCK
713
- MOCK_trackedLogAllow('FHE.allowTransient', ctHash, account);
714
- }
717
+ // NOTE: MOCK
718
+ MOCK_trackedLogAllow('FHE.allowTransient', ctHash, account);
715
719
  }
716
720
 
717
721
  function allowForDecryption(uint256 ctHash) external {
718
- if (!TMCommon.isTriviallyEncryptedFromHash(ctHash)) {
719
- uint256[] memory hashes = new uint256[](1);
720
- hashes[0] = ctHash;
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
- // NOTE: MOCK
724
- MOCK_trackedLogAllow('FHE.allowForDecryption', ctHash, msg.sender);
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
- if (securityZone < securityZoneMin) {
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
- if (securityZone > securityZoneMax) {
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
- for (uint256 i = 0; i < ctHashes.length; i++) {
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
- bool[] memory out = new bool[](ctHashes.length);
908
- for (uint256 i = 0; i < ctHashes.length; i++) {
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";
package/dist/index.js CHANGED
@@ -1425,6 +1425,11 @@ var MockTaskManagerArtifact = {
1425
1425
  }
1426
1426
  ]
1427
1427
  },
1428
+ {
1429
+ type: "error",
1430
+ name: "LengthMismatch",
1431
+ inputs: []
1432
+ },
1428
1433
  {
1429
1434
  type: "error",
1430
1435
  name: "OnlyAggregatorAllowed",