@openzeppelin/confidential-contracts 0.2.0 → 0.3.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 (33) hide show
  1. package/build/contracts/Checkpoints.json +2 -2
  2. package/build/contracts/CheckpointsConfidential.json +2 -2
  3. package/build/contracts/{ConfidentialFungibleToken.json → ERC7984.json} +28 -33
  4. package/build/contracts/{ConfidentialFungibleTokenERC20Wrapper.json → ERC7984ERC20Wrapper.json} +34 -39
  5. package/build/contracts/ERC7984Freezable.json +666 -0
  6. package/build/contracts/ERC7984ObserverAccess.json +676 -0
  7. package/build/contracts/ERC7984Omnibus.json +994 -0
  8. package/build/contracts/ERC7984Restricted.json +677 -0
  9. package/build/contracts/ERC7984Rwa.json +1370 -0
  10. package/build/contracts/{ConfidentialFungibleTokenUtils.json → ERC7984Utils.json} +4 -4
  11. package/build/contracts/{ConfidentialFungibleTokenVotes.json → ERC7984Votes.json} +76 -81
  12. package/build/contracts/FHESafeMath.json +2 -2
  13. package/build/contracts/{IConfidentialFungibleToken.json → IERC7984.json} +15 -15
  14. package/build/contracts/{IConfidentialFungibleTokenReceiver.json → IERC7984Receiver.json} +2 -2
  15. package/build/contracts/IERC7984Rwa.json +797 -0
  16. package/build/contracts/VestingWalletConfidentialFactory.json +2 -2
  17. package/finance/VestingWalletConfidential.sol +6 -9
  18. package/finance/VestingWalletConfidentialFactory.sol +7 -12
  19. package/interfaces/{IConfidentialFungibleToken.sol → IERC7984.sol} +5 -5
  20. package/interfaces/{IConfidentialFungibleTokenReceiver.sol → IERC7984Receiver.sol} +3 -3
  21. package/interfaces/IERC7984Rwa.sol +64 -0
  22. package/package.json +4 -4
  23. package/token/{ConfidentialFungibleToken.sol → ERC7984/ERC7984.sol} +68 -76
  24. package/token/{extensions/ConfidentialFungibleTokenERC20Wrapper.sol → ERC7984/extensions/ERC7984ERC20Wrapper.sol} +18 -20
  25. package/token/ERC7984/extensions/ERC7984Freezable.sol +66 -0
  26. package/token/ERC7984/extensions/ERC7984ObserverAccess.sol +63 -0
  27. package/token/ERC7984/extensions/ERC7984Omnibus.sol +209 -0
  28. package/token/ERC7984/extensions/ERC7984Restricted.sol +118 -0
  29. package/token/ERC7984/extensions/ERC7984Rwa.sol +236 -0
  30. package/token/{extensions/ConfidentialFungibleTokenVotes.sol → ERC7984/extensions/ERC7984Votes.sol} +8 -14
  31. package/token/{utils/ConfidentialFungibleTokenUtils.sol → ERC7984/utils/ERC7984Utils.sol} +12 -12
  32. package/utils/FHESafeMath.sol +42 -7
  33. package/utils/structs/temporary-Checkpoints.sol +2 -2
@@ -0,0 +1,236 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // OpenZeppelin Confidential Contracts (last updated v0.3.0-rc.0) (token/ERC7984/extensions/ERC7984Rwa.sol)
3
+
4
+ pragma solidity ^0.8.27;
5
+
6
+ import {FHE, externalEuint64, euint64} from "@fhevm/solidity/lib/FHE.sol";
7
+ import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
8
+ import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
9
+ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
10
+ import {Multicall} from "@openzeppelin/contracts/utils/Multicall.sol";
11
+ import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
12
+ import {IERC7984} from "./../../../interfaces/IERC7984.sol";
13
+ import {IERC7984Rwa} from "./../../../interfaces/IERC7984Rwa.sol";
14
+ import {FHESafeMath} from "./../../../utils/FHESafeMath.sol";
15
+ import {ERC7984} from "./../ERC7984.sol";
16
+ import {ERC7984Freezable} from "./ERC7984Freezable.sol";
17
+ import {ERC7984Restricted} from "./ERC7984Restricted.sol";
18
+
19
+ /**
20
+ * @dev Extension of {ERC7984} that supports confidential Real World Assets (RWAs).
21
+ * This interface provides compliance checks, transfer controls and enforcement actions.
22
+ */
23
+ abstract contract ERC7984Rwa is
24
+ IERC7984Rwa,
25
+ ERC7984Freezable,
26
+ ERC7984Restricted,
27
+ Pausable,
28
+ Multicall,
29
+ ERC165,
30
+ AccessControl
31
+ {
32
+ bytes32 public constant AGENT_ROLE = keccak256("AGENT_ROLE");
33
+
34
+ /// @dev Checks if the sender is an admin.
35
+ modifier onlyAdmin() {
36
+ _checkRole(DEFAULT_ADMIN_ROLE);
37
+ _;
38
+ }
39
+
40
+ /// @dev Checks if the sender is an agent.
41
+ modifier onlyAgent() {
42
+ _checkRole(AGENT_ROLE);
43
+ _;
44
+ }
45
+
46
+ constructor(address admin) {
47
+ _grantRole(DEFAULT_ADMIN_ROLE, admin);
48
+ }
49
+
50
+ /// @inheritdoc ERC165
51
+ function supportsInterface(
52
+ bytes4 interfaceId
53
+ ) public view virtual override(IERC165, ERC165, AccessControl) returns (bool) {
54
+ return
55
+ interfaceId == type(IERC7984Rwa).interfaceId ||
56
+ interfaceId == type(IERC7984).interfaceId ||
57
+ super.supportsInterface(interfaceId);
58
+ }
59
+
60
+ /// @dev Returns true if has admin role, false otherwise.
61
+ function isAdmin(address account) public view virtual returns (bool) {
62
+ return hasRole(DEFAULT_ADMIN_ROLE, account);
63
+ }
64
+
65
+ /// @dev Returns true if agent, false otherwise.
66
+ function isAgent(address account) public view virtual returns (bool) {
67
+ return hasRole(AGENT_ROLE, account);
68
+ }
69
+
70
+ /// @dev Adds agent.
71
+ function addAgent(address account) public virtual onlyAdmin {
72
+ _grantRole(AGENT_ROLE, account);
73
+ }
74
+
75
+ /// @dev Removes agent.
76
+ function removeAgent(address account) public virtual onlyAdmin {
77
+ _revokeRole(AGENT_ROLE, account);
78
+ }
79
+
80
+ /// @dev Pauses contract.
81
+ function pause() public virtual onlyAgent {
82
+ _pause();
83
+ }
84
+
85
+ /// @dev Unpauses contract.
86
+ function unpause() public virtual onlyAgent {
87
+ _unpause();
88
+ }
89
+
90
+ /// @dev Blocks a user account.
91
+ function blockUser(address account) public virtual onlyAgent {
92
+ _blockUser(account);
93
+ }
94
+
95
+ /// @dev Unblocks a user account.
96
+ function unblockUser(address account) public virtual onlyAgent {
97
+ _allowUser(account);
98
+ }
99
+
100
+ /// @dev Sets confidential frozen for an account.
101
+ function setConfidentialFrozen(
102
+ address account,
103
+ externalEuint64 encryptedAmount,
104
+ bytes calldata inputProof
105
+ ) public virtual onlyAgent {
106
+ _setConfidentialFrozen(account, FHE.fromExternal(encryptedAmount, inputProof));
107
+ }
108
+
109
+ /// @dev Sets confidential frozen for an account with proof.
110
+ function setConfidentialFrozen(address account, euint64 encryptedAmount) public virtual onlyAgent {
111
+ require(
112
+ FHE.isAllowed(encryptedAmount, msg.sender),
113
+ ERC7984UnauthorizedUseOfEncryptedAmount(encryptedAmount, msg.sender)
114
+ );
115
+ _setConfidentialFrozen(account, encryptedAmount);
116
+ }
117
+
118
+ /// @dev Mints confidential amount of tokens to account with proof.
119
+ function confidentialMint(
120
+ address to,
121
+ externalEuint64 encryptedAmount,
122
+ bytes calldata inputProof
123
+ ) public virtual onlyAgent returns (euint64) {
124
+ return _mint(to, FHE.fromExternal(encryptedAmount, inputProof));
125
+ }
126
+
127
+ /// @dev Mints confidential amount of tokens to account.
128
+ function confidentialMint(address to, euint64 encryptedAmount) public virtual onlyAgent returns (euint64) {
129
+ require(
130
+ FHE.isAllowed(encryptedAmount, msg.sender),
131
+ ERC7984UnauthorizedUseOfEncryptedAmount(encryptedAmount, msg.sender)
132
+ );
133
+ return _mint(to, encryptedAmount);
134
+ }
135
+
136
+ /// @dev Burns confidential amount of tokens from account with proof.
137
+ function confidentialBurn(
138
+ address account,
139
+ externalEuint64 encryptedAmount,
140
+ bytes calldata inputProof
141
+ ) public virtual onlyAgent returns (euint64) {
142
+ return _burn(account, FHE.fromExternal(encryptedAmount, inputProof));
143
+ }
144
+
145
+ /// @dev Burns confidential amount of tokens from account.
146
+ function confidentialBurn(address account, euint64 encryptedAmount) public virtual onlyAgent returns (euint64) {
147
+ require(
148
+ FHE.isAllowed(encryptedAmount, msg.sender),
149
+ ERC7984UnauthorizedUseOfEncryptedAmount(encryptedAmount, msg.sender)
150
+ );
151
+ return _burn(account, encryptedAmount);
152
+ }
153
+
154
+ /// @dev Forces transfer of confidential amount of tokens from account to account with proof by skipping compliance checks.
155
+ function forceConfidentialTransferFrom(
156
+ address from,
157
+ address to,
158
+ externalEuint64 encryptedAmount,
159
+ bytes calldata inputProof
160
+ ) public virtual onlyAgent returns (euint64) {
161
+ return _forceUpdate(from, to, FHE.fromExternal(encryptedAmount, inputProof));
162
+ }
163
+
164
+ /// @dev Forces transfer of confidential amount of tokens from account to account by skipping compliance checks.
165
+ function forceConfidentialTransferFrom(
166
+ address from,
167
+ address to,
168
+ euint64 encryptedAmount
169
+ ) public virtual onlyAgent returns (euint64 transferred) {
170
+ require(
171
+ FHE.isAllowed(encryptedAmount, msg.sender),
172
+ ERC7984UnauthorizedUseOfEncryptedAmount(encryptedAmount, msg.sender)
173
+ );
174
+ return _forceUpdate(from, to, encryptedAmount);
175
+ }
176
+
177
+ /// @inheritdoc ERC7984Freezable
178
+ function confidentialAvailable(
179
+ address account
180
+ ) public virtual override(IERC7984Rwa, ERC7984Freezable) returns (euint64) {
181
+ return super.confidentialAvailable(account);
182
+ }
183
+
184
+ /// @inheritdoc ERC7984Freezable
185
+ function confidentialFrozen(
186
+ address account
187
+ ) public view virtual override(IERC7984Rwa, ERC7984Freezable) returns (euint64) {
188
+ return super.confidentialFrozen(account);
189
+ }
190
+
191
+ /// @inheritdoc Pausable
192
+ function paused() public view virtual override(IERC7984Rwa, Pausable) returns (bool) {
193
+ return super.paused();
194
+ }
195
+
196
+ /// @inheritdoc ERC7984Restricted
197
+ function isUserAllowed(
198
+ address account
199
+ ) public view virtual override(IERC7984Rwa, ERC7984Restricted) returns (bool) {
200
+ return super.isUserAllowed(account);
201
+ }
202
+
203
+ /// @dev Internal function which updates confidential balances while performing frozen and restriction compliance checks.
204
+ function _update(
205
+ address from,
206
+ address to,
207
+ euint64 encryptedAmount
208
+ ) internal virtual override(ERC7984Freezable, ERC7984Restricted) whenNotPaused returns (euint64) {
209
+ // frozen and restriction checks performed through inheritance
210
+ return super._update(from, to, encryptedAmount);
211
+ }
212
+
213
+ /// @dev Internal function which forces transfer of confidential amount of tokens from account to account by skipping compliance checks.
214
+ function _forceUpdate(address from, address to, euint64 encryptedAmount) internal virtual returns (euint64) {
215
+ // bypassing `from` restriction check with {_checkSenderRestriction}. Still performing `to` restriction check.
216
+ // bypassing paused state by directly calling `super._update`
217
+ return super._update(from, to, encryptedAmount);
218
+ }
219
+
220
+ /**
221
+ * @dev Bypasses the `from` restriction check when performing a {forceConfidentialTransferFrom}.
222
+ */
223
+ function _checkSenderRestriction(address account) internal view override {
224
+ if (_isForceTransfer()) {
225
+ return;
226
+ }
227
+ super._checkSenderRestriction(account);
228
+ }
229
+
230
+ /// @dev Private function which checks if the called function is a {forceConfidentialTransferFrom}.
231
+ function _isForceTransfer() private pure returns (bool) {
232
+ return
233
+ msg.sig == 0x6c9c3c85 || // bytes4(keccak256("forceConfidentialTransferFrom(address,address,bytes32)"))
234
+ msg.sig == 0x44fd6e40; // bytes4(keccak256("forceConfidentialTransferFrom(address,address,bytes32,bytes)"))
235
+ }
236
+ }
@@ -1,27 +1,21 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0) (token/extensions/ConfidentialFungibleTokenVotes.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.3.0-rc.0) (token/ERC7984/extensions/ERC7984Votes.sol)
3
3
  pragma solidity ^0.8.27;
4
4
 
5
5
  import {euint64} from "@fhevm/solidity/lib/FHE.sol";
6
- import {VotesConfidential} from "./../../governance/utils/VotesConfidential.sol";
7
- import {ConfidentialFungibleToken} from "./../ConfidentialFungibleToken.sol";
6
+ import {VotesConfidential} from "../../../governance/utils/VotesConfidential.sol";
7
+ import {ERC7984} from "./../ERC7984.sol";
8
8
 
9
9
  /**
10
- * @dev Extension of {ConfidentialFungibleToken} supporting confidential votes tracking and delegation.
10
+ * @dev Extension of {ERC7984} supporting confidential votes tracking and delegation.
11
11
  *
12
- * The amount of confidential voting units an account has is equal to the confidential token balance of
12
+ * The amount of confidential voting units an account has is equal to the balance of
13
13
  * that account. Voing power is taken into account when an account delegates votes to itself or to another
14
14
  * account.
15
15
  */
16
- abstract contract ConfidentialFungibleTokenVotes is ConfidentialFungibleToken, VotesConfidential {
17
- /// @inheritdoc ConfidentialFungibleToken
18
- function confidentialTotalSupply()
19
- public
20
- view
21
- virtual
22
- override(VotesConfidential, ConfidentialFungibleToken)
23
- returns (euint64)
24
- {
16
+ abstract contract ERC7984Votes is ERC7984, VotesConfidential {
17
+ /// @inheritdoc ERC7984
18
+ function confidentialTotalSupply() public view virtual override(VotesConfidential, ERC7984) returns (euint64) {
25
19
  return super.confidentialTotalSupply();
26
20
  }
27
21
 
@@ -1,21 +1,21 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0) (token/utils/ConfidentialFungibleTokenUtils.sol)
3
- pragma solidity ^0.8.24;
2
+ // OpenZeppelin Confidential Contracts (last updated v0.3.0-rc.0) (token/ERC7984/utils/ERC7984Utils.sol)
3
+ pragma solidity ^0.8.27;
4
4
 
5
5
  import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
6
6
 
7
- import {IConfidentialFungibleTokenReceiver} from "../../interfaces/IConfidentialFungibleTokenReceiver.sol";
8
- import {ConfidentialFungibleToken} from "../ConfidentialFungibleToken.sol";
7
+ import {IERC7984Receiver} from "../../../interfaces/IERC7984Receiver.sol";
8
+ import {ERC7984} from "../ERC7984.sol";
9
9
 
10
- /// @dev Library that provides common {ConfidentialFungibleToken} utility functions.
11
- library ConfidentialFungibleTokenUtils {
10
+ /// @dev Library that provides common {ERC7984} utility functions.
11
+ library ERC7984Utils {
12
12
  /**
13
13
  * @dev Performs a transfer callback to the recipient of the transfer `to`. Should be invoked
14
- * after all transfers "withCallback" on a {ConfidentialFungibleToken}.
14
+ * after all transfers "withCallback" on a {ERC7984}.
15
15
  *
16
16
  * The transfer callback is not invoked on the recipient if the recipient has no code (i.e. is an EOA). If the
17
17
  * recipient has non-zero code, it must implement
18
- * {IConfidentialFungibleTokenReceiver-onConfidentialTransferReceived} and return an `ebool` indicating
18
+ * {IERC7984Receiver-onConfidentialTransferReceived} and return an `ebool` indicating
19
19
  * whether the transfer was accepted or not. If the `ebool` is `false`, the transfer will be reversed.
20
20
  */
21
21
  function checkOnTransferReceived(
@@ -26,13 +26,13 @@ library ConfidentialFungibleTokenUtils {
26
26
  bytes calldata data
27
27
  ) internal returns (ebool) {
28
28
  if (to.code.length > 0) {
29
- try
30
- IConfidentialFungibleTokenReceiver(to).onConfidentialTransferReceived(operator, from, amount, data)
31
- returns (ebool retval) {
29
+ try IERC7984Receiver(to).onConfidentialTransferReceived(operator, from, amount, data) returns (
30
+ ebool retval
31
+ ) {
32
32
  return retval;
33
33
  } catch (bytes memory reason) {
34
34
  if (reason.length == 0) {
35
- revert ConfidentialFungibleToken.ConfidentialFungibleTokenInvalidReceiver(to);
35
+ revert ERC7984.ERC7984InvalidReceiver(to);
36
36
  } else {
37
37
  assembly ("memory-safe") {
38
38
  revert(add(32, reason), mload(reason))
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0) (utils/FHESafeMath.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.3.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";
@@ -16,13 +16,11 @@ library FHESafeMath {
16
16
  */
17
17
  function tryIncrease(euint64 oldValue, euint64 delta) internal returns (ebool success, euint64 updated) {
18
18
  if (!FHE.isInitialized(oldValue)) {
19
- success = FHE.asEbool(true);
20
- updated = delta;
21
- } else {
22
- euint64 newValue = FHE.add(oldValue, delta);
23
- success = FHE.ge(newValue, oldValue);
24
- updated = FHE.select(success, newValue, oldValue);
19
+ return (FHE.asEbool(true), delta);
25
20
  }
21
+ euint64 newValue = FHE.add(oldValue, delta);
22
+ success = FHE.ge(newValue, oldValue);
23
+ updated = FHE.select(success, newValue, oldValue);
26
24
  }
27
25
 
28
26
  /**
@@ -31,7 +29,44 @@ library FHESafeMath {
31
29
  * and `updated` will be the original value.
32
30
  */
33
31
  function tryDecrease(euint64 oldValue, euint64 delta) internal returns (ebool success, euint64 updated) {
32
+ if (!FHE.isInitialized(oldValue)) {
33
+ if (!FHE.isInitialized(delta)) {
34
+ return (FHE.asEbool(true), oldValue);
35
+ }
36
+ return (FHE.eq(oldValue, delta), oldValue);
37
+ }
34
38
  success = FHE.ge(oldValue, delta);
35
39
  updated = FHE.select(success, FHE.sub(oldValue, delta), oldValue);
36
40
  }
41
+
42
+ /**
43
+ * @dev Try to add `a` and `b`. If the operation is successful, `success` will be true and `res`
44
+ * will be the sum of `a` and `b`. Otherwise, `success` will be false, and `res` will be 0.
45
+ */
46
+ function tryAdd(euint64 a, euint64 b) internal returns (ebool success, euint64 res) {
47
+ if (!FHE.isInitialized(a)) {
48
+ return (FHE.asEbool(true), b);
49
+ }
50
+ if (!FHE.isInitialized(b)) {
51
+ return (FHE.asEbool(true), a);
52
+ }
53
+
54
+ euint64 sum = FHE.add(a, b);
55
+ success = FHE.ge(sum, a);
56
+ res = FHE.select(success, sum, FHE.asEuint64(0));
57
+ }
58
+
59
+ /**
60
+ * @dev Try to subtract `b` from `a`. If the operation is successful, `success` will be true and `res`
61
+ * will be `a - b`. Otherwise, `success` will be false, and `res` will be 0.
62
+ */
63
+ function trySub(euint64 a, euint64 b) internal returns (ebool success, euint64 res) {
64
+ if (!FHE.isInitialized(b)) {
65
+ return (FHE.asEbool(true), a);
66
+ }
67
+
68
+ euint64 difference = FHE.sub(a, b);
69
+ success = FHE.le(difference, a);
70
+ res = FHE.select(success, difference, FHE.asEuint64(0));
71
+ }
37
72
  }
@@ -1,6 +1,6 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0) (utils/structs/temporary-Checkpoints.sol)
3
- // OpenZeppelin Contracts (last updated v5.3.0) (utils/structs/Checkpoints.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.3.0-rc.0) (utils/structs/temporary-Checkpoints.sol)
3
+ // OpenZeppelin Contracts (last updated v5.4.0) (utils/structs/Checkpoints.sol)
4
4
  // This file was procedurally generated from scripts/generate/templates/Checkpoints.js.
5
5
  // WARNING: This file is temporary and will be deleted once the latest version of the file is released in v5.5.0 of @openzeppelin/contracts.
6
6