@@ -13,13 +13,13 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
1313 */
1414contract ConfidentialTokenWrappersRegistry is Ownable2StepUpgradeable , UUPSUpgradeable {
1515 /// @notice Struct to represent a (token, confidential token, is revoked) tuple.
16- struct ConfidentialTokenPair {
16+ struct TokenWrapperPair {
1717 /// @notice The address of the token.
1818 address tokenAddress;
1919 /// @notice The address of the confidential token.
2020 address confidentialTokenAddress;
21- /// @notice If the confidential token has been revoked.
22- bool isRevoked ;
21+ /// @notice If the confidential token is valid, ie has not been revoked yet .
22+ bool isValid ;
2323 }
2424
2525 /// @custom:storage-location erc7201:fhevm_protocol.storage.ConfidentialTokenWrappersRegistry
@@ -28,18 +28,21 @@ contract ConfidentialTokenWrappersRegistry is Ownable2StepUpgradeable, UUPSUpgra
2828 mapping (address tokenAddress = > address confidentialTokenAddress ) _tokensToConfidentialTokens;
2929 /// @notice Mapping from confidential token address to token address.
3030 mapping (address confidentialTokenAddress = > address tokenAddress ) _confidentialTokensToTokens;
31- /// @notice If a confidential token has been revoked.
32- mapping (address confidentialTokenAddress = > bool isRevoked ) _revokedConfidentialTokens ;
31+ /// @notice If a confidential token is valid, i.e not revoked.
32+ mapping (address confidentialTokenAddress = > bool isValid ) _validConfidentialTokens ;
3333 /// @notice Index of registered tokens.
3434 mapping (address tokenAddress = > uint256 index ) _tokenIndex;
35- /// @notice Registered token and confidential token pairs.
36- ConfidentialTokenPair [] _tokenConfidentialTokenPairs;
35+ /// @notice Registered token and confidential token wrapper pairs.
36+ TokenWrapperPair [] _tokenConfidentialTokenPairs;
3737 }
3838
3939 // keccak256(abi.encode(uint256(keccak256("fhevm_protocol.storage.ConfidentialTokenWrappersRegistry")) - 1)) & ~bytes32(uint256(0xff))
4040 bytes32 private constant CONFIDENTIAL_TOKEN_WRAPPERS_REGISTRY_STORAGE_LOCATION =
4141 0xc361bd0b1d7584416623b46edb98317525b8de8e557ab49cee21f14d6752da00 ;
4242
43+ /// @notice Error thrown when fromIndex is greater or equal to toIndex.
44+ error FromIndexGreaterOrEqualToIndex (uint256 fromIndex , uint256 toIndex );
45+
4346 /// @notice Error thrown when the token address is zero.
4447 error TokenZeroAddress ();
4548
@@ -65,9 +68,6 @@ contract ConfidentialTokenWrappersRegistry is Ownable2StepUpgradeable, UUPSUpgra
6568 /// @notice Error thrown when no token is associated with a confidential token.
6669 error NoTokenAssociatedWithConfidentialToken (address confidentialTokenAddress );
6770
68- /// @notice Error thrown when a confidential token is not revoked.
69- error ConfidentialTokenNotRevoked (address confidentialTokenAddress );
70-
7171 /// @notice Emitted when a token is registered and associated with a confidential token.
7272 event ConfidentialTokenRegistered (address indexed tokenAddress , address indexed confidentialTokenAddress );
7373
@@ -123,14 +123,16 @@ contract ConfidentialTokenWrappersRegistry is Ownable2StepUpgradeable, UUPSUpgra
123123 $._confidentialTokensToTokens[confidentialTokenAddress] = tokenAddress;
124124
125125 // Register the token and confidential token pairs in the array and keep track of their indexes.
126+ $._tokenIndex[tokenAddress] = $._tokenConfidentialTokenPairs.length ;
126127 $._tokenConfidentialTokenPairs.push (
127- ConfidentialTokenPair ({
128+ TokenWrapperPair ({
128129 tokenAddress: tokenAddress,
129130 confidentialTokenAddress: confidentialTokenAddress,
130- isRevoked: false
131+ isValid: true
131132 })
132133 );
133- $._tokenIndex[tokenAddress] = $._tokenConfidentialTokenPairs.length - 1 ;
134+
135+ $._validConfidentialTokens[confidentialTokenAddress] = true ;
134136
135137 emit ConfidentialTokenRegistered (tokenAddress, confidentialTokenAddress);
136138 }
@@ -144,74 +146,125 @@ contract ConfidentialTokenWrappersRegistry is Ownable2StepUpgradeable, UUPSUpgra
144146 revert ConfidentialTokenZeroAddress ();
145147 }
146148
147- // The confidential token must not be already revoked.
148- if (isConfidentialTokenRevoked (confidentialTokenAddress)) {
149- revert RevokedConfidentialToken (confidentialTokenAddress);
150- }
151-
152149 // The confidential token must be associated with a token.
153150 (, address tokenAddress ) = getTokenAddress (confidentialTokenAddress);
154151 if (tokenAddress == address (0 )) {
155152 revert NoTokenAssociatedWithConfidentialToken (confidentialTokenAddress);
156153 }
157154
155+ // The confidential token must not be already revoked.
156+ if (! isConfidentialTokenValid (confidentialTokenAddress)) {
157+ revert RevokedConfidentialToken (confidentialTokenAddress);
158+ }
159+
158160 ConfidentialTokenWrappersRegistryStorage storage $ = _getConfidentialTokenWrappersRegistryStorage ();
159161
160- $._revokedConfidentialTokens [confidentialTokenAddress] = true ;
162+ $._validConfidentialTokens [confidentialTokenAddress] = false ;
161163
162164 // Set token's confidential token address to zero to indicate that it has been revoked.
163165 uint256 index = $._tokenIndex[tokenAddress];
164- $._tokenConfidentialTokenPairs[index].isRevoked = true ;
166+ $._tokenConfidentialTokenPairs[index].isValid = false ;
165167
166168 emit ConfidentialTokenRevoked (tokenAddress, confidentialTokenAddress);
167169 }
168170 /**
169171 * @notice Returns the address of the confidential token associated with a token. A null address
170172 * is returned if no confidential token has been registered for the token.
171173 * @param tokenAddress The address of the token.
172- * @return True if the confidential token has been revoked, false otherwise.
174+ * @return True if the confidential token is valid, ie non- revoked, false otherwise.
173175 * @return The address of the confidential token.
174176 */
175177 function getConfidentialTokenAddress (address tokenAddress ) public view returns (bool , address ) {
176178 address confidentialTokenAddress = _getConfidentialTokenWrappersRegistryStorage ()._tokensToConfidentialTokens[
177179 tokenAddress
178180 ];
179- bool isRevoked = isConfidentialTokenRevoked (confidentialTokenAddress);
180- return (isRevoked , confidentialTokenAddress);
181+ bool isValid = isConfidentialTokenValid (confidentialTokenAddress);
182+ return (isValid , confidentialTokenAddress);
181183 }
182184
183185 /**
184186 * @notice Returns the address of the token associated with a confidential token.
185187 * A null address is returned if the confidential token has not been registered for any token.
186188 * @param confidentialTokenAddress The address of the confidential token.
187- * @return True if the confidential token has been revoked, false otherwise.
189+ * @return True if the confidential token is valid, ie non- revoked, false otherwise.
188190 * @return The address of the token.
189191 */
190192 function getTokenAddress (address confidentialTokenAddress ) public view returns (bool , address ) {
191- bool isRevoked = isConfidentialTokenRevoked (confidentialTokenAddress);
193+ bool isValid = isConfidentialTokenValid (confidentialTokenAddress);
192194 address tokenAddress = _getConfidentialTokenWrappersRegistryStorage ()._confidentialTokensToTokens[
193195 confidentialTokenAddress
194196 ];
195- return (isRevoked, tokenAddress);
197+ return (isValid, tokenAddress);
198+ }
199+
200+ /**
201+ * @notice Returns the index of the registered token in the array of
202+ * (tokenAddress, confidentialTokenAddress, isValid) tuples.
203+ * Will raise an error if token has not been registered yet.
204+ * @param tokenAddress The address of the token.
205+ * @return The index of the token.
206+ */
207+ function getTokenIndex (address tokenAddress ) public view returns (uint256 ) {
208+ uint256 tokenIndex = _getConfidentialTokenWrappersRegistryStorage ()._tokenIndex[tokenAddress];
209+ return tokenIndex;
196210 }
197211
198212 /**
199- * @notice Returns the array of (token address, confidential token address, is revoked ) tuples.
213+ * @notice Returns the array of (tokenAddress, confidentialTokenAddress, isValid ) tuples.
200214 * A tuple containing a revoked confidential token is kept in the array and addresses are not
201- * affected, only the isRevoked flag is set to true.
202- * @return The array of (token address, confidential token address, is revoked) tuples.
215+ * affected, only the isValid flag is set to false.
216+ * @dev Warning: might run out-of-gas if used inside a transaction, rather than an offchain view call.
217+ * In a contract, use a safer alternative: getTokenConfidentialTokenPairsSlice or getTokenConfidentialTokenPair.
218+ * @return The array of (tokenAddress, confidentialTokenAddress, isValid) tuples.
203219 */
204- function getTokenConfidentialTokenPairs () public view returns (ConfidentialTokenPair [] memory ) {
220+ function getTokenConfidentialTokenPairs () public view returns (TokenWrapperPair [] memory ) {
205221 return _getConfidentialTokenWrappersRegistryStorage ()._tokenConfidentialTokenPairs;
206222 }
207223
208224 /**
209- * @notice Returns true if a confidential token has been revoked, false otherwise.
225+ * @notice Returns a slice of the array of (tokenAddress, confidentialTokenAddress, isValid) tuples,
226+ * from fromIndex to toIndex.
227+ * A tuple containing a revoked confidential token is kept in the array and addresses are not
228+ * affected, only the isValid flag is set to false.
229+ * @return A slice of the array of (tokenAddress, confidentialTokenAddress, isValid) tuples.
230+ */
231+ function getTokenConfidentialTokenPairsSlice (
232+ uint256 fromIndex ,
233+ uint256 toIndex
234+ ) public view returns (TokenWrapperPair[] memory ) {
235+ if (toIndex <= fromIndex) revert FromIndexGreaterOrEqualToIndex (fromIndex, toIndex);
236+ TokenWrapperPair[] memory slice = new TokenWrapperPair [](toIndex - fromIndex);
237+ for (uint256 i = fromIndex; i < toIndex; i++ ) {
238+ slice[i] = _getConfidentialTokenWrappersRegistryStorage ()._tokenConfidentialTokenPairs[i];
239+ }
240+ return slice;
241+ }
242+
243+ /**
244+ * @notice Returns the (tokenAddress, confidentialTokenAddress, isValid) tuples at index.
245+ * A tuple containing a revoked confidential token is kept in the array and addresses are not
246+ * affected, only the isValid flag is set to false.
247+ * @return The (tokenAddress, confidentialTokenAddress, isValid) tuple.
248+ */
249+ function getTokenConfidentialTokenPair (uint256 index ) public view returns (TokenWrapperPair memory ) {
250+ return _getConfidentialTokenWrappersRegistryStorage ()._tokenConfidentialTokenPairs[index];
251+ }
252+
253+ /**
254+ * @notice Returns the number of stored (tokenAddress, confidentialTokenAddress, isValid) tuples.
255+ * @return The length of the array of (tokenAddress, confidentialTokenAddress, isValid) tuples.
256+ */
257+ function getTokenConfidentialTokenPairsLength () public view returns (uint256 ) {
258+ return _getConfidentialTokenWrappersRegistryStorage ()._tokenConfidentialTokenPairs.length ;
259+ }
260+
261+ /**
262+ * @notice Returns true if a confidential token has not been revoked, false otherwise.
210263 * @param confidentialTokenAddress The address of the confidential token.
211- * @return True if the confidential token has been revoked , false otherwise.
264+ * @return True if the confidential token is valid , false otherwise.
212265 */
213- function isConfidentialTokenRevoked (address confidentialTokenAddress ) public view returns (bool ) {
214- return _getConfidentialTokenWrappersRegistryStorage ()._revokedConfidentialTokens [confidentialTokenAddress];
266+ function isConfidentialTokenValid (address confidentialTokenAddress ) public view returns (bool ) {
267+ return _getConfidentialTokenWrappersRegistryStorage ()._validConfidentialTokens [confidentialTokenAddress];
215268 }
216269
217270 function _authorizeUpgrade (address newImplementation ) internal override onlyOwner {}
0 commit comments