@openzeppelin/confidential-contracts 0.4.0 → 0.5.0-rc.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.
Files changed (39) hide show
  1. package/build/contracts/BatcherConfidential.json +5 -0
  2. package/build/contracts/CheckpointsConfidential.json +2 -2
  3. package/build/contracts/ERC7984.json +6 -28
  4. package/build/contracts/ERC7984BalanceCapHookModule.json +277 -0
  5. package/build/contracts/ERC7984ERC20Wrapper.json +6 -28
  6. package/build/contracts/ERC7984Freezable.json +6 -28
  7. package/build/contracts/ERC7984HolderCapHookModule.json +291 -0
  8. package/build/contracts/ERC7984HookModule.json +200 -0
  9. package/build/contracts/ERC7984Hooked.json +832 -0
  10. package/build/contracts/ERC7984IdentityCheck.json +691 -0
  11. package/build/contracts/ERC7984ObserverAccess.json +6 -28
  12. package/build/contracts/ERC7984Omnibus.json +6 -28
  13. package/build/contracts/ERC7984Restricted.json +6 -28
  14. package/build/contracts/ERC7984Rwa.json +61 -29
  15. package/build/contracts/ERC7984Utils.json +2 -2
  16. package/build/contracts/ERC7984Votes.json +6 -28
  17. package/build/contracts/FHESafeMath.json +2 -2
  18. package/build/contracts/IERC7984HookModule.json +151 -0
  19. package/build/contracts/IERC7984Rwa.json +87 -0
  20. package/build/contracts/IIdentityRegistry.json +30 -0
  21. package/finance/BatcherConfidential.sol +7 -3
  22. package/governance/utils/VotesConfidential.sol +2 -2
  23. package/interfaces/IERC7984HookModule.sol +39 -0
  24. package/interfaces/IERC7984Receiver.sol +3 -1
  25. package/interfaces/IERC7984Rwa.sol +28 -1
  26. package/package.json +1 -1
  27. package/token/ERC7984/ERC7984.sol +39 -28
  28. package/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol +3 -3
  29. package/token/ERC7984/extensions/ERC7984Freezable.sol +3 -7
  30. package/token/ERC7984/extensions/ERC7984Hooked.sol +158 -0
  31. package/token/ERC7984/extensions/ERC7984IdentityCheck.sol +58 -0
  32. package/token/ERC7984/extensions/ERC7984Restricted.sol +3 -3
  33. package/token/ERC7984/extensions/ERC7984Rwa.sol +65 -28
  34. package/token/ERC7984/utils/ERC7984BalanceCapHookModule.sol +92 -0
  35. package/token/ERC7984/utils/ERC7984HolderCapHookModule.sol +145 -0
  36. package/token/ERC7984/utils/ERC7984HookModule.sol +170 -0
  37. package/utils/FHESafeMath.sol +26 -1
  38. package/utils/HandleAccessManager.sol +5 -3
  39. package/utils/structs/CheckpointsConfidential.sol +1 -2
@@ -0,0 +1,170 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (token/ERC7984/utils/ERC7984HookModule.sol)
3
+
4
+ pragma solidity ^0.8.27;
5
+
6
+ import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
7
+ import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
8
+ import {IERC7984HookModule} from "./../../../interfaces/IERC7984HookModule.sol";
9
+ import {HandleAccessManager} from "./../../../utils/HandleAccessManager.sol";
10
+
11
+ /**
12
+ * @dev An abstract base contract for building ERC-7984 hook modules. Compatible with {ERC7984Hooked}.
13
+ */
14
+ abstract contract ERC7984HookModule is IERC7984HookModule, ERC165 {
15
+ /// @dev The caller `account` is not authorized to perform the operation.
16
+ error ERC7984HookModuleUnauthorizedAccount(address account);
17
+
18
+ /// @dev The caller `user` does not have access to the encrypted amount `amount`.
19
+ error ERC7984HookModuleUnauthorizedUseOfEncryptedAmount(euint64 amount, address user);
20
+
21
+ /// @dev The module is already installed for the given token.
22
+ error ERC7984HookModuleAlreadyInstalled(address token);
23
+
24
+ /// @dev The module is not installed for the given token.
25
+ error ERC7984HookModuleNotInstalled(address token);
26
+
27
+ mapping(address token => bool) private _installed;
28
+
29
+ /// @inheritdoc IERC7984HookModule
30
+ function preTransfer(address from, address to, euint64 encryptedAmount) public virtual returns (ebool) {
31
+ require(
32
+ FHE.isAllowed(encryptedAmount, msg.sender),
33
+ ERC7984HookModuleUnauthorizedUseOfEncryptedAmount(encryptedAmount, msg.sender)
34
+ );
35
+ ebool compliant = _preTransfer(msg.sender, from, to, encryptedAmount);
36
+ FHE.allowTransient(compliant, msg.sender);
37
+ return compliant;
38
+ }
39
+
40
+ /// @inheritdoc IERC7984HookModule
41
+ function postTransfer(address from, address to, euint64 encryptedAmount) public virtual {
42
+ require(
43
+ FHE.isAllowed(encryptedAmount, msg.sender),
44
+ ERC7984HookModuleUnauthorizedUseOfEncryptedAmount(encryptedAmount, msg.sender)
45
+ );
46
+ _postTransfer(msg.sender, from, to, encryptedAmount);
47
+ }
48
+
49
+ /// @inheritdoc IERC7984HookModule
50
+ function onInstall(bytes calldata initData) public virtual {
51
+ require(!_isModuleInstalled(msg.sender), ERC7984HookModuleAlreadyInstalled(msg.sender));
52
+
53
+ _onInstall(msg.sender, initData);
54
+ }
55
+
56
+ /// @inheritdoc IERC7984HookModule
57
+ function onUninstall(bytes calldata deinitData) public virtual {
58
+ require(_isModuleInstalled(msg.sender), ERC7984HookModuleNotInstalled(msg.sender));
59
+
60
+ _onUninstall(msg.sender, deinitData);
61
+ }
62
+
63
+ /// @inheritdoc ERC165
64
+ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
65
+ return interfaceId == type(IERC7984HookModule).interfaceId || super.supportsInterface(interfaceId);
66
+ }
67
+
68
+ /**
69
+ * @dev Internal function which may be overridden by the derived contract to perform actions
70
+ * when the module is installed.
71
+ */
72
+ function _onInstall(address token, bytes calldata /* initData */) internal virtual {
73
+ _installed[token] = true;
74
+ }
75
+
76
+ /**
77
+ * @dev Internal function which may be overridden by the derived contract to perform actions
78
+ * when the module is uninstalled.
79
+ */
80
+ function _onUninstall(address token, bytes calldata /* deinitData */) internal virtual {
81
+ delete _installed[token];
82
+ }
83
+
84
+ /**
85
+ * @dev Internal function which runs before a transfer. Transient access is already granted to the module
86
+ * for `encryptedAmount`. If additional handle access is needed from the token, call {_getTokenHandleAllowance}.
87
+ *
88
+ * NOTE: ACL allowance on `encryptedAmount` is already checked for `msg.sender` in {preTransfer}.
89
+ */
90
+ function _preTransfer(
91
+ address /* token */,
92
+ address /* from */,
93
+ address /* to */,
94
+ euint64 /* encryptedAmount */
95
+ ) internal virtual returns (ebool) {
96
+ return FHE.asEbool(true);
97
+ }
98
+
99
+ /**
100
+ * @dev Internal function which performs operations after transfers. Transient access is already granted to the module
101
+ * for `encryptedAmount`. If additional handle access is needed from the token, call {_getTokenHandleAllowance}.
102
+ *
103
+ * NOTE: ACL allowance on `encryptedAmount` is already checked for `msg.sender` in {postTransfer}.
104
+ */
105
+ function _postTransfer(
106
+ address /*token*/,
107
+ address /*from*/,
108
+ address /*to*/,
109
+ euint64 /*encryptedAmount*/
110
+ ) internal virtual {
111
+ // default to no-op
112
+ }
113
+
114
+ /**
115
+ * @dev Check if the module is installed for the given token. The default implementation reads from
116
+ * an internal storage flag maintained by {onInstall} and {onUninstall}. Derived contracts may override
117
+ * to extend the check, but should typically rely on the default behavior.
118
+ *
119
+ * NOTE: This function should use internal storage to check if the module is installed for the given token.
120
+ * Do not use external storage like {ERC7984Hooked-isModuleInstalled}.
121
+ */
122
+ function _isModuleInstalled(address token) internal view virtual returns (bool) {
123
+ return _installed[token];
124
+ }
125
+
126
+ /// @dev Allow modules to get access to token handles during transaction.
127
+ function _getTokenHandleAllowance(address token, euint64 handle) internal virtual {
128
+ _getTokenHandleAllowance(token, handle, false);
129
+ }
130
+
131
+ /// @dev Allow modules to get access to token handles.
132
+ function _getTokenHandleAllowance(address token, euint64 handle, bool persistent) internal virtual {
133
+ if (FHE.isInitialized(handle)) {
134
+ HandleAccessManager(token).getHandleAllowance(euint64.unwrap(handle), address(this), persistent);
135
+ }
136
+ }
137
+
138
+ /**
139
+ * @dev Optionally emit the result of the pre-transfer hook.
140
+ *
141
+ * Grants persistent ACL on `compliant` to both this contract and `from`.
142
+ */
143
+ function _emitPreTransferResults(
144
+ address token,
145
+ address from,
146
+ address to,
147
+ euint64 encryptedAmount,
148
+ ebool compliant,
149
+ bytes32 context
150
+ ) internal virtual {
151
+ if (FHE.isInitialized(compliant)) {
152
+ if (from != address(0)) {
153
+ FHE.allowThis(compliant);
154
+ FHE.allow(compliant, from);
155
+ }
156
+ }
157
+ emit ERC7984HookModuleResult(token, from, to, encryptedAmount, compliant, context);
158
+ }
159
+
160
+ /**
161
+ * @dev Get transient ACL allowance for the given handle from a contract that inherits {HandleAccessManager}.
162
+ *
163
+ * Additionally verifies that the token is authorized to access the handle.
164
+ */
165
+ function _accessHandle(address token, euint64 handle) internal {
166
+ if (!FHE.isInitialized(handle)) return;
167
+ require(FHE.isAllowed(handle, token), ERC7984HookModuleUnauthorizedUseOfEncryptedAmount(handle, token));
168
+ _getTokenHandleAllowance(token, handle, false);
169
+ }
170
+ }
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.4.0) (utils/FHESafeMath.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (utils/FHESafeMath.sol)
3
3
  pragma solidity ^0.8.24;
4
4
 
5
5
  import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
@@ -72,4 +72,29 @@ library FHESafeMath {
72
72
  success = FHE.le(difference, a);
73
73
  res = FHE.select(success, difference, FHE.asEuint64(0));
74
74
  }
75
+
76
+ /**
77
+ * @dev Add `a` and `b` saturating at `type(uint64).max` on overflow. The returned value is the sum
78
+ * of `a` and `b` if it does not overflow, otherwise `type(uint64).max`.
79
+ */
80
+ function saturatingAdd(euint64 a, euint64 b) internal returns (euint64) {
81
+ if (!FHE.isInitialized(a)) {
82
+ return b;
83
+ }
84
+ if (!FHE.isInitialized(b)) {
85
+ return a;
86
+ }
87
+
88
+ euint64 sum = FHE.add(a, b);
89
+ return FHE.select(FHE.ge(sum, a), sum, FHE.asEuint64(type(uint64).max));
90
+ }
91
+
92
+ /**
93
+ * @dev Subtract `b` from `a` saturating at zero on underflow. The returned value is `a - b` if
94
+ * `a >= b`, otherwise 0.
95
+ */
96
+ function saturatingSub(euint64 a, euint64 b) internal returns (euint64) {
97
+ euint64 minB = FHE.min(a, b);
98
+ return FHE.sub(a, minB);
99
+ }
75
100
  }
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.4.0) (utils/HandleAccessManager.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (utils/HandleAccessManager.sol)
3
3
  pragma solidity ^0.8.26;
4
4
 
5
5
  import {Impl} from "@fhevm/solidity/lib/Impl.sol";
@@ -23,8 +23,10 @@ abstract contract HandleAccessManager {
23
23
  }
24
24
 
25
25
  /**
26
- * @dev Unimplemented function that must return true if the message sender is allowed to call
26
+ * @dev Validation function that must return true if the message sender is allowed to call
27
27
  * {getHandleAllowance} for the given handle.
28
28
  */
29
- function _validateHandleAllowance(bytes32 handle) internal view virtual returns (bool);
29
+ function _validateHandleAllowance(bytes32) internal view virtual returns (bool) {
30
+ return false;
31
+ }
30
32
  }
@@ -1,11 +1,10 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.4.0) (utils/structs/CheckpointsConfidential.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.5.0-rc.0) (utils/structs/CheckpointsConfidential.sol)
3
3
  // This file was procedurally generated from scripts/generate/templates/CheckpointsConfidential.js.
4
4
 
5
5
  pragma solidity ^0.8.24;
6
6
 
7
7
  import {euint32, euint64} from "@fhevm/solidity/lib/FHE.sol";
8
- import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
9
8
  import {Checkpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol";
10
9
 
11
10
  /**