@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.
- package/CHANGELOG.md +38 -0
- package/README.md +46 -30
- package/contracts/ABITest.sol +26 -13
- package/contracts/ACPShareRegistry.sol +145 -0
- package/contracts/ACPTimestampRevoker.sol +62 -0
- package/contracts/MockACL.sol +199 -20
- package/contracts/MockTaskManager.sol +90 -17
- package/contracts/MockThresholdNetwork.sol +19 -19
- package/contracts/Permissioned.sol +85 -124
- package/dist/index.d.mts +1023 -128
- package/dist/index.d.ts +1023 -128
- package/dist/index.js +868 -81
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +867 -82
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/ACPShareRegistry.ts +359 -0
- package/src/ACPTimestampRevoker.ts +134 -0
- package/src/MockACL.ts +207 -9
- package/src/MockTaskManager.ts +101 -50
- package/src/MockThresholdNetwork.ts +59 -14
- package/src/index.ts +10 -1
- package/src/typechain-types/ACPShareRegistry.ts +189 -0
- package/src/typechain-types/ACPTimestampRevoker.ts +157 -0
- package/src/typechain-types/MockACL.ts +151 -19
- package/src/typechain-types/MockTaskManager.ts +67 -33
- package/src/typechain-types/MockThresholdNetwork.ts +35 -29
- package/src/typechain-types/index.ts +2 -0
|
@@ -5,142 +5,108 @@ pragma solidity >=0.8.19 <0.9.0;
|
|
|
5
5
|
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
|
|
6
6
|
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
|
7
7
|
|
|
8
|
+
/// @dev ACP scope discriminator (uint8 on the wire). Exactly one scope mode per ACP:
|
|
9
|
+
/// SCOPE_GLOBAL — access to ALL of `issuer`s encrypted values; `contracts`/`handles` must be empty
|
|
10
|
+
/// SCOPE_CONTRACT — access to values readable by any of `contracts`; `handles` must be empty
|
|
11
|
+
/// SCOPE_HANDLES — access to the listed ciphertext `handles` only; `contracts` must be empty
|
|
12
|
+
/// Array/scope consistency is validated client-side at creation (no contract-side enforcement).
|
|
13
|
+
uint8 constant SCOPE_GLOBAL = 0;
|
|
14
|
+
uint8 constant SCOPE_CONTRACT = 1;
|
|
15
|
+
uint8 constant SCOPE_HANDLES = 2;
|
|
16
|
+
|
|
8
17
|
/**
|
|
9
|
-
* @dev
|
|
10
|
-
*
|
|
11
|
-
* The minimum permission to access a user's own data requires the fields
|
|
12
|
-
* < issuer, expiration, sealingKey, issuerSignature >
|
|
13
|
-
*
|
|
14
|
-
* ---
|
|
15
|
-
*
|
|
16
|
-
* If not sharing the permission, `issuer` signs a signature using the fields:
|
|
17
|
-
* < issuer, expiration, sealingKey, issuerSignature >
|
|
18
|
-
* This signature can now be used by `issuer` to access their own encrypted data.
|
|
19
|
-
*
|
|
20
|
-
* ---
|
|
21
|
-
*
|
|
22
|
-
* Sharing a permission is a two step process: `issuer` completes step 1, and `recipient` completes step 2.
|
|
23
|
-
*
|
|
24
|
-
* 1:
|
|
25
|
-
* `issuer` creates a permission with `recipient` populated with the address of the user to give access to.
|
|
26
|
-
* `issuer` does not include a `sealingKey` in the permission, it will be populated by the `recipient`.
|
|
27
|
-
* `issuer` signs a signature including the fields: (note: `sealingKey` is absent in this signature)
|
|
28
|
-
* < issuer, expiration, sealingKey, issuerSignature >
|
|
29
|
-
* `issuer` packages the permission data and `issuerSignature` and shares it with `recipient`
|
|
30
|
-
* ** None of this data is sensitive, and can be shared as cleartext **
|
|
31
|
-
*
|
|
32
|
-
* 2:
|
|
33
|
-
* `recipient` adds their `sealingKey` to the data received from `issuer`
|
|
34
|
-
* `recipient` signs a signature including the fields:
|
|
35
|
-
* < sealingKey, issuerSignature >
|
|
36
|
-
* `recipient` can now use the completed Permission to access `issuer`s encrypted data.
|
|
18
|
+
* @dev ACP (Access Control Permission) — the V3 permission struct.
|
|
37
19
|
*
|
|
38
|
-
*
|
|
20
|
+
* Signing flows are identical to V2 (self / two-step sharing) with the
|
|
21
|
+
* `ACPIssuerSelf` / `ACPIssuerShared` / `ACPRecipient` EIP-712 types under
|
|
22
|
+
* domain version "2".
|
|
39
23
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
24
|
+
* Revocation: `revokerData` is an opaque uint256 interpreted by
|
|
25
|
+
* `revokerContract` (creation timestamp in the default ACPTimestampRevoker).
|
|
26
|
+
* `revokerData = 0` or `revokerContract = address(0)` disables the check
|
|
27
|
+
* (permission not revocable).
|
|
43
28
|
*/
|
|
44
|
-
struct
|
|
45
|
-
// (base) User that initially created the permission, target of data fetching
|
|
29
|
+
struct ACP {
|
|
46
30
|
address issuer;
|
|
47
|
-
// (base) Expiration timestamp
|
|
48
31
|
uint64 expiration;
|
|
49
|
-
// (sharing) The user that this permission will be shared with
|
|
50
|
-
// ** optional, use `address(0)` to disable **
|
|
51
32
|
address recipient;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
address validatorContract;
|
|
58
|
-
// (base) The publicKey of a sealingPair used to re-encrypt `issuer`s confidential data
|
|
59
|
-
// (non-sharing) Populated by `issuer`
|
|
60
|
-
// (sharing) Populated by `recipient`
|
|
33
|
+
uint256 revokerData;
|
|
34
|
+
address revokerContract;
|
|
35
|
+
uint8 scope;
|
|
36
|
+
address[] contracts;
|
|
37
|
+
bytes32[] handles;
|
|
61
38
|
bytes32 sealingKey;
|
|
62
|
-
// (base) `signTypedData` signature created by `issuer`.
|
|
63
|
-
// (base) Shared- and Self- permissions differ in signature format: (`sealingKey` absent in shared signature)
|
|
64
|
-
// (non-sharing) < issuer, expiration, recipient, validatorId, validatorContract, sealingKey >
|
|
65
|
-
// (sharing) < issuer, expiration, recipient, validatorId, validatorContract >
|
|
66
39
|
bytes issuerSignature;
|
|
67
|
-
// (sharing) `signTypedData` signature created by `recipient` with format:
|
|
68
|
-
// (sharing) < sealingKey, issuerSignature>
|
|
69
|
-
// ** required for shared permits **
|
|
70
40
|
bytes recipientSignature;
|
|
71
41
|
}
|
|
72
42
|
|
|
73
|
-
/// @dev Minimum required interface to create a custom permission
|
|
74
|
-
///
|
|
43
|
+
/// @dev Minimum required interface to create a custom permission revoker.
|
|
44
|
+
/// Revokers are optional and provide control to disable a permission after creation.
|
|
75
45
|
interface IPermissionCustomIdValidator {
|
|
76
|
-
/// @dev
|
|
46
|
+
/// @dev Returning `true` disables the permission.
|
|
77
47
|
function disabled(address issuer, uint256 id) external view returns (bool);
|
|
78
48
|
}
|
|
79
49
|
|
|
80
50
|
contract MockPermissioned is EIP712 {
|
|
81
|
-
using
|
|
51
|
+
using ACPUtils for ACP;
|
|
82
52
|
|
|
83
|
-
|
|
53
|
+
/// @dev Same verifying-contract identity as V2 ("ACL"), domain version bumped for V3 types.
|
|
54
|
+
constructor() EIP712("ACL", "2") {}
|
|
84
55
|
|
|
85
|
-
/// @dev Emitted when `permission.expiration` is in the past (< block.timestamp)
|
|
86
56
|
error PermissionInvalid_Expired();
|
|
87
|
-
|
|
88
|
-
/// @dev Emitted when `issuerSignature` is malformed or was not signed by `permission.issuer`
|
|
89
57
|
error PermissionInvalid_IssuerSignature();
|
|
90
|
-
|
|
91
|
-
/// @dev Emitted when `recipientSignature` is malformed or was not signed by `permission.recipient`
|
|
92
58
|
error PermissionInvalid_RecipientSignature();
|
|
93
|
-
|
|
94
|
-
/// @dev Emitted when `validatorContract` returned `false` indicating that this permission has been externally disabled
|
|
95
59
|
error PermissionInvalid_Disabled();
|
|
96
60
|
|
|
97
|
-
/// @dev
|
|
98
|
-
///
|
|
99
|
-
/// - Expired: `permission.expiration` is in the past (< block.timestamp)
|
|
100
|
-
/// - Issuer signature: `issuerSignature` is malformed or was not signed by `permission.issuer`
|
|
101
|
-
/// - Recipient signature: `recipientSignature` is malformed or was not signed by `permission.recipient`
|
|
102
|
-
/// - Disabled: `validatorContract` returned `false` indicating that this permission has been externally disabled
|
|
103
|
-
/// @param permission Permission struct containing data necessary to validate data access and seal for return.
|
|
61
|
+
/// @dev Validates an ACP's structure: expiration, signatures, revocation.
|
|
62
|
+
/// Identical check order and semantics to V2 `withPermission`.
|
|
104
63
|
///
|
|
105
|
-
/// NOTE: Functions protected by `withPermission` should return ONLY the sensitive data of `
|
|
64
|
+
/// NOTE: Functions protected by `withPermission` should return ONLY the sensitive data of `acp.issuer`.
|
|
106
65
|
/// !! Returning data of `msg.sender` will leak sensitive values - `msg.sender` cannot be trusted in view functions !!
|
|
107
|
-
modifier withPermission(
|
|
66
|
+
modifier withPermission(ACP memory acp) {
|
|
108
67
|
// Expiration
|
|
109
|
-
if (
|
|
68
|
+
if (acp.expiration < block.timestamp)
|
|
110
69
|
revert PermissionInvalid_Expired();
|
|
111
70
|
|
|
112
71
|
// Issuer signature
|
|
113
72
|
if (
|
|
114
73
|
!SignatureChecker.isValidSignatureNow(
|
|
115
|
-
|
|
116
|
-
_hashTypedDataV4(
|
|
117
|
-
|
|
74
|
+
acp.issuer,
|
|
75
|
+
_hashTypedDataV4(acp.issuerHash()),
|
|
76
|
+
acp.issuerSignature
|
|
118
77
|
)
|
|
119
78
|
) revert PermissionInvalid_IssuerSignature();
|
|
120
79
|
|
|
121
80
|
// (if applicable) Recipient signature
|
|
122
81
|
if (
|
|
123
|
-
|
|
82
|
+
acp.recipient != address(0) &&
|
|
124
83
|
!SignatureChecker.isValidSignatureNow(
|
|
125
|
-
|
|
126
|
-
_hashTypedDataV4(
|
|
127
|
-
|
|
84
|
+
acp.recipient,
|
|
85
|
+
_hashTypedDataV4(acp.recipientHash()),
|
|
86
|
+
acp.recipientSignature
|
|
128
87
|
)
|
|
129
88
|
) revert PermissionInvalid_RecipientSignature();
|
|
130
89
|
|
|
131
|
-
// (if applicable) Externally disabled
|
|
90
|
+
// (if applicable) Externally disabled (revoked)
|
|
132
91
|
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
IPermissionCustomIdValidator(
|
|
136
|
-
|
|
137
|
-
|
|
92
|
+
acp.revokerData != 0 &&
|
|
93
|
+
acp.revokerContract != address(0) &&
|
|
94
|
+
IPermissionCustomIdValidator(acp.revokerContract).disabled(
|
|
95
|
+
acp.issuer,
|
|
96
|
+
acp.revokerData
|
|
138
97
|
)
|
|
139
98
|
) revert PermissionInvalid_Disabled();
|
|
140
99
|
|
|
141
100
|
_;
|
|
142
101
|
}
|
|
143
102
|
|
|
103
|
+
/// @dev Structure-validity probe (expiration / signatures / revocation).
|
|
104
|
+
function checkPermissionValidity(
|
|
105
|
+
ACP memory acp
|
|
106
|
+
) public view withPermission(acp) returns (bool) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
144
110
|
function hashTypedDataV4(
|
|
145
111
|
bytes32 structHash
|
|
146
112
|
) public view virtual returns (bytes32) {
|
|
@@ -148,65 +114,60 @@ contract MockPermissioned is EIP712 {
|
|
|
148
114
|
}
|
|
149
115
|
}
|
|
150
116
|
|
|
151
|
-
/// @dev
|
|
152
|
-
///
|
|
153
|
-
library
|
|
154
|
-
function issuerHash(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (permission.recipient == address(0))
|
|
158
|
-
return issuerSelfHash(permission);
|
|
159
|
-
return issuerSharedHash(permission);
|
|
117
|
+
/// @dev Signature type hashes for ACP. Field order must match the struct and the
|
|
118
|
+
/// SDK's SignatureTypes exactly — pinned by tests on both sides.
|
|
119
|
+
library ACPUtils {
|
|
120
|
+
function issuerHash(ACP memory acp) internal pure returns (bytes32) {
|
|
121
|
+
if (acp.recipient == address(0)) return issuerSelfHash(acp);
|
|
122
|
+
return issuerSharedHash(acp);
|
|
160
123
|
}
|
|
161
124
|
|
|
162
|
-
function issuerSelfHash(
|
|
163
|
-
Permission memory permission
|
|
164
|
-
) internal pure returns (bytes32) {
|
|
125
|
+
function issuerSelfHash(ACP memory acp) internal pure returns (bytes32) {
|
|
165
126
|
return
|
|
166
127
|
keccak256(
|
|
167
128
|
abi.encode(
|
|
168
129
|
keccak256(
|
|
169
|
-
"
|
|
130
|
+
"ACPIssuerSelf(address issuer,uint64 expiration,address recipient,uint256 revokerData,address revokerContract,uint8 scope,address[] contracts,bytes32[] handles,bytes32 sealingKey)"
|
|
170
131
|
),
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
132
|
+
acp.issuer,
|
|
133
|
+
acp.expiration,
|
|
134
|
+
acp.recipient,
|
|
135
|
+
acp.revokerData,
|
|
136
|
+
acp.revokerContract,
|
|
137
|
+
acp.scope,
|
|
138
|
+
keccak256(abi.encodePacked(acp.contracts)),
|
|
139
|
+
keccak256(abi.encodePacked(acp.handles)),
|
|
140
|
+
acp.sealingKey
|
|
177
141
|
)
|
|
178
142
|
);
|
|
179
143
|
}
|
|
180
144
|
|
|
181
|
-
function issuerSharedHash(
|
|
182
|
-
Permission memory permission
|
|
183
|
-
) internal pure returns (bytes32) {
|
|
145
|
+
function issuerSharedHash(ACP memory acp) internal pure returns (bytes32) {
|
|
184
146
|
return
|
|
185
147
|
keccak256(
|
|
186
148
|
abi.encode(
|
|
187
149
|
keccak256(
|
|
188
|
-
"
|
|
150
|
+
"ACPIssuerShared(address issuer,uint64 expiration,address recipient,uint256 revokerData,address revokerContract,uint8 scope,address[] contracts,bytes32[] handles)"
|
|
189
151
|
),
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
152
|
+
acp.issuer,
|
|
153
|
+
acp.expiration,
|
|
154
|
+
acp.recipient,
|
|
155
|
+
acp.revokerData,
|
|
156
|
+
acp.revokerContract,
|
|
157
|
+
acp.scope,
|
|
158
|
+
keccak256(abi.encodePacked(acp.contracts)),
|
|
159
|
+
keccak256(abi.encodePacked(acp.handles))
|
|
195
160
|
)
|
|
196
161
|
);
|
|
197
162
|
}
|
|
198
163
|
|
|
199
|
-
function recipientHash(
|
|
200
|
-
Permission memory permission
|
|
201
|
-
) internal pure returns (bytes32) {
|
|
164
|
+
function recipientHash(ACP memory acp) internal pure returns (bytes32) {
|
|
202
165
|
return
|
|
203
166
|
keccak256(
|
|
204
167
|
abi.encode(
|
|
205
|
-
keccak256(
|
|
206
|
-
|
|
207
|
-
)
|
|
208
|
-
permission.sealingKey,
|
|
209
|
-
keccak256(permission.issuerSignature)
|
|
168
|
+
keccak256("ACPRecipient(bytes32 sealingKey,bytes issuerSignature)"),
|
|
169
|
+
acp.sealingKey,
|
|
170
|
+
keccak256(acp.issuerSignature)
|
|
210
171
|
)
|
|
211
172
|
);
|
|
212
173
|
}
|