@cofhe/mock-contracts 0.6.0 → 0.7.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.
@@ -2,7 +2,7 @@
2
2
  pragma solidity >=0.8.19 <0.9.0;
3
3
 
4
4
  import { Strings } from '@openzeppelin/contracts/utils/Strings.sol';
5
- import { MockPermissioned, Permission } from './Permissioned.sol';
5
+ import { MockPermissioned, ACP, SCOPE_GLOBAL, SCOPE_CONTRACT, SCOPE_HANDLES } from './Permissioned.sol';
6
6
  import { TASK_MANAGER_ADDRESS } from '@fhenixprotocol/cofhe-contracts/FHE.sol';
7
7
 
8
8
  /**
@@ -27,6 +27,16 @@ contract MockACL is MockPermissioned {
27
27
  /// @param sender Sender address.
28
28
  error DirectAllowForbidden(address sender);
29
29
 
30
+ /// @notice Returned when no share is pending for `receiver` on `handle`.
31
+ /// @param handle Handle.
32
+ /// @param receiver Address the share would have been directed at.
33
+ error NotShared(uint256 handle, address receiver);
34
+
35
+ /// @notice Returned when a share is pending but was written by a different party.
36
+ /// @param expected Sharer the receiver named.
37
+ /// @param actual Sharer recorded in the slot.
38
+ error UnexpectedSharer(address expected, address actual);
39
+
30
40
  /// @notice Emitted when a list of handles is allowed for decryption.
31
41
  /// @param handlesList List of handles allowed for decryption.
32
42
  event AllowedForDecryption(uint256[] handlesList);
@@ -37,17 +47,21 @@ contract MockACL is MockPermissioned {
37
47
  /// @param contractAddress Contract address.
38
48
  event NewDelegation(address indexed sender, address indexed delegatee, address indexed contractAddress);
39
49
 
50
+ /// @notice Emitted when the default revoker contract address is updated (zero = unset).
51
+ event DefaultRevokerContractUpdated(address oldAddress, address newAddress);
52
+
53
+ /// @notice Emitted when the share registry address is updated (zero = unset).
54
+ event ShareRegistryUpdated(address oldAddress, address newAddress);
55
+
40
56
  /// @custom:storage-location erc7201:cofhe.storage.ACL
41
57
  struct ACLStorage {
42
58
  mapping(uint256 handle => bool isGlobal) globalHandles;
43
59
  mapping(uint256 handle => mapping(address account => bool isAllowed)) persistedAllowedPairs;
44
60
  mapping(uint256 => bool) allowedForDecryption;
45
61
  mapping(address account => mapping(address delegatee => mapping(address contractAddress => bool isDelegate))) delegates;
46
- /// @dev Approximates EIP-1153 transient storage: stores the block.number when the allowance
47
- /// was granted. An allowance is considered active only if it was set in the current block,
48
- /// so it auto-expires when the block changes — no explicit cleanup required.
49
- /// In Hardhat automine mode (one tx per block) this faithfully replicates per-tx transience.
50
- mapping(bytes32 => uint256) transientAllowanceBlocks;
62
+ /// @dev ACP infrastructure addresses served to SDKs (appended fields — do not reorder)
63
+ address defaultRevokerContract;
64
+ address shareRegistry;
51
65
  }
52
66
 
53
67
  /// @notice Name of the contract.
@@ -69,6 +83,11 @@ contract MockACL is MockPermissioned {
69
83
  bytes32 private constant ACL_SLOT =
70
84
  keccak256(abi.encode(uint256(keccak256('cofhe.storage.ACL')) - 1)) & ~bytes32(uint256(0xff));
71
85
 
86
+ /// @dev Domain separator for share slots. Transient allowance keys are
87
+ /// keccak256(abi.encodePacked(handle, account)) with no prefix, so share keys must be
88
+ /// separated to stop a (handle, receiver) pair aliasing between the two namespaces.
89
+ bytes32 private constant SHARE_DOMAIN = keccak256('cofhe.acl.share');
90
+
72
91
  /// @custom:oz-upgrades-unsafe-allow constructor
73
92
  constructor() MockPermissioned() {}
74
93
 
@@ -156,9 +175,92 @@ contract MockACL is MockPermissioned {
156
175
  revert SenderNotAllowed(requester);
157
176
  }
158
177
 
159
- ACLStorage storage $ = _getACLStorage();
160
- bytes32 key = keccak256(abi.encodePacked(handle, account));
161
- $.transientAllowanceBlocks[key] = block.number;
178
+ _allowTransient(handle, account);
179
+ }
180
+
181
+ /**
182
+ * @dev Derives the transient slot holding the sharer for a directed share.
183
+ * @param handle Handle.
184
+ * @param receiver Address the share is directed at.
185
+ */
186
+ function _shareKey(uint256 handle, address receiver) private pure returns (bytes32) {
187
+ return keccak256(abi.encodePacked(SHARE_DOMAIN, handle, receiver));
188
+ }
189
+
190
+ /**
191
+ * @dev tstore plus registration in the cleanup index at transient slot 0, so that
192
+ * cleanTransientStorage() clears the key. Every transient write goes through here,
193
+ * which is what keeps allowances and share slots cleared together.
194
+ * @param key Transient slot.
195
+ * @param value Value to store.
196
+ */
197
+ function _tstoreTracked(bytes32 key, uint256 value) private {
198
+ assembly {
199
+ tstore(key, value)
200
+ let length := tload(0)
201
+ let lengthPlusOne := add(length, 1)
202
+ tstore(lengthPlusOne, key)
203
+ tstore(0, lengthPlusOne)
204
+ }
205
+ }
206
+
207
+ /**
208
+ * @dev Writes the transient allowance. Callers own the custody check.
209
+ * @param handle Handle.
210
+ * @param account Address being granted access.
211
+ */
212
+ function _allowTransient(uint256 handle, address account) internal {
213
+ _tstoreTracked(keccak256(abi.encodePacked(handle, account)), 1);
214
+ }
215
+
216
+ /**
217
+ * @notice Grants `receiver` transient access to `handle` and records `sharer` as the
218
+ * party that handed it over, for the duration of this transaction.
219
+ * @dev The caller must be the Task Manager contract.
220
+ * @dev Stricter than allowTransient: there is no TASK_MANAGER_ADDRESS bypass, since
221
+ * nothing shares on the Task Manager's own behalf.
222
+ * @param handle Handle.
223
+ * @param sharer Address handing the handle over.
224
+ * @param receiver Address the handle is being handed to.
225
+ */
226
+ function shareCtHash(uint256 handle, address sharer, address receiver) public virtual {
227
+ if (msg.sender != TASK_MANAGER_ADDRESS_) {
228
+ revert DirectAllowForbidden(msg.sender);
229
+ }
230
+
231
+ if (!isAllowed(handle, sharer)) {
232
+ revert SenderNotAllowed(sharer);
233
+ }
234
+
235
+ _allowTransient(handle, receiver); // capability
236
+ _tstoreTracked(_shareKey(handle, receiver), uint256(uint160(sharer))); // provenance
237
+ }
238
+
239
+ /**
240
+ * @notice Consumes the share directed at `receiver` for `handle`.
241
+ * @dev The caller must be the Task Manager contract. The slot is cleared, so a
242
+ * share is claimable exactly once. On revert the clear is rolled back with
243
+ * the frame, leaving the share available to its intended receiver.
244
+ * @param handle Handle.
245
+ * @param expectedSharer Sharer the receiver requires. Must be the party that delivered the
246
+ * handle, not merely one the receiver trusts.
247
+ * @param receiver Address consuming the share.
248
+ */
249
+ function receiveCtHash(uint256 handle, address expectedSharer, address receiver) public virtual {
250
+ if (msg.sender != TASK_MANAGER_ADDRESS_) {
251
+ revert DirectAllowForbidden(msg.sender);
252
+ }
253
+
254
+ bytes32 shareKey = _shareKey(handle, receiver);
255
+ address sharer;
256
+ assembly {
257
+ sharer := tload(shareKey)
258
+ tstore(shareKey, 0)
259
+ }
260
+
261
+ if (sharer == address(0)) revert NotShared(handle, receiver);
262
+ if (sharer != expectedSharer) revert UnexpectedSharer(expectedSharer, sharer);
263
+ if (!isAllowed(handle, sharer)) revert SenderNotAllowed(sharer);
162
264
  }
163
265
 
164
266
  /**
@@ -213,9 +315,12 @@ contract MockACL is MockPermissioned {
213
315
  * @return isAllowedTransient Whether the account can access transiently the handle.
214
316
  */
215
317
  function allowedTransient(uint256 handle, address account) public view virtual returns (bool) {
216
- ACLStorage storage $ = _getACLStorage();
318
+ bool isAllowedTransient;
217
319
  bytes32 key = keccak256(abi.encodePacked(handle, account));
218
- return $.transientAllowanceBlocks[key] == block.number;
320
+ assembly {
321
+ isAllowedTransient := tload(key)
322
+ }
323
+ return isAllowedTransient;
219
324
  }
220
325
 
221
326
  /**
@@ -269,13 +374,28 @@ contract MockACL is MockPermissioned {
269
374
  }
270
375
 
271
376
  /**
272
- * @dev No-op in the mock: transient allowances auto-expire when the block changes, so explicit
273
- * cleanup is not needed. Kept for interface compatibility with the production ACL.
377
+ * @dev This function removes the transient allowances, which could be useful for integration with
378
+ * Account Abstraction when bundling several UserOps calling the TaskManagerCoprocessor.
274
379
  */
275
380
  function cleanTransientStorage() external virtual {
276
381
  if (msg.sender != TASK_MANAGER_ADDRESS_) {
277
382
  revert DirectAllowForbidden(msg.sender);
278
383
  }
384
+
385
+ assembly {
386
+ let length := tload(0)
387
+ tstore(0, 0)
388
+ let lengthPlusOne := add(length, 1)
389
+ for {
390
+ let i := 1
391
+ } lt(i, lengthPlusOne) {
392
+ i := add(i, 1)
393
+ } {
394
+ let handle := tload(i)
395
+ tstore(i, 0)
396
+ tstore(handle, 0)
397
+ }
398
+ }
279
399
  }
280
400
 
281
401
  /**
@@ -307,14 +427,73 @@ contract MockACL is MockPermissioned {
307
427
  }
308
428
  }
309
429
 
310
- function isAllowedWithPermission(
311
- Permission memory permission,
312
- uint256 handle
313
- ) public view withPermission(permission) returns (bool) {
314
- return isAllowed(handle, permission.issuer);
430
+
431
+ // ---------------------------------------------------------------------------
432
+ // ACP (ACP V3) — scope-checked access
433
+ // ---------------------------------------------------------------------------
434
+
435
+ /// @notice Default revoker contract for newly created ACPs, served to SDKs (zero = unset).
436
+ function defaultRevokerContract() public view returns (address) {
437
+ return _getACLStorage().defaultRevokerContract;
315
438
  }
316
439
 
317
- function checkPermitValidity(Permission memory permission) public view withPermission(permission) returns (bool) {
318
- return true;
440
+ /// @notice The ACPShareRegistry address, served to SDKs (zero = sharing unavailable).
441
+ function shareRegistry() public view returns (address) {
442
+ return _getACLStorage().shareRegistry;
443
+ }
444
+
445
+ /// @notice Sets the default revoker contract address (unrestricted in the mock;
446
+ /// the production setter is onlyOwner).
447
+ function setDefaultRevokerContract(address newAddress) external {
448
+ ACLStorage storage $ = _getACLStorage();
449
+ emit DefaultRevokerContractUpdated($.defaultRevokerContract, newAddress);
450
+ $.defaultRevokerContract = newAddress;
451
+ }
452
+
453
+ /// @notice Sets the share registry address (unrestricted in the mock;
454
+ /// the production setter is onlyOwner).
455
+ function setShareRegistry(address newAddress) external {
456
+ ACLStorage storage $ = _getACLStorage();
457
+ emit ShareRegistryUpdated($.shareRegistry, newAddress);
458
+ $.shareRegistry = newAddress;
459
+ }
460
+
461
+ /// @notice V3 (ACP) access check — the scope table.
462
+ ///
463
+ /// | condition | result |
464
+ /// |------------------------------------------------------|--------|
465
+ /// | permission structure invalid (expired/sig/revoked) | REVERT |
466
+ /// | issuer does NOT have access to handle | false |
467
+ /// | permission.global | true |
468
+ /// | any permission.contracts allowed for handle | true |
469
+ /// | permission.handles contains handle | true |
470
+ /// | otherwise | false |
471
+ ///
472
+ /// @dev Scopes narrow the issuer's existing access, never widen it.
473
+ /// Contract scope is an intersection over the EXISTING
474
+ /// `persistedAllowedPairs` (populated via FHE.allow/allowThis) —
475
+ /// no new data structures. Transient allowances deliberately do not
476
+ /// satisfy contract scope: only persisted grants count.
477
+ function isAllowedWithPermission(ACP memory acp, uint256 handle) public view withPermission(acp) returns (bool) {
478
+ // Scopes narrow the issuer's existing access, never widen it
479
+ if (!isAllowed(handle, acp.issuer)) return false;
480
+
481
+ if (acp.scope == SCOPE_GLOBAL) return true;
482
+
483
+ if (acp.scope == SCOPE_CONTRACT) {
484
+ for (uint256 i = 0; i < acp.contracts.length; i++) {
485
+ if (isAllowed(handle, acp.contracts[i])) return true;
486
+ }
487
+ return false;
488
+ }
489
+
490
+ if (acp.scope == SCOPE_HANDLES) {
491
+ for (uint256 i = 0; i < acp.handles.length; i++) {
492
+ if (acp.handles[i] == bytes32(handle)) return true;
493
+ }
494
+ return false;
495
+ }
496
+
497
+ return false;
319
498
  }
320
499
  }
@@ -2,12 +2,13 @@
2
2
  /* solhint-disable one-contract-per-file */
3
3
  pragma solidity >=0.8.25 <0.9.0;
4
4
 
5
- import { MockACL, Permission } from './MockACL.sol';
5
+ import { MockACL } from './MockACL.sol';
6
+ import { ACP } from './Permissioned.sol';
6
7
  // import {PlaintextsStorage} from "./PlaintextsStorage.sol";
7
8
  import { Strings } from '@openzeppelin/contracts/utils/Strings.sol';
8
9
  import { ECDSA } from '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';
9
10
  import { MockCoFHE } from './MockCoFHE.sol';
10
- import { ITaskManager, FunctionId, Utils, EncryptedInput } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol';
11
+ import { ITaskManager, FunctionId, Utils, UnsignedEncryptedInput } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol';
11
12
 
12
13
  error DecryptionResultNotReady(uint256 ctHash);
13
14
  // Input validation errors
@@ -556,26 +557,53 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
556
557
  }
557
558
  }
558
559
 
559
- function verifyInput(EncryptedInput memory input, address sender) external returns (uint256) {
560
- int32 securityZone = int32(uint32(input.securityZone));
561
-
560
+ /// @notice Verify a batch of encrypted inputs that share a single signature.
561
+ /// @dev The verifier signs the whole batch with one signature over
562
+ /// keccak256(h_0 || h_1 || ... || h_n), where each h_i is the same
563
+ /// per-input message hash defined by `inputMessageHash`:
564
+ /// keccak256(ctHash || utype || securityZone || sender || chainid || contractAddress).
565
+ /// `contractAddress` (the caller of this function) binds the batch to the specific
566
+ /// consuming contract, matching cofhe-contracts#77.
567
+ /// Inputs are processed in order; the returned hashes line up with `inputs`.
568
+ /// This is the sole verification path - the real FHE.sol library routes single
569
+ /// inputs through here too (as a one-element batch), so there's no separate
570
+ /// single-item `verifyInput` entry point to keep in sync.
571
+ /// @param inputs The encrypted inputs to verify (no per-input signature -
572
+ /// the batch is authenticated by the single `signature` argument).
573
+ /// @param sender The account the inputs are bound to.
574
+ /// @param signature The single ECDSA signature covering the whole batch.
575
+ /// @return appendedHashes The metadata-appended ct hashes, in input order.
576
+ function batchVerifyInputs(
577
+ UnsignedEncryptedInput[] memory inputs,
578
+ address sender,
579
+ bytes memory signature
580
+ ) external returns (uint256[] memory) {
581
+ uint256 len = inputs.length;
562
582
  // When signer is set to 0 address we skip this logic to be able to support debug use cases.
563
583
  // In debug use cases we assume that the verifier is not necessarily running.
564
584
  if (verifierSigner != address(0)) {
565
- if (!isValidSecurityZone(securityZone)) {
566
- revert InvalidSecurityZone(securityZone, securityZoneMin, securityZoneMax);
585
+ for (uint256 i = 0; i < len; i++) {
586
+ int32 securityZone = int32(uint32(inputs[i].securityZone));
587
+ if (!isValidSecurityZone(securityZone)) {
588
+ revert InvalidSecurityZone(securityZone, securityZoneMin, securityZoneMax);
589
+ }
567
590
  }
568
591
 
569
- address signer = extractSigner(input, sender);
592
+ address signer = extractBatchSigner(inputs, sender, msg.sender, signature);
570
593
  if (signer != verifierSigner) {
571
594
  revert InvalidSigner(signer, verifierSigner);
572
595
  }
573
596
  }
574
597
 
575
- uint256 appendedHash = TMCommon.appendMetadata(input.ctHash, securityZone, input.utype, false);
598
+ uint256[] memory appendedHashes = new uint256[](len);
599
+ for (uint256 i = 0; i < len; i++) {
600
+ int32 securityZone = int32(uint32(inputs[i].securityZone));
601
+ uint256 appendedHash = TMCommon.appendMetadata(inputs[i].ctHash, securityZone, inputs[i].utype, false);
602
+ acl.allowTransient(appendedHash, msg.sender, address(this));
603
+ appendedHashes[i] = appendedHash;
604
+ }
576
605
 
577
- acl.allowTransient(appendedHash, msg.sender, address(this));
578
- return appendedHash;
606
+ return appendedHashes;
579
607
  }
580
608
 
581
609
  function allow(uint256 ctHash, address account) external {
@@ -623,11 +651,55 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
623
651
  return acl.isAllowed(ctHash, account);
624
652
  }
625
653
 
626
- function extractSigner(EncryptedInput memory input, address sender) private view returns (address) {
627
- bytes memory combined = abi.encodePacked(input.ctHash, input.utype, input.securityZone, sender, block.chainid);
628
- bytes32 expectedHash = keccak256(combined);
654
+ function shareCtHash(uint256 ctHash, address receiver) external {
655
+ acl.shareCtHash(ctHash, msg.sender, receiver);
656
+
657
+ // NOTE: MOCK
658
+ MOCK_logAllow('FHE.share', ctHash, receiver);
659
+ }
629
660
 
630
- address signer = ECDSA.recover(expectedHash, input.signature);
661
+ function receiveCtHash(uint256 ctHash, address expectedSharer) external {
662
+ acl.receiveCtHash(ctHash, expectedSharer, msg.sender);
663
+
664
+ // NOTE: MOCK
665
+ MOCK_logAllow('FHE.receive', ctHash, expectedSharer);
666
+ }
667
+
668
+ /// @dev Per-input message hash used by batch verification:
669
+ /// keccak256(ctHash || utype || securityZone || sender || chainid || contractAddress).
670
+ /// `contractAddress` binds the input to the specific contract that consumes it
671
+ /// (the caller of `batchVerifyInputs`), matching cofhe-contracts#77 -
672
+ /// without this, a signed input observed on-chain could be replayed into any other
673
+ /// contract, which would then obtain an ACL allowance over the ciphertext.
674
+ function inputMessageHash(
675
+ uint256 ctHash,
676
+ uint8 utype,
677
+ uint8 securityZone,
678
+ address sender,
679
+ address contractAddress
680
+ ) private view returns (bytes32) {
681
+ return keccak256(abi.encodePacked(ctHash, utype, securityZone, sender, block.chainid, contractAddress));
682
+ }
683
+
684
+ /// @dev Recover the signer of a batch from the single signature over
685
+ /// keccak256(h_0 || h_1 || ... || h_n), where each h_i is `inputMessageHash`.
686
+ function extractBatchSigner(
687
+ UnsignedEncryptedInput[] memory inputs,
688
+ address sender,
689
+ address contractAddress,
690
+ bytes memory signature
691
+ ) private view returns (address) {
692
+ bytes memory concatenatedHashes;
693
+ for (uint256 i = 0; i < inputs.length; i++) {
694
+ concatenatedHashes = abi.encodePacked(
695
+ concatenatedHashes,
696
+ inputMessageHash(inputs[i].ctHash, inputs[i].utype, inputs[i].securityZone, sender, contractAddress)
697
+ );
698
+ }
699
+
700
+ bytes32 batchHash = keccak256(concatenatedHashes);
701
+
702
+ address signer = ECDSA.recover(batchHash, signature);
631
703
 
632
704
  if (signer == address(0)) {
633
705
  revert InvalidSignature();
@@ -683,8 +755,9 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
683
755
  aggregator = _aggregatorAddress;
684
756
  }
685
757
 
686
- function isAllowedWithPermission(Permission memory permission, uint256 handle) public view returns (bool) {
687
- return acl.isAllowedWithPermission(permission, handle);
758
+ /// @notice ACP scope-checked access, forwarded to the ACL.
759
+ function isAllowedWithPermission(ACP memory acp, uint256 handle) public view returns (bool) {
760
+ return acl.isAllowedWithPermission(acp, handle);
688
761
  }
689
762
 
690
763
  // Stub implementations for new ITaskManager interface methods (inc PR #48)
@@ -9,7 +9,7 @@ pragma solidity >=0.8.19 <0.9.0;
9
9
 
10
10
  import { MockACL } from './MockACL.sol';
11
11
  import { MockTaskManager } from './MockTaskManager.sol';
12
- import { Permission, MockPermissioned } from './Permissioned.sol';
12
+ import { MockPermissioned, ACP } from './Permissioned.sol';
13
13
 
14
14
  contract MockThresholdNetwork {
15
15
  MockTaskManager public mockTaskManager;
@@ -35,10 +35,10 @@ contract MockThresholdNetwork {
35
35
  function queryDecrypt(
36
36
  uint256 ctHash,
37
37
  uint256,
38
- Permission memory permission
38
+ ACP memory acp
39
39
  ) public view returns (bool allowed, string memory error, uint256) {
40
40
  bool isAllowed;
41
- try mockAcl.isAllowedWithPermission(permission, ctHash) returns (bool _isAllowed) {
41
+ try mockAcl.isAllowedWithPermission(acp, ctHash) returns (bool _isAllowed) {
42
42
  isAllowed = _isAllowed;
43
43
  } catch Error(string memory reason) {
44
44
  // Handle string error messages
@@ -92,12 +92,12 @@ contract MockThresholdNetwork {
92
92
  function querySealOutput(
93
93
  uint256 ctHash,
94
94
  uint256,
95
- Permission memory permission
95
+ ACP memory acp
96
96
  ) public view returns (bool allowed, string memory error, bytes32) {
97
- if (permission.sealingKey == bytes32(0)) revert SealingKeyMissing();
97
+ if (acp.sealingKey == bytes32(0)) revert SealingKeyMissing();
98
98
 
99
99
  bool isAllowed;
100
- try mockAcl.isAllowedWithPermission(permission, ctHash) returns (bool _isAllowed) {
100
+ try mockAcl.isAllowedWithPermission(acp, ctHash) returns (bool _isAllowed) {
101
101
  isAllowed = _isAllowed;
102
102
  } catch Error(string memory reason) {
103
103
  // Handle string error messages
@@ -112,16 +112,16 @@ contract MockThresholdNetwork {
112
112
  if (!isAllowed) return (false, 'NotAllowed', bytes32(0));
113
113
 
114
114
  uint256 value = mockTaskManager.mockStorage(ctHash);
115
- return (true, '', seal(value, permission.sealingKey));
115
+ return (true, '', seal(value, acp.sealingKey));
116
116
  }
117
117
 
118
118
  // DECRYPT FOR TX
119
119
 
120
- function _isAllowedWithPermit(
120
+ function _isAllowedWithACP(
121
121
  uint256 ctHash,
122
- Permission memory permission
122
+ ACP memory acp
123
123
  ) internal view returns (bool isAllowed, string memory error) {
124
- try mockTaskManager.isAllowedWithPermission(permission, ctHash) returns (bool _isAllowed) {
124
+ try mockTaskManager.isAllowedWithPermission(acp, ctHash) returns (bool _isAllowed) {
125
125
  isAllowed = _isAllowed;
126
126
  } catch Error(string memory reason) {
127
127
  return (false, reason);
@@ -135,7 +135,7 @@ contract MockThresholdNetwork {
135
135
  return (true, '');
136
136
  }
137
137
 
138
- function _isAllowedWithoutPermit(uint256 ctHash) internal view returns (bool isAllowed, string memory error) {
138
+ function _isAllowedWithoutACP(uint256 ctHash) internal view returns (bool isAllowed, string memory error) {
139
139
  try mockAcl.globalAllowed(ctHash) returns (bool _isAllowed) {
140
140
  isAllowed = _isAllowed;
141
141
  } catch Error(string memory reason) {
@@ -150,27 +150,27 @@ contract MockThresholdNetwork {
150
150
  return (true, '');
151
151
  }
152
152
 
153
- /// @notice Decrypt a ciphertext for a transaction using a permit.
154
- function decryptForTxWithPermit(
153
+ /// @notice Decrypt a ciphertext for a transaction using an ACP.
154
+ function decryptForTxWithACP(
155
155
  uint256 ctHash,
156
- Permission memory permission
156
+ ACP memory acp
157
157
  ) public view returns (bool allowed, string memory error, uint256 decryptedValue) {
158
- if (permission.issuer == address(0)) {
158
+ if (acp.issuer == address(0)) {
159
159
  return (false, 'PermissionMissing', 0);
160
160
  }
161
161
 
162
- (bool isAllowed, string memory err) = _isAllowedWithPermit(ctHash, permission);
162
+ (bool isAllowed, string memory err) = _isAllowedWithACP(ctHash, acp);
163
163
  if (!isAllowed) return (false, err, 0);
164
164
 
165
165
  uint256 value = mockTaskManager.mockStorage(ctHash);
166
166
  return (true, '', value);
167
167
  }
168
168
 
169
- /// @notice Decrypt a ciphertext for a transaction using global allowance (no permit).
170
- function decryptForTxWithoutPermit(
169
+ /// @notice Decrypt a ciphertext for a transaction using global allowance (no acp).
170
+ function decryptForTxWithoutACP(
171
171
  uint256 ctHash
172
172
  ) public view returns (bool allowed, string memory error, uint256 decryptedValue) {
173
- (bool isAllowed, string memory err) = _isAllowedWithoutPermit(ctHash);
173
+ (bool isAllowed, string memory err) = _isAllowedWithoutACP(ctHash);
174
174
  if (!isAllowed) return (false, err, 0);
175
175
 
176
176
  uint256 value = mockTaskManager.mockStorage(ctHash);