@openzeppelin/confidential-contracts 0.2.0-rc.1 → 0.2.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 (29) hide show
  1. package/build/contracts/Checkpoints.json +2 -2
  2. package/build/contracts/CheckpointsConfidential.json +3 -9
  3. package/build/contracts/ConfidentialFungibleTokenUtils.json +2 -2
  4. package/build/contracts/ConfidentialFungibleTokenVotes.json +23 -0
  5. package/build/contracts/{TFHESafeMath.json → FHESafeMath.json} +4 -4
  6. package/build/contracts/HandleAccessManager.json +34 -0
  7. package/build/contracts/VestingWalletCliffConfidential.json +3 -3
  8. package/build/contracts/VestingWalletConfidential.json +3 -3
  9. package/build/contracts/VestingWalletConfidentialFactory.json +155 -0
  10. package/build/contracts/VotesConfidential.json +23 -0
  11. package/finance/ERC7821WithExecutor.sol +2 -2
  12. package/finance/VestingWalletCliffConfidential.sol +15 -4
  13. package/finance/VestingWalletConfidential.sol +28 -13
  14. package/finance/VestingWalletConfidentialFactory.sol +120 -0
  15. package/governance/utils/VotesConfidential.sol +18 -4
  16. package/interfaces/IConfidentialFungibleToken.sol +2 -2
  17. package/interfaces/IConfidentialFungibleTokenReceiver.sol +1 -1
  18. package/package.json +1 -1
  19. package/token/ConfidentialFungibleToken.sol +9 -12
  20. package/token/extensions/ConfidentialFungibleTokenERC20Wrapper.sol +19 -8
  21. package/token/extensions/ConfidentialFungibleTokenVotes.sol +9 -1
  22. package/token/utils/ConfidentialFungibleTokenUtils.sol +1 -1
  23. package/utils/{TFHESafeMath.sol → FHESafeMath.sol} +2 -2
  24. package/utils/HandleAccessManager.sol +29 -0
  25. package/utils/structs/CheckpointsConfidential.sol +1 -6
  26. package/utils/structs/temporary-Checkpoints.sol +1 -1
  27. package/build/contracts/VestingWalletCliffExecutorConfidential.json +0 -424
  28. package/build/contracts/VestingWalletCliffExecutorConfidentialFactory.json +0 -290
  29. package/finance/VestingWalletCliffExecutorConfidentialFactory.sol +0 -203
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (governance/utils/VotesConfidential.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (governance/utils/VotesConfidential.sol)
3
3
  pragma solidity ^0.8.24;
4
4
 
5
5
  import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
@@ -9,9 +9,25 @@ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
9
9
  import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
10
10
  import {Nonces} from "@openzeppelin/contracts/utils/Nonces.sol";
11
11
  import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
12
+ import {HandleAccessManager} from "./../../utils/HandleAccessManager.sol";
12
13
  import {CheckpointsConfidential} from "./../../utils/structs/CheckpointsConfidential.sol";
13
14
 
14
- abstract contract VotesConfidential is Nonces, EIP712, IERC6372 {
15
+ /**
16
+ * @dev A confidential votes contract tracking confidential voting power of accounts over time.
17
+ * It features vote delegation to delegators.
18
+
19
+ * This contract keeps a history (checkpoints) of each account's confidential vote power. Confidential
20
+ * voting power can be delegated either by calling the {delegate} function directly, or by providing
21
+ * a signature to be used with {delegateBySig}. Confidential voting power handles can be queried
22
+ * through the public accessors {getVotes} and {getPastVotes} but can only be decrypted by accounts
23
+ * allowed to access them. Ensure that {HandleAccessManager-_validateHandleAllowance} is implemented properly, allowing all
24
+ * necessary addresses to access voting power handles.
25
+ *
26
+ * By default, voting units does not account for voting power. This makes transfers of underlying
27
+ * voting units cheaper. The downside is that it requires users to delegate to themselves in order
28
+ * to activate checkpoints and have their voting power tracked.
29
+ */
30
+ abstract contract VotesConfidential is Nonces, EIP712, IERC6372, HandleAccessManager {
15
31
  using FHE for *;
16
32
  using CheckpointsConfidential for CheckpointsConfidential.TraceEuint64;
17
33
 
@@ -168,7 +184,6 @@ abstract contract VotesConfidential is Nonces, EIP712, IERC6372 {
168
184
  store = _delegateCheckpoints[from];
169
185
  euint64 newValue = store.latest().sub(amount);
170
186
  newValue.allowThis();
171
- newValue.allow(from);
172
187
  euint64 oldValue = _push(store, newValue);
173
188
  emit DelegateVotesChanged(from, oldValue, newValue);
174
189
  }
@@ -176,7 +191,6 @@ abstract contract VotesConfidential is Nonces, EIP712, IERC6372 {
176
191
  store = _delegateCheckpoints[to];
177
192
  euint64 newValue = store.latest().add(amount);
178
193
  newValue.allowThis();
179
- newValue.allow(to);
180
194
  euint64 oldValue = _push(store, newValue);
181
195
  emit DelegateVotesChanged(to, oldValue, newValue);
182
196
  }
@@ -1,10 +1,10 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (interfaces/IConfidentialFungibleToken.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (interfaces/IConfidentialFungibleToken.sol)
3
3
  pragma solidity ^0.8.24;
4
4
 
5
5
  import {euint64, externalEuint64} from "@fhevm/solidity/lib/FHE.sol";
6
6
 
7
- /// @dev Draft interface for a confidential fungible token standard utilizing the Zama TFHE library.
7
+ /// @dev Draft interface for a confidential fungible token standard utilizing the Zama FHE library.
8
8
  interface IConfidentialFungibleToken {
9
9
  /**
10
10
  * @dev Emitted when the expiration timestamp for an operator `operator` is updated for a given `holder`.
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (interfaces/IConfidentialFungibleTokenReceiver.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (interfaces/IConfidentialFungibleTokenReceiver.sol)
3
3
  pragma solidity ^0.8.24;
4
4
 
5
5
  import {ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openzeppelin/confidential-contracts",
3
3
  "description": "Smart Contract library for use with confidential coprocessors",
4
- "version": "0.2.0-rc.1",
4
+ "version": "0.2.0",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",
@@ -1,10 +1,10 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (token/ConfidentialFungibleToken.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (token/ConfidentialFungibleToken.sol)
3
3
  pragma solidity ^0.8.27;
4
4
 
5
5
  import {FHE, externalEuint64, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
6
6
  import {IConfidentialFungibleToken} from "./../interfaces/IConfidentialFungibleToken.sol";
7
- import {TFHESafeMath} from "./../utils/TFHESafeMath.sol";
7
+ import {FHESafeMath} from "./../utils/FHESafeMath.sol";
8
8
  import {ConfidentialFungibleTokenUtils} from "./utils/ConfidentialFungibleTokenUtils.sol";
9
9
 
10
10
  /**
@@ -220,7 +220,7 @@ abstract contract ConfidentialFungibleToken is IConfidentialFungibleToken {
220
220
  _requestHandles[requestID] = encryptedAmount;
221
221
  }
222
222
 
223
- /// @dev May only be called by the gateway contract. Finalizes a disclose encrypted amount request.
223
+ /// @dev Finalizes a disclose encrypted amount request.
224
224
  function finalizeDiscloseEncryptedAmount(
225
225
  uint256 requestId,
226
226
  uint64 amount,
@@ -266,14 +266,11 @@ abstract contract ConfidentialFungibleToken is IConfidentialFungibleToken {
266
266
  euint64 sent = _transfer(from, to, amount);
267
267
 
268
268
  // Perform callback
269
- transferred = FHE.select(
270
- ConfidentialFungibleTokenUtils.checkOnTransferReceived(msg.sender, from, to, sent, data),
271
- sent,
272
- FHE.asEuint64(0)
273
- );
269
+ ebool success = ConfidentialFungibleTokenUtils.checkOnTransferReceived(msg.sender, from, to, sent, data);
274
270
 
275
- // Refund if success fails. refund should never fail
276
- _update(to, from, FHE.sub(sent, transferred));
271
+ // Try to refund if callback fails
272
+ euint64 refund = _update(to, from, FHE.select(success, FHE.asEuint64(0), sent));
273
+ transferred = FHE.sub(sent, refund);
277
274
  }
278
275
 
279
276
  function _update(address from, address to, euint64 amount) internal virtual returns (euint64 transferred) {
@@ -281,13 +278,13 @@ abstract contract ConfidentialFungibleToken is IConfidentialFungibleToken {
281
278
  euint64 ptr;
282
279
 
283
280
  if (from == address(0)) {
284
- (success, ptr) = TFHESafeMath.tryIncrease(_totalSupply, amount);
281
+ (success, ptr) = FHESafeMath.tryIncrease(_totalSupply, amount);
285
282
  FHE.allowThis(ptr);
286
283
  _totalSupply = ptr;
287
284
  } else {
288
285
  euint64 fromBalance = _balances[from];
289
286
  require(FHE.isInitialized(fromBalance), ConfidentialFungibleTokenZeroBalance(from));
290
- (success, ptr) = TFHESafeMath.tryDecrease(fromBalance, amount);
287
+ (success, ptr) = FHESafeMath.tryDecrease(fromBalance, amount);
291
288
  FHE.allowThis(ptr);
292
289
  FHE.allow(ptr, from);
293
290
  _balances[from] = ptr;
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (token/extensions/ConfidentialFungibleTokenERC20Wrapper.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (token/extensions/ConfidentialFungibleTokenERC20Wrapper.sol)
3
3
 
4
4
  pragma solidity ^0.8.27;
5
5
 
@@ -15,6 +15,9 @@ import {ConfidentialFungibleToken} from "./../ConfidentialFungibleToken.sol";
15
15
  * @dev A wrapper contract built on top of {ConfidentialFungibleToken} that allows wrapping an `ERC20` token
16
16
  * into a confidential fungible token. The wrapper contract implements the `IERC1363Receiver` interface
17
17
  * which allows users to transfer `ERC1363` tokens directly to the wrapper with a callback to wrap the tokens.
18
+ *
19
+ * WARNING: Minting assumes the full amount of the underlying token transfer has been received, hence some non-standard
20
+ * tokens such as fee-on-transfer or other deflationary-type tokens are not supported by this wrapper.
18
21
  */
19
22
  abstract contract ConfidentialFungibleTokenERC20Wrapper is ConfidentialFungibleToken, IERC1363Receiver {
20
23
  IERC20 private immutable _underlying;
@@ -70,14 +73,14 @@ abstract contract ConfidentialFungibleTokenERC20Wrapper is ConfidentialFungibleT
70
73
  // check caller is the token contract
71
74
  require(address(underlying()) == msg.sender, ConfidentialFungibleTokenUnauthorizedCaller(msg.sender));
72
75
 
73
- // transfer excess back to the sender
74
- uint256 excess = amount % rate();
75
- if (excess > 0) SafeERC20.safeTransfer(underlying(), from, excess);
76
-
77
76
  // mint confidential token
78
77
  address to = data.length < 20 ? from : address(bytes20(data));
79
78
  _mint(to, FHE.asEuint64(SafeCast.toUint64(amount / rate())));
80
79
 
80
+ // transfer excess back to the sender
81
+ uint256 excess = amount % rate();
82
+ if (excess > 0) SafeERC20.safeTransfer(underlying(), from, excess);
83
+
81
84
  // return magic value
82
85
  return IERC1363Receiver.onTransferReceived.selector;
83
86
  }
@@ -125,8 +128,7 @@ abstract contract ConfidentialFungibleTokenERC20Wrapper is ConfidentialFungibleT
125
128
  }
126
129
 
127
130
  /**
128
- * @dev Called by the fhEVM gateway with the decrypted amount `amount` for a request id `requestId`.
129
- * Fills unwrap requests.
131
+ * @dev Fills an unwrap request for a given request id related to a decrypted unwrap amount.
130
132
  */
131
133
  function finalizeUnwrap(uint256 requestID, uint64 amount, bytes[] memory signatures) public virtual {
132
134
  FHE.checkSignatures(requestID, signatures);
@@ -156,6 +158,15 @@ abstract contract ConfidentialFungibleTokenERC20Wrapper is ConfidentialFungibleT
156
158
  _receivers[requestID] = to;
157
159
  }
158
160
 
161
+ /**
162
+ * @dev Returns the default number of decimals of the underlying ERC-20 token that is being wrapped.
163
+ * Used as a default fallback when {_tryGetAssetDecimals} fails to fetch decimals of the underlying
164
+ * ERC-20 token.
165
+ */
166
+ function _fallbackUnderlyingDecimals() internal pure virtual returns (uint8) {
167
+ return 18;
168
+ }
169
+
159
170
  /**
160
171
  * @dev Returns the maximum number that will be used for {decimals} by the wrapper.
161
172
  */
@@ -170,6 +181,6 @@ abstract contract ConfidentialFungibleTokenERC20Wrapper is ConfidentialFungibleT
170
181
  if (success && encodedDecimals.length == 32) {
171
182
  return abi.decode(encodedDecimals, (uint8));
172
183
  }
173
- return 18;
184
+ return _fallbackUnderlyingDecimals();
174
185
  }
175
186
  }
@@ -1,12 +1,20 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (token/extensions/ConfidentialFungibleTokenVotes.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (token/extensions/ConfidentialFungibleTokenVotes.sol)
3
3
  pragma solidity ^0.8.27;
4
4
 
5
5
  import {euint64} from "@fhevm/solidity/lib/FHE.sol";
6
6
  import {VotesConfidential} from "./../../governance/utils/VotesConfidential.sol";
7
7
  import {ConfidentialFungibleToken} from "./../ConfidentialFungibleToken.sol";
8
8
 
9
+ /**
10
+ * @dev Extension of {ConfidentialFungibleToken} supporting confidential votes tracking and delegation.
11
+ *
12
+ * The amount of confidential voting units an account has is equal to the confidential token balance of
13
+ * that account. Voing power is taken into account when an account delegates votes to itself or to another
14
+ * account.
15
+ */
9
16
  abstract contract ConfidentialFungibleTokenVotes is ConfidentialFungibleToken, VotesConfidential {
17
+ /// @inheritdoc ConfidentialFungibleToken
10
18
  function confidentialTotalSupply()
11
19
  public
12
20
  view
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (token/utils/ConfidentialFungibleTokenUtils.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (token/utils/ConfidentialFungibleTokenUtils.sol)
3
3
  pragma solidity ^0.8.24;
4
4
 
5
5
  import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (utils/TFHESafeMath.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.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";
@@ -8,7 +8,7 @@ import {FHE, ebool, euint64} from "@fhevm/solidity/lib/FHE.sol";
8
8
  * @dev Library providing safe arithmetic operations for encrypted values
9
9
  * to handle potential overflows in FHE operations.
10
10
  */
11
- library TFHESafeMath {
11
+ library FHESafeMath {
12
12
  /**
13
13
  * @dev Try to increase the encrypted value `oldValue` by `delta`. If the operation is successful,
14
14
  * `success` will be true and `updated` will be the new value. Otherwise, `success` will be false
@@ -0,0 +1,29 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (utils/HandleAccessManager.sol)
3
+ pragma solidity ^0.8.24;
4
+
5
+ import {Impl} from "@fhevm/solidity/lib/Impl.sol";
6
+
7
+ abstract contract HandleAccessManager {
8
+ /**
9
+ * @dev Get handle access for the given handle `handle`. Access will be given to the
10
+ * account `account` with the given persistence flag.
11
+ *
12
+ * NOTE: This function call is gated by `msg.sender` and validated by the
13
+ * {_validateHandleAllowance} function.
14
+ */
15
+ function getHandleAllowance(bytes32 handle, address account, bool persistent) public virtual {
16
+ _validateHandleAllowance(handle);
17
+ if (persistent) {
18
+ Impl.allow(handle, account);
19
+ } else {
20
+ Impl.allowTransient(handle, account);
21
+ }
22
+ }
23
+
24
+ /**
25
+ * @dev Unimplemented function that must revert if the message sender is not allowed to call
26
+ * {getHandleAllowance} for the given handle.
27
+ */
28
+ function _validateHandleAllowance(bytes32 handle) internal view virtual;
29
+ }
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (utils/structs/CheckpointsConfidential.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.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;
@@ -18,11 +18,6 @@ import {Checkpoints} from "./temporary-Checkpoints.sol";
18
18
  library CheckpointsConfidential {
19
19
  using Checkpoints for Checkpoints.Trace256;
20
20
 
21
- /**
22
- * @dev A value was attempted to be inserted on a past checkpoint.
23
- */
24
- error CheckpointUnorderedInsertion();
25
-
26
21
  struct TraceEuint32 {
27
22
  Checkpoints.Trace256 _inner;
28
23
  }
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.2.0-rc.1) (utils/structs/temporary-Checkpoints.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.2.0) (utils/structs/temporary-Checkpoints.sol)
3
3
  // OpenZeppelin Contracts (last updated v5.3.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.