@zentity/fhevm-contracts 0.3.0 → 0.4.1

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.
Files changed (123) hide show
  1. package/abi/ComplianceRules.json +25 -16
  2. package/abi/CompliantERC20.json +30 -16
  3. package/abi/IdentityRegistry.json +496 -119
  4. package/contracts/compliance/ComplianceRules.sol +40 -189
  5. package/contracts/core/IdentityRegistry.sol +280 -232
  6. package/contracts/interfaces/IComplianceRules.sol +30 -0
  7. package/contracts/interfaces/IIdentityRegistry.sol +133 -159
  8. package/contracts/proxy/ERC1967Proxy.sol +6 -0
  9. package/contracts/test/MockFacilitator.sol +40 -0
  10. package/contracts/tokens/CompliantERC20.sol +28 -242
  11. package/deployments/hardhat/addresses.json +3 -8
  12. package/deployments/sepolia/ComplianceRules.json +91 -207
  13. package/deployments/sepolia/CompliantERC20.json +114 -293
  14. package/deployments/sepolia/IdentityRegistry.json +498 -742
  15. package/deployments/sepolia/IdentityRegistry_Implementation.json +1698 -0
  16. package/deployments/sepolia/IdentityRegistry_Proxy.json +192 -0
  17. package/deployments/sepolia/addresses.json +5 -6
  18. package/dist/index.d.ts +175 -9
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +44 -1
  21. package/package.json +1 -1
  22. package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +153 -0
  23. package/typechain-types/@openzeppelin/contracts/access/Ownable2Step.ts +217 -0
  24. package/typechain-types/@openzeppelin/contracts/access/index.ts +5 -0
  25. package/typechain-types/@openzeppelin/contracts/index.ts +11 -0
  26. package/typechain-types/@openzeppelin/contracts/interfaces/IERC1967.ts +168 -0
  27. package/typechain-types/@openzeppelin/contracts/interfaces/IERC5267.ts +151 -0
  28. package/typechain-types/{contracts/tokens/CompliantERC20.sol/IComplianceChecker.ts → @openzeppelin/contracts/interfaces/draft-IERC1822.sol/IERC1822Proxiable.ts} +12 -17
  29. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC1822.sol/index.ts +4 -0
  30. package/typechain-types/@openzeppelin/contracts/interfaces/index.ts +7 -0
  31. package/typechain-types/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.ts +105 -0
  32. package/typechain-types/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.ts +69 -0
  33. package/typechain-types/@openzeppelin/contracts/proxy/ERC1967/index.ts +5 -0
  34. package/typechain-types/@openzeppelin/contracts/proxy/Proxy.ts +69 -0
  35. package/typechain-types/@openzeppelin/contracts/proxy/beacon/IBeacon.ts +90 -0
  36. package/typechain-types/@openzeppelin/contracts/proxy/beacon/index.ts +4 -0
  37. package/typechain-types/@openzeppelin/contracts/proxy/index.ts +8 -0
  38. package/typechain-types/@openzeppelin/contracts/utils/Address.ts +69 -0
  39. package/typechain-types/@openzeppelin/contracts/utils/Errors.ts +69 -0
  40. package/typechain-types/@openzeppelin/contracts/utils/Strings.ts +69 -0
  41. package/typechain-types/@openzeppelin/contracts/utils/cryptography/ECDSA.ts +69 -0
  42. package/typechain-types/@openzeppelin/contracts/utils/cryptography/index.ts +4 -0
  43. package/typechain-types/@openzeppelin/contracts/utils/index.ts +10 -0
  44. package/typechain-types/@openzeppelin/contracts/utils/math/SafeCast.ts +69 -0
  45. package/typechain-types/@openzeppelin/contracts/utils/math/index.ts +4 -0
  46. package/typechain-types/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.ts +251 -0
  47. package/typechain-types/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.ts +186 -0
  48. package/typechain-types/@openzeppelin/contracts-upgradeable/access/index.ts +5 -0
  49. package/typechain-types/@openzeppelin/contracts-upgradeable/index.ts +9 -0
  50. package/typechain-types/@openzeppelin/contracts-upgradeable/proxy/index.ts +5 -0
  51. package/typechain-types/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.ts +105 -0
  52. package/typechain-types/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.ts +196 -0
  53. package/typechain-types/@openzeppelin/contracts-upgradeable/proxy/utils/index.ts +5 -0
  54. package/typechain-types/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.ts +105 -0
  55. package/typechain-types/@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.ts +184 -0
  56. package/typechain-types/@openzeppelin/contracts-upgradeable/utils/cryptography/index.ts +4 -0
  57. package/typechain-types/@openzeppelin/contracts-upgradeable/utils/index.ts +6 -0
  58. package/typechain-types/@openzeppelin/index.ts +7 -0
  59. package/typechain-types/contracts/compliance/ComplianceRules.ts +18 -7
  60. package/typechain-types/contracts/core/IdentityRegistry.ts +493 -233
  61. package/typechain-types/contracts/index.ts +2 -0
  62. package/typechain-types/contracts/interfaces/IComplianceRules.ts +290 -0
  63. package/typechain-types/contracts/interfaces/IIdentityRegistry.ts +269 -341
  64. package/typechain-types/contracts/interfaces/index.ts +1 -0
  65. package/typechain-types/contracts/test/MockFacilitator.ts +187 -0
  66. package/typechain-types/contracts/test/index.ts +4 -0
  67. package/typechain-types/contracts/tokens/{CompliantERC20.sol/CompliantERC20.ts → CompliantERC20.ts} +19 -8
  68. package/typechain-types/contracts/tokens/index.ts +1 -2
  69. package/typechain-types/factories/@openzeppelin/contracts/access/Ownable2Step__factory.ts +138 -0
  70. package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +96 -0
  71. package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +5 -0
  72. package/typechain-types/factories/@openzeppelin/contracts/index.ts +7 -0
  73. package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC1967__factory.ts +67 -0
  74. package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC5267__factory.ts +71 -0
  75. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC1822.sol/IERC1822Proxiable__factory.ts +38 -0
  76. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC1822.sol/index.ts +4 -0
  77. package/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts +6 -0
  78. package/typechain-types/factories/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy__factory.ts +144 -0
  79. package/typechain-types/factories/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils__factory.ts +105 -0
  80. package/typechain-types/factories/@openzeppelin/contracts/proxy/ERC1967/index.ts +5 -0
  81. package/typechain-types/factories/@openzeppelin/contracts/proxy/Proxy__factory.ts +26 -0
  82. package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/IBeacon__factory.ts +35 -0
  83. package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/index.ts +4 -0
  84. package/typechain-types/factories/@openzeppelin/contracts/proxy/index.ts +6 -0
  85. package/typechain-types/factories/@openzeppelin/contracts/utils/Address__factory.ts +75 -0
  86. package/typechain-types/factories/@openzeppelin/contracts/utils/Errors__factory.ts +101 -0
  87. package/typechain-types/factories/@openzeppelin/contracts/utils/Strings__factory.ts +90 -0
  88. package/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/ECDSA__factory.ts +91 -0
  89. package/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/index.ts +4 -0
  90. package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +8 -0
  91. package/typechain-types/factories/@openzeppelin/contracts/utils/math/SafeCast__factory.ts +118 -0
  92. package/typechain-types/factories/@openzeppelin/contracts/utils/math/index.ts +4 -0
  93. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable__factory.ts +165 -0
  94. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable__factory.ts +122 -0
  95. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/access/index.ts +5 -0
  96. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/index.ts +6 -0
  97. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/proxy/index.ts +4 -0
  98. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable__factory.ts +48 -0
  99. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable__factory.ts +153 -0
  100. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/proxy/utils/index.ts +5 -0
  101. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable__factory.ts +48 -0
  102. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable__factory.ts +97 -0
  103. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/utils/cryptography/index.ts +4 -0
  104. package/typechain-types/factories/@openzeppelin/contracts-upgradeable/utils/index.ts +5 -0
  105. package/typechain-types/factories/@openzeppelin/index.ts +5 -0
  106. package/typechain-types/factories/contracts/compliance/ComplianceRules__factory.ts +26 -17
  107. package/typechain-types/factories/contracts/core/IdentityRegistry__factory.ts +493 -116
  108. package/typechain-types/factories/contracts/index.ts +1 -0
  109. package/typechain-types/factories/contracts/interfaces/IComplianceRules__factory.ts +193 -0
  110. package/typechain-types/factories/contracts/interfaces/IIdentityRegistry__factory.ts +236 -186
  111. package/typechain-types/factories/contracts/interfaces/index.ts +1 -0
  112. package/typechain-types/factories/contracts/test/MockFacilitator__factory.ts +194 -0
  113. package/typechain-types/factories/contracts/test/index.ts +4 -0
  114. package/typechain-types/factories/contracts/tokens/CompliantERC20__factory.ts +595 -0
  115. package/typechain-types/factories/contracts/tokens/index.ts +1 -1
  116. package/typechain-types/factories/index.ts +1 -0
  117. package/typechain-types/hardhat.d.ts +394 -16
  118. package/typechain-types/index.ts +48 -4
  119. package/deployments/hardhat/.chainId +0 -1
  120. package/typechain-types/contracts/tokens/CompliantERC20.sol/index.ts +0 -5
  121. package/typechain-types/factories/contracts/tokens/CompliantERC20.sol/CompliantERC20__factory.ts +0 -581
  122. package/typechain-types/factories/contracts/tokens/CompliantERC20.sol/IComplianceChecker__factory.ts +0 -44
  123. package/typechain-types/factories/contracts/tokens/CompliantERC20.sol/index.ts +0 -5
@@ -3,98 +3,24 @@ pragma solidity ^0.8.27;
3
3
 
4
4
  import {FHE, ebool} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
+ import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol";
6
7
  import {IIdentityRegistry} from "../interfaces/IIdentityRegistry.sol";
7
-
8
- /**
9
- * @title ComplianceRules
10
- * @author Gustavo Valverde
11
- * @notice Combines multiple compliance checks using FHE operations
12
- * @dev Part of zentity-fhevm-contracts - Builder Track
13
- *
14
- * @custom:category compliance
15
- * @custom:concept Combining encrypted compliance checks with FHE.and()
16
- * @custom:difficulty intermediate
17
- *
18
- * This contract aggregates compliance checks from IdentityRegistry and returns
19
- * encrypted boolean results. Consumer contracts (like CompliantERC20) can use
20
- * these results with FHE.select() for branch-free logic.
21
- *
22
- * Key patterns demonstrated:
23
- * 1. FHE.and() for combining multiple encrypted conditions
24
- * 2. Integration with IdentityRegistry
25
- * 3. Configurable compliance parameters
26
- * 4. Encrypted result caching
27
- */
28
- contract ComplianceRules is ZamaEthereumConfig {
29
- // ============ State ============
30
-
31
- /// @notice Reference to the identity registry
8
+ import {IComplianceRules} from "../interfaces/IComplianceRules.sol";
9
+
10
+ /// @title ComplianceRules
11
+ /// @author Gustavo Valverde
12
+ /// @notice Compliance aggregation contract combining registry checks via FHE.and()
13
+ /// @dev Not proxied can be redeployed independently. Delegates to the registry's
14
+ /// combined checkCompliance() for the standard case, and composes individual
15
+ /// checks for country-restricted scenarios.
16
+ contract ComplianceRules is IComplianceRules, Ownable2Step, ZamaEthereumConfig {
32
17
  IIdentityRegistry public immutable identityRegistry;
33
18
 
34
- /// @notice Owner/admin
35
- address public owner;
36
- /// @notice Pending owner for two-step ownership transfer
37
- address public pendingOwner;
38
-
39
- /// @notice Minimum compliance level required for compliance
40
19
  uint8 public minComplianceLevel;
41
20
 
42
- /// @notice Store last compliance check result for each user
43
21
  mapping(address user => ebool result) private complianceResults;
44
-
45
- /// @notice Authorized callers that can request compliance checks for others
46
22
  mapping(address caller => bool authorized) public authorizedCallers;
47
23
 
48
- // ============ Events ============
49
-
50
- /// @notice Emitted when the minimum compliance level requirement is updated
51
- /// @param newLevel The new minimum compliance level required for compliance
52
- event MinComplianceLevelUpdated(uint8 indexed newLevel);
53
-
54
- /// @notice Emitted when a compliance check is performed for a user
55
- /// @param user Address of the user whose compliance was checked
56
- event ComplianceChecked(address indexed user);
57
-
58
- /// @notice Emitted when a caller's authorization is updated
59
- /// @param caller Address being authorized or revoked
60
- /// @param allowed Whether the caller is allowed
61
- event AuthorizedCallerUpdated(address indexed caller, bool indexed allowed);
62
-
63
- /// @notice Emitted when ownership transfer is initiated
64
- /// @param currentOwner Current owner address
65
- /// @param pendingOwner Address that can accept ownership
66
- event OwnershipTransferStarted(address indexed currentOwner, address indexed pendingOwner);
67
-
68
- /// @notice Emitted when ownership transfer is completed
69
- /// @param previousOwner Previous owner address
70
- /// @param newOwner New owner address
71
- event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
72
-
73
- // ============ Errors ============
74
-
75
- /// @notice Thrown when caller is not the contract owner
76
- error OnlyOwner();
77
- /// @notice Thrown when caller is not the pending owner
78
- error OnlyPendingOwner();
79
- /// @notice Thrown when new owner is the zero address
80
- error InvalidOwner();
81
-
82
- /// @notice Thrown when registry address is zero
83
- error RegistryNotSet();
84
-
85
- /// @notice Thrown when caller is not authorized to check another user
86
- error CallerNotAuthorized();
87
-
88
- /// @notice Thrown when caller lacks permission for encrypted result
89
- error AccessProhibited();
90
-
91
- // ============ Modifiers ============
92
-
93
- modifier onlyOwner() {
94
- if (msg.sender != owner) revert OnlyOwner();
95
- _;
96
- }
97
-
98
24
  modifier onlyAuthorizedOrSelf(address user) {
99
25
  if (msg.sender != user && !authorizedCallers[msg.sender]) {
100
26
  revert CallerNotAuthorized();
@@ -102,154 +28,79 @@ contract ComplianceRules is ZamaEthereumConfig {
102
28
  _;
103
29
  }
104
30
 
105
- // ============ Constructor ============
106
-
107
- /**
108
- * @notice Initialize with identity registry reference
109
- * @param registry Address of the IdentityRegistry contract
110
- * @param initialMinComplianceLevel Initial minimum compliance level (default: 1)
111
- */
112
- constructor(address registry, uint8 initialMinComplianceLevel) {
113
- if (registry == address(0)) revert RegistryNotSet();
31
+ constructor(
32
+ address registry,
33
+ uint8 initialMinComplianceLevel
34
+ ) Ownable(msg.sender) {
35
+ if (registry == address(0)) revert CallerNotAuthorized();
114
36
  identityRegistry = IIdentityRegistry(registry);
115
- owner = msg.sender;
116
37
  minComplianceLevel = initialMinComplianceLevel;
117
38
  }
118
39
 
119
- // ============ Admin Functions ============
40
+ // ============ Admin ============
120
41
 
121
- /**
122
- * @notice Update minimum compliance level
123
- * @param newLevel New minimum level
124
- */
125
42
  function setMinComplianceLevel(uint8 newLevel) external onlyOwner {
126
43
  minComplianceLevel = newLevel;
127
44
  emit MinComplianceLevelUpdated(newLevel);
128
45
  }
129
46
 
130
- /**
131
- * @notice Allow or revoke a caller to check compliance for other users
132
- * @param caller Address to update
133
- * @param allowed Whether the caller is allowed
134
- */
135
47
  function setAuthorizedCaller(address caller, bool allowed) external onlyOwner {
136
48
  authorizedCallers[caller] = allowed;
137
49
  emit AuthorizedCallerUpdated(caller, allowed);
138
50
  }
139
51
 
140
- /**
141
- * @notice Initiate transfer of contract ownership
142
- * @param newOwner Address that can accept ownership
143
- */
144
- function transferOwnership(address newOwner) external onlyOwner {
145
- if (newOwner == address(0)) revert InvalidOwner();
146
- pendingOwner = newOwner;
147
- emit OwnershipTransferStarted(owner, newOwner);
148
- }
149
-
150
- /**
151
- * @notice Accept ownership transfer
152
- */
153
- function acceptOwnership() external {
154
- if (msg.sender != pendingOwner) revert OnlyPendingOwner();
155
- address previousOwner = owner;
156
- owner = pendingOwner;
157
- pendingOwner = address(0);
158
- emit OwnershipTransferred(previousOwner, owner);
159
- }
160
-
161
52
  // ============ Compliance Checks ============
162
53
 
163
- /**
164
- * @notice Check if user passes all compliance requirements
165
- * @dev Combines: hasMinComplianceLevel AND isNotBlacklisted
166
- * @param user Address to check
167
- * @return Encrypted boolean indicating compliance status
168
- *
169
- * Note: This function makes external calls to IdentityRegistry which
170
- * computes and stores verification results. The combined result is
171
- * stored locally for later retrieval.
172
- */
54
+ /// @inheritdoc IComplianceRules
173
55
  function checkCompliance(address user) external onlyAuthorizedOrSelf(user) returns (ebool) {
174
- // Check if user is attested
175
56
  if (!identityRegistry.isAttested(user)) {
176
- ebool notAttestedResult = FHE.asEbool(false);
177
- FHE.allowThis(notAttestedResult);
178
- FHE.allow(notAttestedResult, msg.sender);
179
- complianceResults[user] = notAttestedResult;
180
- return notAttestedResult;
57
+ return _storeResult(user, FHE.asEbool(false));
181
58
  }
182
59
 
183
- // Get individual compliance checks
184
- ebool hasCompliance = identityRegistry.hasMinComplianceLevel(user, minComplianceLevel);
185
- ebool notBlacklisted = identityRegistry.isNotBlacklisted(user);
60
+ // Delegate to registry's combined check (level + blacklist)
61
+ ebool result = identityRegistry.checkCompliance(user, minComplianceLevel);
186
62
 
187
- // Combine all conditions
188
- ebool result = FHE.and(hasCompliance, notBlacklisted);
189
-
190
- // Store and grant permissions
191
- complianceResults[user] = result;
192
- FHE.allowThis(result);
193
- FHE.allow(result, msg.sender);
194
-
195
- emit ComplianceChecked(user);
196
-
197
- return result;
63
+ return _storeResult(user, result);
198
64
  }
199
65
 
200
- /**
201
- * @notice Check compliance with additional country restriction
202
- * @param user Address to check
203
- * @param allowedCountry Country code that is allowed
204
- * @return Encrypted boolean indicating compliance status
205
- */
66
+ /// @inheritdoc IComplianceRules
206
67
  function checkComplianceWithCountry(
207
68
  address user,
208
69
  uint16 allowedCountry
209
70
  ) external onlyAuthorizedOrSelf(user) returns (ebool) {
210
- // Check if user is attested
211
71
  if (!identityRegistry.isAttested(user)) {
212
- ebool notAttestedResult = FHE.asEbool(false);
213
- FHE.allowThis(notAttestedResult);
214
- FHE.allow(notAttestedResult, msg.sender);
215
- return notAttestedResult;
72
+ return _storeResult(user, FHE.asEbool(false));
216
73
  }
217
74
 
218
- // Get individual compliance checks
219
- ebool hasCompliance = identityRegistry.hasMinComplianceLevel(user, minComplianceLevel);
220
- ebool notBlacklisted = identityRegistry.isNotBlacklisted(user);
75
+ // Combined level + blacklist check
76
+ ebool baseCompliance = identityRegistry.checkCompliance(user, minComplianceLevel);
77
+ // Additional country restriction
221
78
  ebool isFromAllowedCountry = identityRegistry.isFromCountry(user, allowedCountry);
222
79
 
223
- // Combine all conditions
224
- ebool result = FHE.and(FHE.and(hasCompliance, notBlacklisted), isFromAllowedCountry);
225
-
226
- // Grant permissions
227
- FHE.allowThis(result);
228
- FHE.allow(result, msg.sender);
229
-
230
- emit ComplianceChecked(user);
80
+ ebool result = FHE.and(baseCompliance, isFromAllowedCountry);
231
81
 
232
- return result;
82
+ return _storeResult(user, result);
233
83
  }
234
84
 
235
- /**
236
- * @notice Get the last compliance check result for a user
237
- * @dev Call checkCompliance first to compute and store the result
238
- * @param user Address to get result for
239
- * @return Encrypted boolean result
240
- */
85
+ /// @inheritdoc IComplianceRules
241
86
  function getComplianceResult(address user) external view returns (ebool) {
242
87
  ebool result = complianceResults[user];
243
88
  if (!FHE.isSenderAllowed(result)) revert AccessProhibited();
244
89
  return result;
245
90
  }
246
91
 
247
- /**
248
- * @notice Check if compliance result exists for user
249
- * @param user Address to check
250
- * @return Whether a cached result exists
251
- */
92
+ /// @inheritdoc IComplianceRules
252
93
  function hasComplianceResult(address user) external view returns (bool) {
253
94
  return FHE.isInitialized(complianceResults[user]);
254
95
  }
96
+
97
+ // ============ Internal ============
98
+
99
+ function _storeResult(address user, ebool result) internal returns (ebool) {
100
+ complianceResults[user] = result;
101
+ FHE.allowThis(result);
102
+ FHE.allow(result, msg.sender);
103
+ emit ComplianceChecked(user);
104
+ return result;
105
+ }
255
106
  }