@openzeppelin/confidential-contracts 0.3.0 → 0.3.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.
@@ -36,6 +36,11 @@
36
36
  "name": "ERC7984InvalidSender",
37
37
  "type": "error"
38
38
  },
39
+ {
40
+ "inputs": [],
41
+ "name": "ERC7984TotalSupplyOverflow",
42
+ "type": "error"
43
+ },
39
44
  {
40
45
  "inputs": [
41
46
  {
@@ -640,6 +645,19 @@
640
645
  "stateMutability": "nonpayable",
641
646
  "type": "function"
642
647
  },
648
+ {
649
+ "inputs": [],
650
+ "name": "inferredTotalSupply",
651
+ "outputs": [
652
+ {
653
+ "internalType": "uint256",
654
+ "name": "",
655
+ "type": "uint256"
656
+ }
657
+ ],
658
+ "stateMutability": "view",
659
+ "type": "function"
660
+ },
643
661
  {
644
662
  "inputs": [
645
663
  {
@@ -664,6 +682,19 @@
664
682
  "stateMutability": "view",
665
683
  "type": "function"
666
684
  },
685
+ {
686
+ "inputs": [],
687
+ "name": "maxTotalSupply",
688
+ "outputs": [
689
+ {
690
+ "internalType": "uint256",
691
+ "name": "",
692
+ "type": "uint256"
693
+ }
694
+ ],
695
+ "stateMutability": "view",
696
+ "type": "function"
697
+ },
667
698
  {
668
699
  "inputs": [],
669
700
  "name": "name",
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.3.0",
4
+ "version": "0.3.1",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Confidential Contracts (last updated v0.3.0) (token/ERC7984/extensions/ERC7984ERC20Wrapper.sol)
2
+ // OpenZeppelin Confidential Contracts (last updated v0.3.1) (token/ERC7984/extensions/ERC7984ERC20Wrapper.sol)
3
3
 
4
4
  pragma solidity ^0.8.27;
5
5
 
@@ -30,6 +30,7 @@ abstract contract ERC7984ERC20Wrapper is ERC7984, IERC1363Receiver {
30
30
  event UnwrapFinalized(address indexed receiver, euint64 encryptedAmount, uint64 cleartextAmount);
31
31
 
32
32
  error InvalidUnwrapRequest(euint64 amount);
33
+ error ERC7984TotalSupplyOverflow();
33
34
 
34
35
  constructor(IERC20 underlying_) {
35
36
  _underlying = underlying_;
@@ -45,28 +46,10 @@ abstract contract ERC7984ERC20Wrapper is ERC7984, IERC1363Receiver {
45
46
  }
46
47
  }
47
48
 
48
- /// @inheritdoc ERC7984
49
- function decimals() public view virtual override returns (uint8) {
50
- return _decimals;
51
- }
52
-
53
- /**
54
- * @dev Returns the rate at which the underlying token is converted to the wrapped token.
55
- * For example, if the `rate` is 1000, then 1000 units of the underlying token equal 1 unit of the wrapped token.
56
- */
57
- function rate() public view virtual returns (uint256) {
58
- return _rate;
59
- }
60
-
61
- /// @dev Returns the address of the underlying ERC-20 token that is being wrapped.
62
- function underlying() public view returns (IERC20) {
63
- return _underlying;
64
- }
65
-
66
49
  /**
67
50
  * @dev `ERC1363` callback function which wraps tokens to the address specified in `data` or
68
51
  * the address `from` (if no address is specified in `data`). This function refunds any excess tokens
69
- * sent beyond the nearest multiple of {rate}. See {wrap} from more details on wrapping tokens.
52
+ * sent beyond the nearest multiple of {rate} to `from`. See {wrap} from more details on wrapping tokens.
70
53
  */
71
54
  function onTransferReceived(
72
55
  address /*operator*/,
@@ -149,6 +132,63 @@ abstract contract ERC7984ERC20Wrapper is ERC7984, IERC1363Receiver {
149
132
  emit UnwrapFinalized(to, burntAmount, burntAmountCleartext);
150
133
  }
151
134
 
135
+ /// @inheritdoc ERC7984
136
+ function decimals() public view virtual override returns (uint8) {
137
+ return _decimals;
138
+ }
139
+
140
+ /**
141
+ * @dev Returns the rate at which the underlying token is converted to the wrapped token.
142
+ * For example, if the `rate` is 1000, then 1000 units of the underlying token equal 1 unit of the wrapped token.
143
+ */
144
+ function rate() public view virtual returns (uint256) {
145
+ return _rate;
146
+ }
147
+
148
+ /// @dev Returns the address of the underlying ERC-20 token that is being wrapped.
149
+ function underlying() public view returns (IERC20) {
150
+ return _underlying;
151
+ }
152
+
153
+ /**
154
+ * @dev Returns the underlying balance divided by the {rate}, a value greater or equal to the actual
155
+ * {confidentialTotalSupply}.
156
+ *
157
+ * NOTE: The return value of this function can be inflated by directly sending underlying tokens to the wrapper contract.
158
+ * Reductions will lag compared to {confidentialTotalSupply} since it is updated on {unwrap} while this function updates
159
+ * on {finalizeUnwrap}.
160
+ */
161
+ function inferredTotalSupply() public view virtual returns (uint256) {
162
+ return underlying().balanceOf(address(this)) / rate();
163
+ }
164
+
165
+ /// @dev Returns the maximum total supply of wrapped tokens supported by the encrypted datatype.
166
+ function maxTotalSupply() public view virtual returns (uint256) {
167
+ return type(uint64).max;
168
+ }
169
+
170
+ /**
171
+ * @dev This function must revert if the new {confidentialTotalSupply} is invalid (overflow occurred).
172
+ *
173
+ * NOTE: Overflow can be detected here since the wrapper holdings are non-confidential. In other cases, it may be impossible
174
+ * to infer total supply overflow synchronously. This function may revert even if the {confidentialTotalSupply} did
175
+ * not overflow.
176
+ */
177
+ function _checkConfidentialTotalSupply() internal virtual {
178
+ if (inferredTotalSupply() > maxTotalSupply()) {
179
+ revert ERC7984TotalSupplyOverflow();
180
+ }
181
+ }
182
+
183
+ /// @inheritdoc ERC7984
184
+ function _update(address from, address to, euint64 amount) internal virtual override returns (euint64) {
185
+ if (from == address(0)) {
186
+ _checkConfidentialTotalSupply();
187
+ }
188
+ return super._update(from, to, amount);
189
+ }
190
+
191
+ /// @dev Internal logic for handling the creation of unwrap requests.
152
192
  function _unwrap(address from, address to, euint64 amount) internal virtual {
153
193
  require(to != address(0), ERC7984InvalidReceiver(to));
154
194
  require(from == msg.sender || isOperator(from, msg.sender), ERC7984UnauthorizedSpender(from, msg.sender));