|
| 1 | +// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1 |
| 2 | +// This software is licensed under the Zora Delayed Open Source License. |
| 3 | +// Under this license, you may use, copy, modify, and distribute this software for |
| 4 | +// non-commercial purposes only. Commercial use and competitive products are prohibited |
| 5 | +// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion), |
| 6 | +// at which point this software automatically becomes available under the MIT License. |
| 7 | +// Full license terms available at: https://docs.zora.co/coins/license |
| 8 | +pragma solidity ^0.8.23; |
| 9 | + |
| 10 | +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; |
| 11 | +import {IVersionedContract} from "@zoralabs/shared-contracts/interfaces/IVersionedContract.sol"; |
| 12 | +import {MultiOwnable} from "../utils/MultiOwnable.sol"; |
| 13 | +import {IZoraHookRegistry} from "../interfaces/IZoraHookRegistry.sol"; |
| 14 | + |
| 15 | +/// @title Zora Hook Registry |
| 16 | +/// @notice A registry of Zora hook contracts for Uniswap V4 |
| 17 | +contract ZoraHookRegistry is IZoraHookRegistry, MultiOwnable { |
| 18 | + using EnumerableSet for EnumerableSet.AddressSet; |
| 19 | + |
| 20 | + /// @dev The set of registered hook addresses |
| 21 | + EnumerableSet.AddressSet internal registeredHooks; |
| 22 | + |
| 23 | + /// @dev The tag for each hook |
| 24 | + mapping(address hook => string tag) internal hookTags; |
| 25 | + |
| 26 | + constructor() {} |
| 27 | + |
| 28 | + /// @notice Initializes the registry with initial owners |
| 29 | + function initialize(address[] memory initialOwners) external initializer { |
| 30 | + __MultiOwnable_init(initialOwners); |
| 31 | + } |
| 32 | + |
| 33 | + /// @notice Returns whether a hook is currently registered |
| 34 | + function isRegisteredHook(address hook) external view returns (bool) { |
| 35 | + return registeredHooks.contains(hook); |
| 36 | + } |
| 37 | + |
| 38 | + /// @notice Returns all registered hooks |
| 39 | + function getHooks() external view returns (ZoraHook[] memory) { |
| 40 | + uint256 numHooks = registeredHooks.length(); |
| 41 | + |
| 42 | + ZoraHook[] memory hooks = new ZoraHook[](numHooks); |
| 43 | + |
| 44 | + for (uint256 i; i < numHooks; i++) { |
| 45 | + address hook = registeredHooks.at(i); |
| 46 | + |
| 47 | + hooks[i] = ZoraHook({hook: hook, tag: getHookTag(hook), version: getHookVersion(hook)}); |
| 48 | + } |
| 49 | + |
| 50 | + return hooks; |
| 51 | + } |
| 52 | + |
| 53 | + /// @notice Returns all registered hook addresses |
| 54 | + function getHookAddresses() external view returns (address[] memory) { |
| 55 | + return registeredHooks.values(); |
| 56 | + } |
| 57 | + |
| 58 | + /// @notice Returns the tag for a hook |
| 59 | + function getHookTag(address hook) public view returns (string memory) { |
| 60 | + return hookTags[hook]; |
| 61 | + } |
| 62 | + |
| 63 | + /// @notice Returns the contract version for a hook if it exists |
| 64 | + function getHookVersion(address hook) public pure returns (string memory version) { |
| 65 | + try IVersionedContract(hook).contractVersion() returns (string memory _version) { |
| 66 | + version = _version; |
| 67 | + } catch {} |
| 68 | + } |
| 69 | + |
| 70 | + /// @notice Adds hooks to the registry |
| 71 | + function registerHooks(address[] calldata hooks, string[] calldata tags) external onlyOwner { |
| 72 | + require(hooks.length == tags.length, ArrayLengthMismatch()); |
| 73 | + |
| 74 | + for (uint256 i; i < hooks.length; i++) { |
| 75 | + if (registeredHooks.add(hooks[i])) { |
| 76 | + hookTags[hooks[i]] = tags[i]; |
| 77 | + |
| 78 | + emit ZoraHookRegistered(hooks[i], tags[i], getHookVersion(hooks[i])); |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + /// @notice Removes hooks from the registry |
| 84 | + function removeHooks(address[] calldata hooks) external onlyOwner { |
| 85 | + for (uint256 i; i < hooks.length; i++) { |
| 86 | + if (registeredHooks.remove(hooks[i])) { |
| 87 | + emit ZoraHookRemoved(hooks[i], hookTags[hooks[i]], getHookVersion(hooks[i])); |
| 88 | + |
| 89 | + delete hookTags[hooks[i]]; |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | +} |
0 commit comments