# MezzDeployer

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

**Inherits:** ReentrancyGuardUpgradeable, HubOwnableUUPSUpgradeable, IMezzDeployer

**Author:** Daniel Yamagata & Naveen Ailawadi

Deploys all 'core' contracts for a Mezzanine Instance. The Mezz Deployer is the initial contract that a user interacts with to deploy a Mezz Company

*The Mezz Deployer includes defaults for Mezz guards based on their core ID. Refer to src/core/guards/base/MezzGuard.sol for more information If the guard is a 'blacklist', defaults are meant to include malicious contracts and functions which should be blocked. If the guard is a 'whitelist', defaults are meant to include contracts and function which should be enabled By default, every guard in Mezzanine is a 'blacklist' as it is less heavy-handed than a 'whitelist'*

## State Variables

### MEZZ\_MIGRATOR

```solidity
IMezzMigrator public immutable MEZZ_MIGRATOR;
```

### MezzDeployerStorageLocation

```solidity
bytes32 private constant MezzDeployerStorageLocation =
    0xb862070e819a934b7ff2bcc5f351b88c7b19d8fd2bbeee8d45544c981e112200;
```

## Functions

### \_getMezzDeployerStorage

```solidity
function _getMezzDeployerStorage() internal pure returns (MezzDeployerStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) HubOwnableUUPSUpgradeable(_mezzHub);
```

### init

*Sets the Reentrancy Guard's status to '\_NOT\_ENTERED'*

```solidity
function init() external initializer;
```

### \_\_MezzDeployer\_init

```solidity
function __MezzDeployer_init() internal virtual onlyInitializing;
```

### deployMezzInstance

Deploys a Mezz Instance with the given 'initArgs'. This is the first function that a user should interact with in Mezzanine

*The address of the common shares is not returned but is queryable via the Treasury*

```solidity
function deployMezzInstance(DataTypes.MezzInitArgs memory initArgs)
    external
    virtual
    pausable
    returns (DataTypes.MezzInstance memory);
```

**Parameters**

| Name       | Type                     | Description                                        |
| ---------- | ------------------------ | -------------------------------------------------- |
| `initArgs` | `DataTypes.MezzInitArgs` | The arguments to initialize the Mezz Instance with |

**Returns**

| Name     | Type                     | Description                                                                                          |
| -------- | ------------------------ | ---------------------------------------------------------------------------------------------------- |
| `<none>` | `DataTypes.MezzInstance` | The Mezz Instance, which includes the treasury, finance department, governor, and the token timelock |

### deployGuard

Deploys and initializes a Mezzanine Guard. &#x20;

```solidity
function deployGuard(bytes32 coreId, address _controlled, address _controller, bytes memory params)
    external
    virtual
    pausable
    returns (address);
```

**Parameters**

| Name          | Type      | Description                                              |
| ------------- | --------- | -------------------------------------------------------- |
| `coreId`      | `bytes32` | The coreId of the guard implementation to deploy         |
| `_controlled` | `address` | The address to set as the controlled                     |
| `_controller` | `address` | The address to set as the controller                     |
| `params`      | `bytes`   | Additional params used during the guard's initialization |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `address` | The address of the deployed guard |

### \_deployGuard

*Deploys and initializes a guard atomically. Used in deployGuard(), deployMezzInstance(), and deployDepartment()*

```solidity
function _deployGuard(bytes32 guardCoreId, address _controlled, address _controller, bytes memory params)
    internal
    virtual
    returns (address);
```

### deployDepartment

Deploy and initializes a department atomically

*The department is not atomically inserted as a child to the provided Treasury or Department. This must be done via a separate transaction or can be done atomically via a multicall*

```solidity
function deployDepartment(
    bytes32 departmentCoreId,
    bytes32 guardCoreId,
    address treasury,
    address[] memory owners,
    uint256 threshold,
    address parent,
    bytes memory params
) external virtual pausable returns (address);
```

**Parameters**

| Name               | Type        | Description                                                                                                              |
| ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| `departmentCoreId` | `bytes32`   | The core ID of the department to deploy                                                                                  |
| `guardCoreId`      | `bytes32`   | The core ID of the guard to deploy, whose 'controlled' will be the deployed department and 'controller' will be 'parent' |
| `treasury`         | `address`   | The treasury contract that the department is associated with                                                             |
| `owners`           | `address[]` | The signers for the department's multisignature functionality                                                            |
| `threshold`        | `uint256`   | The threshold for the department's multisignature functionality                                                          |
| `parent`           | `address`   | The parent of the department to deploy                                                                                   |
| `params`           | `bytes`     | Bespoke abi.encoded parameters to pass to the department's init() function                                               |

**Returns**

| Name     | Type      | Description                            |
| -------- | --------- | -------------------------------------- |
| `<none>` | `address` | The address of the deployed department |

### deployModule

Deploys and initializes a module atomically

*The module is not atomically inserted as a child to the provided Treasury or Department. This must be done via a separate transaction or can be done atomically via a multicall*

```solidity
function deployModule(bytes32 moduleCoreId, address parent, bytes memory params)
    external
    virtual
    pausable
    returns (address);
```

**Parameters**

| Name           | Type      | Description                                                                |
| -------------- | --------- | -------------------------------------------------------------------------- |
| `moduleCoreId` | `bytes32` | The core ID of the module to deploy                                        |
| `parent`       | `address` |                                                                            |
| `params`       | `bytes`   | The bespoke abi.encoded parameters to pass to the module's init() function |

**Returns**

| Name     | Type      | Description                        |
| -------- | --------- | ---------------------------------- |
| `<none>` | `address` | The address of the deployed module |

### deployAsset

Deploys and initialize an asset associated with 'assetCoreId' and returns the deployed contract

*Used by Treasury contracts when adding assets to the capital stack*

```solidity
function deployAsset(bytes32 assetCoreId, address treasury, bytes memory params)
    external
    virtual
    pausable
    returns (address);
```

**Parameters**

| Name          | Type      | Description                                                                                   |
| ------------- | --------- | --------------------------------------------------------------------------------------------- |
| `assetCoreId` | `bytes32` | The core ID of the asset to deploy                                                            |
| `treasury`    | `address` | The treasury contract that the asset is associated with. Used during the asset initialization |
| `params`      | `bytes`   | The bespoke abi-encoded parameters used for the asset's initialization                        |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `address` | The address of the deployed asset |

### deployGovernor

Deploys and initializes a governor associated with 'governorCoreId' and returns the deployed contract

*Used by Treasury contracts when changing governors*

```solidity
function deployGovernor(bytes32 governorCoreId, address treasury, bytes memory params)
    external
    virtual
    pausable
    returns (address);
```

**Parameters**

| Name             | Type      | Description                                                           |
| ---------------- | --------- | --------------------------------------------------------------------- |
| `governorCoreId` | `bytes32` | The core ID of the governor to deploy                                 |
| `treasury`       | `address` | The treasury contract that the governor is associated with            |
| `params`         | `bytes`   | Bespoke abi.encoded params for the governor's initialization function |

**Returns**

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `<none>` | `address` | The address of the deployed governor |

### addGuardSelectorDefault

Adds a selector default to the Guard with the given 'coreId'. Only callable by the Mezz Hub Owner

*Will revert if the selector default is already set*

```solidity
function addGuardSelectorDefault(bytes32 guardCoreId, DataTypes.GuardSelector memory guardSelectorToAdd)
    external
    virtual
    onlyHubOwner;
```

**Parameters**

| Name                 | Type                      | Description |
| -------------------- | ------------------------- | ----------- |
| `guardCoreId`        | `bytes32`                 |             |
| `guardSelectorToAdd` | `DataTypes.GuardSelector` |             |

### addGuardContractDefault

Adds a contract default to the Guard with the given 'coreId'. Only callable by the Mezz Hub Owner

```solidity
function addGuardContractDefault(bytes32 guardCoreId, address contractDefaultToAdd) external virtual onlyHubOwner;
```

**Parameters**

| Name                   | Type      | Description        |
| ---------------------- | --------- | ------------------ |
| `guardCoreId`          | `bytes32` |                    |
| `contractDefaultToAdd` | `address` | The default to add |

### removeGuardSelectorDefault

Removes a selector default for the Guard with the given 'coreId'. Only callable by the Mezz Hub Owner

```solidity
function removeGuardSelectorDefault(bytes32 guardCoreId, DataTypes.GuardSelector memory selectorToRemove)
    external
    virtual
    onlyHubOwner;
```

**Parameters**

| Name               | Type                      | Description           |
| ------------------ | ------------------------- | --------------------- |
| `guardCoreId`      | `bytes32`                 |                       |
| `selectorToRemove` | `DataTypes.GuardSelector` | The default to remove |

### removeGuardContractDefault

Removes a contract default for the Guard with the given 'coreId'. Only callable by the Mezz Hub Owner

```solidity
function removeGuardContractDefault(bytes32 guardCoreId, address contractDefaultToRemove) external onlyHubOwner;
```

**Parameters**

| Name                      | Type      | Description           |
| ------------------------- | --------- | --------------------- |
| `guardCoreId`             | `bytes32` |                       |
| `contractDefaultToRemove` | `address` | The default to remove |

### getTreasuryFromSymbol

Returns a company's treasury contract from its symbol. From there, the company's organizations, governor, etc. can be reconstructed on a frontend

```solidity
function getTreasuryFromSymbol(string memory companySymbol) external view returns (address);
```

**Returns**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `<none>` | `address` | The treasury contract address |

### isCompanyNameTaken

Returns true if 'companyName' is taken, false otherwise

```solidity
function isCompanyNameTaken(string memory companyName) external view returns (bool);
```

### isCompanySymbolTaken

Returns true if 'companySymbol' is taken, false otherwise

```solidity
function isCompanySymbolTaken(string memory companySymbol) external view returns (bool);
```

### getGuardSelectorDefaults

Returns the selector defaults for the guard associated with the given 'coreId'

```solidity
function getGuardSelectorDefaults(bytes32 coreId) external view returns (DataTypes.GuardSelector[] memory);
```

**Returns**

| Name     | Type                        | Description                                         |
| -------- | --------------------------- | --------------------------------------------------- |
| `<none>` | `DataTypes.GuardSelector[]` | The defaults as an array of DataTypes.GuardSelector |

### getGuardContractDefaults

Returns the contract defaults for the guard associated with the given 'coreId'

```solidity
function getGuardContractDefaults(bytes32 coreId) external view returns (address[] memory);
```

**Returns**

| Name     | Type        | Description                           |
| -------- | ----------- | ------------------------------------- |
| `<none>` | `address[]` | The defaults as an array of addresses |

### \_validateGuardImplementation

*Validates that 'guardImplementation' supports the IMezzGuard interface*

```solidity
function _validateGuardImplementation(bytes32 guardCoreId, address guardImplementation) internal view virtual;
```

### \_validateGovernorCoreId

*Reverts if 'governorCoreId' does not correspond to an implemented governor implementation*

```solidity
function _validateGovernorCoreId(bytes32 governorCoreId) internal view virtual;
```

### \_validateOwners

*Valdiates that '\_owners' does not contain address(0)*

```solidity
function _validateOwners(address[] memory _owners) internal pure;
```

### \_validateCompanyName

*Validates the company's name's length and that it does not end in a space*

```solidity
function _validateCompanyName(string memory companyName) internal view virtual;
```

### \_setCompanyName

*Validates 'companyName'. Sets state accordingly*

```solidity
function _setCompanyName(string memory companyName) internal virtual;
```

### \_validateCompanySymbol

*Validate that the company's symbol does not contain a banned character This functions runs in O(n), where n is the number of bytes in the company symbol, since the number of bytes in BANNED\_CHARS is constant Using two for-loops is more gas-efficcient than storing banned chars in an enumerable set, since MLOADs are so much cheaper than SLOADs*

```solidity
function _validateCompanySymbol(string memory companySymbol) internal view virtual;
```

### \_setCompanySymbol

*Validates 'companySymbol'. Sets state accordingly*

```solidity
function _setCompanySymbol(string memory companySymbol) internal virtual returns (bytes32);
```

**Returns**

| Name     | Type      | Description     |
| -------- | --------- | --------------- |
| `<none>` | `bytes32` | The symbol hash |

## Structs

### MezzDeployerStorage

```solidity
struct MezzDeployerStorage {
    mapping(bytes32 => bool) _takenNames;
    mapping(bytes32 => bool) _takenSymbols;
    mapping(bytes32 => address) _treasuryByCompanySymbol;
    mapping(bytes32 => EnumerableSet.AddressSet) _guardContractDefaultsByCoreId;
    mapping(bytes32 => DataTypes.GuardSelector[]) _guardSelectorDefaultsByCoreId;
    mapping(address => mapping(bytes4 => uint256)) _indexByDefaultGuardSelector;
}
```
