# MezzHub

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/MezzHub.sol)

**Inherits:** CommonValidation, ModifiedOwnable2StepUpgradeable, DelayedUUPSUpgradeable, IMezzHub

**Author:** Daniel Yamagata & Jerry Qi & Naveen Ailawadi

The central contract of the Mezzanine protocol. It manages the protocol state and whitelists and is used by 'core' contracts to query 'non-core' contracts

*The addresses of the 'non-core' contracts can only be updated via an upgrade, which must be proposed and executed by the 'owner'. Upgrades require a delay before they can be executed. Similarly, the transfer of ownership requires a delay before it can be accepted. The renouncement of ownership is disabled to prevent griefing by a compromised 'owner'. The re-enablement of this functionality must be done via an upgrade*

## State Variables

### PRECISION\_FACTOR

```solidity
uint256 public constant PRECISION_FACTOR = Constants.PRECISION_FACTOR;
```

### MezzHubStorageLocation

```solidity
bytes32 private constant MezzHubStorageLocation = 0x3de7a073c0cce790cf3a28a9e9c6ae84d1b91b340e346453198ee61a13723200;
```

## Functions

### \_getMezzHubStorage

```solidity
function _getMezzHubStorage() internal pure returns (MezzHubStorage storage $);
```

### constructor

```solidity
constructor();
```

### onlyOwnerOrDefender

*Reverts if the caller is not the 'owner' or a 'defender'*

```solidity
modifier onlyOwnerOrDefender();
```

### ownershipTransferSnapshot

Returns the snapshot of the ownership transfer. This snapshot must pass before a pending ownership transfer can occur. If there is no pending ownership transfer, this will will return zero

```solidity
function ownershipTransferSnapshot() public view returns (uint256);
```

### frozenSnapshot

Returns the snapshot of the protocol freeze. This snapshot must pass before the protocol can

```solidity
function frozenSnapshot() public view returns (uint256);
```

### owner

Returns the address of the Mezz Hub owner

```solidity
function owner() public view virtual override(IMezzHub, OwnableUpgradeable) returns (address);
```

### init

Initializes the Mezz Hub state. Can only be called once

```solidity
function init(address initOwner, address initDocumentRegistry, address initMezzDeployer, address initFeeController)
    external
    initializer;
```

**Parameters**

| Name                   | Type      | Description                               |
| ---------------------- | --------- | ----------------------------------------- |
| `initOwner`            | `address` | The address of the initial Mezz Hub owner |
| `initDocumentRegistry` | `address` | The address of the Document Registry      |
| `initMezzDeployer`     | `address` | The address of the Mezz Deployer          |
| `initFeeController`    | `address` | The address of the Fee Controller         |

### \_\_MezzHub\_init

```solidity
function __MezzHub_init(address initDocumentRegistry, address initMezzDeployer, address initFeeController)
    internal
    onlyInitializing;
```

### transferOwnership

*Overridden 'transferOwnership' such that a snapshot is taken upon the transfer of ownership*

```solidity
function transferOwnership(address newOwner) public virtual override;
```

### acceptOwnership

*Overridden '\_acceptOwnership' such that the snapshot is validated before the ownership transfer is accepted*

```solidity
function acceptOwnership() public virtual override;
```

### cancelOwnershipTransfer

*Cancels a pending ownership transfer. Only callable by the 'owner' or a 'defender' Deletes the snapshot of the ownership transfer and the pending owner*

```solidity
function cancelOwnershipTransfer() public virtual onlyOwnerOrDefender;
```

### renounceOwnership

*Deprecation of 'renounceOwnership' from OwnableUpgradeable to prevent griefing by a compromised 'owner'*

```solidity
function renounceOwnership() public virtual override;
```

### freezeProtocol

Freezes the protocol for 'freezeDuration', which can be up to 14 days. Only callable by the 'owner' or a 'defender' The protocol can be re-frozen at any point while it is frozen.

```solidity
function freezeProtocol(uint48 freezeDuration) external onlyOwnerOrDefender;
```

**Parameters**

| Name             | Type     | Description                                        |
| ---------------- | -------- | -------------------------------------------------- |
| `freezeDuration` | `uint48` | The duration to freeze the protocol for in seconds |

### setProtocolState

Sets the protocol state.  Only callabe by the owner. &#x20;

*Protocol state is defined by the following enum:*

* *0: Active*
* *1: Paused*
* *2: Frozen*

*If protocol state is set by this function, it will be permanently set until this function is called again to change state.*

```solidity
function setProtocolState(DataTypes.ProtocolState newState) external override onlyOwner;
```

**Parameters**

| Name       | Type                      | Description               |
| ---------- | ------------------------- | ------------------------- |
| `newState` | `DataTypes.ProtocolState` | The protocol state to set |

### proposeUpgrade

Proposes an upgrade to the contract's implementation

*The caller must be authorized to propose an upgrade. This authorization is determined by inheriting contracts*

```solidity
function proposeUpgrade(address newImplementation) external override onlyOwner returns (uint256);
```

**Parameters**

| Name                | Type      | Description                           |
| ------------------- | --------- | ------------------------------------- |
| `newImplementation` | `address` | The address of the new implementation |

**Returns**

| Name     | Type      | Description                                             |
| -------- | --------- | ------------------------------------------------------- |
| `<none>` | `uint256` | The snapshot of the pending upgrade as a unix-timestamp |

### cancelProposedUpgrade

Cancels the pending upgrade, deleting the 'pendingUpgrade' and 'pendingUpgradeSnapshot' in storage

*The caller must be authorized to cancel a pending upgrade. This authorization is determined by inheriting contracts*

```solidity
function cancelProposedUpgrade() external override onlyOwnerOrDefender;
```

### setFrozenImplementation

Sets the 'implementationToSet' to 'setting'. If true and 'implementationToSet' is StateAware, the implementation's pausable and freezable functions will revert Only callable by the 'owner'

```solidity
function setFrozenImplementation(address implementationToSet, bool setting) external onlyOwner;
```

### setFrozenDeployment

Sets the 'deploymentToSet' to 'setting'. If true, the deployment's pausable and freezable functions will revert Only callable by the 'owner' or a 'defender'

```solidity
function setFrozenDeployment(address deploymentToSet, bool setting) external onlyOwnerOrDefender;
```

### addWhitelistedDenominationAsset

Adds 'denominationAssetToAdd' to the denomination asset whitelist. Only callable by the 'owner'

*The owner should be cautious to never add ERC777s to the whitelist to prevent possible reentrancy attacks*

```solidity
function addWhitelistedDenominationAsset(address denominationAssetToAdd) external onlyOwner;
```

### removeWhitelistedDenominationAsset

Removes 'denominationAssetToRemove' from the denomination asset whitelist. Only callable by the 'owner'

```solidity
function removeWhitelistedDenominationAsset(address denominationAssetToRemove) external onlyOwner;
```

### addDefender

Adds 'defenderToAdd' to the set of defenders. Only callable by the 'owner'

```solidity
function addDefender(address defenderToAdd) external onlyOwner;
```

### removeDefender

Removes 'defenderToRemove' from the set of defenders. Only callable by the 'owner'

```solidity
function removeDefender(address defenderToRemove) external onlyOwner;
```

### isDefender

Returns true if 'defenderToCheck' is a defender, false otherwise

```solidity
function isDefender(address defenderToCheck) external view returns (bool);
```

### isDenominationAsset

Returns true 'denominationAssetToCheck' is whitelisted, false otherwise

```solidity
function isDenominationAsset(address denominationAssetToCheck) external view returns (bool);
```

### isDeploymentFrozen

Returns true if 'deploymentToCheck' is frozen, false otherwise

```solidity
function isDeploymentFrozen(address deploymentToCheck) external view returns (bool);
```

### isImplementationFrozen

Returns true if 'implementationToCheck' is frozen, false otherwise

```solidity
function isImplementationFrozen(address implementationToCheck) external view returns (bool);
```

### getDefenders

Returns the set of defenders as an array of addresses

```solidity
function getDefenders() external view returns (address[] memory);
```

### getDenominationAssets

Returns the set of denomination assets in no specific order

```solidity
function getDenominationAssets() external view returns (address[] memory);
```

### getDocumentRegistry

Returns the address of the Document Registry

*Used by core contracts*

```solidity
function getDocumentRegistry() external view returns (address);
```

### getFeeController

Returns the address of the fee controller

*Used by core contracts*

```solidity
function getFeeController() external view returns (address);
```

### getMezzDeployer

Returns the address of the Mezz Deployer

*Used by the core contracts*

```solidity
function getMezzDeployer() external view returns (address);
```

### getProtocolState

Returns the Protocol State as an enum, DataTypes.ProtocolState

\*The protocol state is defined by the following enum:

* 0: Active
* 1: Paused
* 2: Frozen&#x20;

The protocol can be frozen in two ways:

* (1) The protocol's state was set to 'Frozen' by the owner via 'setProtocolState()'. If this is the case, it can be unfrozen at any point in time
* (2) The 'owner' or a 'defender' set the protocol's state to 'Frozen' via 'freezeProtocol()', which freezes the protocol for a period of time. It cannot be unfrozen until this time passes\*

```solidity
function getProtocolState() external view returns (DataTypes.ProtocolState);
```

### \_setDocumentRegistry

```solidity
function _setDocumentRegistry(address newDocumentRegistry) internal;
```

### \_setMezzDeployer

```solidity
function _setMezzDeployer(address newMezzDeployer) internal;
```

### \_setFeeController

```solidity
function _setFeeController(address newFeeController) internal;
```

### \_validateCallerIsOwnerOrDefender

*Reverts if the caller is not the 'owner' or a 'defender'*

```solidity
function _validateCallerIsOwnerOrDefender() internal view;
```

### \_isCallerDefender

```solidity
function _isCallerDefender() internal view returns (bool);
```

### \_isCallerOwner

```solidity
function _isCallerOwner() internal view returns (bool);
```

### \_authorizeUpgrade

*Overridden '\_authorizeUpgrade()' from DelayedUUPSUpgradeable such that only the 'owner' can execute an upgrade*

```solidity
function _authorizeUpgrade(address newImplementation) internal view override onlyOwner;
```

## Structs

### MezzHubStorage

```solidity
struct MezzHubStorage {
    address _documentRegistry;
    uint96 _ownershipTransferSnapshot;
    address _mezzDeployer;
    address _feeController;
    DataTypes.ProtocolState _protocolState;
    uint48 _frozenSnapshot;
    EnumerableSet.AddressSet _defenders;
    EnumerableSet.AddressSet _denominationAssetWhitelist;
    mapping(address => bool) _frozenImplementations;
    mapping(address => bool) _frozenDeployments;
}
```
