creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "contracts/interfaces/IRegistry.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport './ISafe.sol';\n\ninterface IRegistry {\n  function userSafes(address) external view returns (address);\n\n  function handlers(address) external view returns (bytes32);\n\n  function callers(address) external view returns (bytes32);\n\n  function bannedAgents(address) external view returns (uint256);\n\n  function fHalt() external view returns (bool);\n\n  function isValidHandler(address handler) external view returns (bool);\n\n  function isValidCaller(address handler) external view returns (bool);\n\n  function registerSafeForUser(ISafe safe, address user) external;\n}\n"
      },
      "contracts/interfaces/ISafe.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.7.0 <0.9.0;\n\nimport '../utils/Enum.sol';\n\ninterface ISafe {\n  event EnabledModule(address module);\n  event DisabledModule(address module);\n  event ExecutionFromModuleSuccess(address indexed module);\n  event ExecutionFromModuleFailure(address indexed module);\n\n  /// @dev Enables a module on the safe\n  /// @notice Can only be called by the safe\n  /// @notice Modules should be stored as a linked list.\n  /// @notice Must emit EnabledModule(address module) if successful.\n  /// @param module Module to be enabled.\n  function enableModule(address module) external;\n\n  /// @dev Disables a module on the safe\n  /// @notice Can only be called by the safe\n  /// @notice Must emit DisabledModule(address module) if successful.\n  /// @param prevModule Address that pointed to the module to be removed in the linked list\n  /// @param module Module to be removed.\n  function disableModule(address prevModule, address module) external;\n\n  /// @dev Allows a Module to execute a transaction.\n  /// @notice Can only be called by an enabled module.\n  /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n  /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n  /// @param to Destination address of module transaction.\n  /// @param value Ether value of module transaction.\n  /// @param data Data payload of module transaction.\n  /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n  function execTransactionFromModule(\n    address to,\n    uint256 value,\n    bytes memory data,\n    Enum.Operation operation\n  ) external returns (bool success);\n\n  /// @dev Allows a Module to execute a transaction and return data\n  /// @notice Can only be called by an enabled module.\n  /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n  /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n  /// @param to Destination address of module transaction.\n  /// @param value Ether value of module transaction.\n  /// @param data Data payload of module transaction.\n  /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n  function execTransactionFromModuleReturnData(\n    address to,\n    uint256 value,\n    bytes memory data,\n    Enum.Operation operation\n  ) external returns (bool success, bytes memory returnData);\n\n  /// @dev Returns if an module is enabled\n  /// @return True if the module is enabled\n  function isModuleEnabled(address module) external view returns (bool);\n\n  /// @dev Returns array of modules.\n  /// @param start Start of the page.\n  /// @param pageSize Maximum number of modules that should be returned.\n  /// @return array Array of modules.\n  /// @return next Start of the next page.\n  function getModulesPaginated(\n    address start,\n    uint256 pageSize\n  ) external view returns (address[] memory array, address next);\n\n  function getOwners() external view returns (address[] memory);\n}\n"
      },
      "contracts/registry/Registry.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';\n\nimport '../interfaces/IRegistry.sol';\nimport '../interfaces/ISafe.sol';\nimport './RegistryStorage.sol';\n\ncontract LucidityRegistry is IRegistry, OwnableUpgradeable, RegistryStorage {\n  event SafeRegistered(ISafe indexed safe, address indexed user);\n  event SafeUnregistered(address indexed safe, address indexed user);\n  event Registered(address indexed registration, bytes32 info);\n  event Unregistered(address indexed registration);\n  event CallerRegistered(address indexed registration, bytes32 info);\n  event CallerUnregistered(address indexed registration);\n  event Banned(address indexed agent);\n  event Unbanned(address indexed agent);\n  event Halted();\n  event Unhalted();\n  event LucidityModuleProxyUpdated(address indexed proxy);\n\n  modifier isNotHalted() {\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.fHalt == false, 'Halted');\n    _;\n  }\n\n  modifier isHalted() {\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.fHalt, 'Not halted');\n    _;\n  }\n\n  modifier isNotBanned(address agent) {\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.bannedAgents[agent] == 0, 'Banned');\n    _;\n  }\n\n  modifier isBanned(address agent) {\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.bannedAgents[agent] != 0, 'Not banned');\n    _;\n  }\n\n  constructor() {\n    _disableInitializers();\n  }\n\n  /**\n   * @notice Initializer for the Registry\n   * @param _owner The owner of the Registry Impl.\n   */\n  function initialize(address _owner) public initializer {\n    __Ownable_init(_owner);\n  }\n\n  /**\n   * @notice Register a safe for a user\n   * @param safe Safe address.\n   * @param user User address.\n   */\n  function registerSafeForUser(ISafe safe, address user) external {\n    require(msg.sender == address(safe) || msg.sender == user, 'unauthorized');\n    require(address(safe) != address(0), 'zero address');\n    require(user != address(0), 'zero address');\n\n    MainStorage storage mainStorage = _getMainStorage();\n\n    // Check if Registration is valid\n    _checkSafeOwnership(user, safe);\n\n    // Check if Safe has enabled lucidity module.\n    require(\n      ISafe(safe).isModuleEnabled(mainStorage.lucidityModuleProxy),\n      'Module not enabled on a safe'\n    );\n\n    mainStorage.userSafes[user] = address(safe);\n\n    emit SafeRegistered(safe, user);\n  }\n\n  /**\n   * @notice Register a handler with a bytes32 information.\n   * @param registration Handler address.\n   * @param info Info string.\n   */\n  function register(address registration, bytes32 info) public onlyOwner {\n    require(registration != address(0), 'zero address');\n    require(info != DEPRECATED && info != bytes32(0), 'unregistered info');\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.handlers[registration] != DEPRECATED, 'unregistered');\n    mainStorage.handlers[registration] = info;\n    emit Registered(registration, info);\n  }\n\n\n  /**\n   * @notice Unregister a handler. The handler will be deprecated.\n   * @param registration The handler to be unregistered.\n   */\n  function unregister(address registration) public onlyOwner {\n    require(registration != address(0), 'zero address');\n    MainStorage storage mainStorage = _getMainStorage();\n    require(\n      mainStorage.handlers[registration] != bytes32(0),\n      'no registration'\n    );\n    require(mainStorage.handlers[registration] != DEPRECATED, 'unregistered');\n    mainStorage.handlers[registration] = DEPRECATED;\n    emit Unregistered(registration);\n  }\n\n  function batchRegister(\n    address[] calldata registrations,\n    bytes32[] calldata infos\n  ) external onlyOwner {\n    for (uint256 i = 0; i < registrations.length; i++) {\n      register(registrations[i], infos[i]);\n    }\n  }\n\n  function batchUnregister(address[] calldata registrations) external onlyOwner {\n    for (uint256 i = 0; i < registrations.length; i++) {\n      unregister(registrations[i]);\n    }\n  }\n\n  /**\n   * @notice Register a caller with a bytes32 information.\n   * @param registration Caller address.\n   * @param info Info string.\n   * @dev Dapps that triggers callback function should be registered.\n   * In this case, registration is the Dapp address and the leading 20 bytes\n   * of info is the handler address.\n   */\n  function registerCaller(\n    address registration,\n    bytes32 info\n  ) public onlyOwner {\n    require(registration != address(0), 'zero address');\n    require(info != DEPRECATED && info != bytes32(0), 'unregistered info');\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.callers[registration] != DEPRECATED, 'unregistered');\n    mainStorage.callers[registration] = info;\n    emit CallerRegistered(registration, info);\n  }\n\n  /**\n   * @notice Unregister a caller. The caller will be deprecated.\n   * @param registration The caller to be unregistered.\n   */\n  function unregisterCaller(address registration) public onlyOwner {\n    require(registration != address(0), 'zero address');\n    MainStorage storage mainStorage = _getMainStorage();\n    require(mainStorage.callers[registration] != bytes32(0), 'no registration');\n    require(mainStorage.callers[registration] != DEPRECATED, 'unregistered');\n    mainStorage.callers[registration] = DEPRECATED;\n    emit CallerUnregistered(registration);\n  }\n\n  function batchRegisterCallers(\n    address[] calldata registrations,\n    bytes32[] calldata infos\n  ) external onlyOwner {\n    require(registrations.length == infos.length, 'length mismatch');\n    for (uint256 i = 0; i < registrations.length; i++) {\n      registerCaller(registrations[i], infos[i]);\n    }\n  }\n\n  function batchUnregisterCallers(address[] calldata registrations) external onlyOwner {\n    for (uint256 i = 0; i < registrations.length; i++) {\n      unregisterCaller(registrations[i]);\n    }\n  }\n\n  /**\n   * @notice Ban agent from query\n   *\n   */\n  function ban(address agent) external isNotBanned(agent) onlyOwner {\n    MainStorage storage mainStorage = _getMainStorage();\n    mainStorage.bannedAgents[agent] = 1;\n    emit Banned(agent);\n  }\n\n  /**\n   * @notice Unban agent from query\n   */\n  function unban(address agent) external isBanned(agent) onlyOwner {\n    MainStorage storage mainStorage = _getMainStorage();\n    mainStorage.bannedAgents[agent] = 0;\n    emit Unbanned(agent);\n  }\n\n  /**\n   * @notice Check if the handler is valid.\n   * @param handler The handler to be verified.\n   */\n  function isValidHandler(\n    address handler\n  ) external view override returns (bool) {\n    MainStorage storage mainStorage = _getMainStorage();\n    return\n      mainStorage.handlers[handler] != 0 &&\n      mainStorage.handlers[handler] != DEPRECATED;\n  }\n\n  /**\n   * @notice Check if the caller is valid.\n   * @param caller The caller to be verified.\n   */\n  function isValidCaller(address caller) external view override returns (bool) {\n    MainStorage storage mainStorage = _getMainStorage();\n    return\n      mainStorage.callers[caller] != 0 &&\n      mainStorage.callers[caller] != DEPRECATED;\n  }\n\n  /**\n   * @notice Get the safe associated with a user.\n   * @param user The user address.\n   */\n  function userSafes(address user) external view returns (address) {\n    MainStorage storage _mainStorage = _getMainStorage();\n    return _mainStorage.userSafes[user];\n  }\n\n  /**\n   * Public function to access the handler mapping.\n   * @param handler The handler address.\n   * @return (bytes32) The handler info.\n   */\n  function handlers(address handler) external view returns (bytes32) {\n    MainStorage storage _mainStorage = _getMainStorage();\n    return _mainStorage.handlers[handler];\n  }\n\n  /**\n   * Public function to access the caller mapping.\n   * @param caller The caller address.\n   * @return (bytes32) The caller info.\n   */\n  function callers(address caller) external view returns (bytes32) {\n    MainStorage storage _mainStorage = _getMainStorage();\n    return _mainStorage.callers[caller];\n  }\n\n  /**\n   * Public function to access the banned agents.\n   * @param agent The agent address.\n   * @return (uint256) The agent info.\n   */\n  function bannedAgents(address agent) external view returns (uint256) {\n    MainStorage storage _mainStorage = _getMainStorage();\n    return _mainStorage.bannedAgents[agent];\n  }\n\n  /**\n   * Public function to access the halted status.\n   * @return (bool) The halted status.\n   */\n  function fHalt() external view returns (bool) {\n    MainStorage storage _mainStorage = _getMainStorage();\n    return _mainStorage.fHalt;\n  }\n\n  /**\n   * Public function to halt the contract.\n   * @dev Only the owner can change the halted status.\n   */\n  function halt() external isNotHalted onlyOwner {\n    MainStorage storage mainStorage = _getMainStorage();\n    mainStorage.fHalt = true;\n    emit Halted();\n  }\n\n  /**\n   * Public function to unhalt the contract.\n   * @dev Only the owner can change the halted status.\n   */\n  function unhalt() external isHalted onlyOwner {\n    MainStorage storage mainStorage = _getMainStorage();\n    mainStorage.fHalt = false;\n    emit Unhalted();\n  }\n\n  function updateLucidityModuleProxy(\n    address _lucidityModuleProxy\n  ) external onlyOwner {\n    MainStorage storage mainStorage = _getMainStorage();\n    mainStorage.lucidityModuleProxy = _lucidityModuleProxy;\n    emit LucidityModuleProxyUpdated(_lucidityModuleProxy);\n  }\n\n  /**\n   * @notice Check if the user is the owner of the safe.\n   * @param user The user address.\n   * @param safe The safe address.\n   */\n  function _checkSafeOwnership(address user, ISafe safe) internal view {\n    address[] memory safeOwners = ISafe(safe).getOwners();\n\n    bool isOwner;\n\n    for (uint256 i = 0; i < safeOwners.length; i++) {\n      if (safeOwners[i] == user) {\n        isOwner = true;\n      }\n    }\n\n    require(\n      isOwner,\n      'Only the owner of the safe can execute this transaction.'\n    );\n  }\n}\n"
      },
      "contracts/registry/RegistryStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\ncontract RegistryStorage {\n  // keccak256(abi.encode(uint256(keccak256('registrystorage.main')) - 1)) & ~bytes32(uint256(0xff));\n  bytes32 private constant REGISTRY_STORAGE_LOCATION =\n    0xee208021263772ae4f9410eea5819abaaec03ca157ada2feaf684cee4b0e8900;\n\n  bytes32 public constant DEPRECATED = bytes10(0x64657072656361746564);\n\n  /// @custom:storage-location erc7201:<RegistryStorage>\n  struct MainStorage {\n    mapping(address => bytes32) handlers;\n    mapping(address => bytes32) callers;\n    mapping(address => uint256) bannedAgents;\n    mapping(address => address) userSafes;\n    bool fHalt;\n    address lucidityModuleProxy;\n  }\n\n  function _getMainStorage() internal pure returns (MainStorage storage $) {\n    assembly {\n      $.slot := REGISTRY_STORAGE_LOCATION\n    }\n  }\n}\n"
      },
      "contracts/utils/Enum.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Enum - Collection of enums used in Safe contracts.\n * @author Richard Meissner - @rmeissner\n */\nabstract contract Enum {\n  enum Operation {\n    Call,\n    DelegateCall,\n    Flashloan\n  }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 400
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}